Skip to content

Commit

Permalink
Merge pull request #69 from fecgov/release/sprint-4
Browse files Browse the repository at this point in the history
Release/sprint 4
  • Loading branch information
toddlees authored Mar 4, 2022
2 parents ab46a1b + b13f50c commit 2ee4831
Show file tree
Hide file tree
Showing 144 changed files with 15,279 additions and 13,925 deletions.
2 changes: 1 addition & 1 deletion .circleci/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ To run in the local CircleCI for the django unit tests (for example), use the fo
circleci local execute -e DATABASE_URL=${DATABASE_URL} \
-e FECFILE_FEC_WEBSITE_API_KEY=${FECFILE_FEC_WEBSITE_API_KEY} \
-e FECFILE_TEST_DB_NAME=${FECFILE_TEST_DB_NAME} \
--job unit-test
--job test
```

## CircleCI configuration
Expand Down
19 changes: 9 additions & 10 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:

dependency-check:
docker:
- image: cimg/python:3.7
- image: cimg/python:3.8

steps:
- checkout
Expand Down Expand Up @@ -50,7 +50,7 @@ jobs:
# These next lines defines a Docker executors: https://circleci.com/docs/2.0/executor-types/
# A list of available CircleCI Docker convenience images are available here: https://circleci.com/developer/images/image/cimg/python
docker:
- image: cimg/python:3.7-node
- image: cimg/python:3.8-node
- image: cimg/postgres:12.8

steps:
Expand Down Expand Up @@ -100,13 +100,7 @@ jobs:
python manage.py migrate
working_directory: ~/project/django-backend/

# Only use SonarCloud linting or security checking for now.
# Leaving this as a comment in case SonarCloud isn't good enough and we need to re-enable
# - run:
# name: Run lint
# command: |
# flake8 --config django-backend/.flake8 --output-file flake8.out . || echo "Found lint errors: " && cat flake8.out
#
# Only use SonarCloud security checking for now.
# - run:
# name: Bandit security checks
# command: |
Expand Down Expand Up @@ -161,10 +155,15 @@ jobs:
key: v1-sonarcloud-scanner-4.6.2.2472
paths: /tmp/cache/scanner

- run:
name: Run lint
command: |
flake8 --config django-backend/.flake8
deploy:

docker:
- image: cimg/python:3.7
- image: cimg/python:3.8

steps:
- checkout
Expand Down
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.7
FROM python:3.8
ENV PYTHONUNBUFFERED=1

RUN mkdir /opt/nxg_fec
Expand All @@ -9,7 +9,7 @@ RUN pip3 install -r /opt/requirements.txt
RUN mv /etc/localtime /etc/localtime.backup && ln -s /usr/share/zoneinfo/EST5EDT /etc/localtime

RUN useradd nxgu --no-create-home --home /opt/nxg_fec && chown -R nxgu:nxgu /opt/nxg_fec
user nxgu
USER nxgu

EXPOSE 8080
ENTRYPOINT ["sh", "-c", "cp /opt/requirements.txt . && pip3 install -r requirements.txt && python wait_for_db.py && gunicorn --bind 0.0.0.0:8080 fecfiler.wsgi -w 10 -t 200 --reload"]
ENTRYPOINT ["/bin/sh", "-c", "python wait_for_db.py && gunicorn --bind 0.0.0.0:8080 fecfiler.wsgi -w 10 -t 200 --reload"]
64 changes: 36 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ When running docker-compose you will need to be in the root directory of the pro
You should set the following environment variables in the shell where you are running 'docker-compose up -d'.
Proper values for the development variables are shown here as an example
```
export DATABASE_URL = "postgres://postgres:postgres@0.0.0.0/postgres"
export DATABASE_URL = "postgres://postgres:postgres@db/postgres"
export FECFILE_TEST_DB_NAME = "postgres"
export DJANGO_SECRET_KEY = "If_using_test_db_use_secret_key_in_cloud.gov"
```
Expand All @@ -45,61 +45,69 @@ export DJANGO_SECRET_KEY = "If_using_test_db_use_secret_key_in_cloud.gov"
# Deployment (FEC team only)

### Create a feature branch
* Developer creates a feature branch and pushes to `origin`:

Using git-flow extensions:
```
git flow feature start feature_branch
```

Without the git-flow extensions:
```
git checkout develop
git pull
git checkout -b feature/my-feature develop
# Work happens here
git push --set-upstream origin feature/my-feature
git checkout -b feature/feature_branch develop
```

* Developer creates a GitHub PR when ready to merge to `develop` branch
* Reviewer reviews and merges feature branch into `develop` via GitHub
* [auto] `develop` is deployed to `dev`

### Create a release branch
* Developer creates a release branch and pushes to `origin`:

```
git checkout develop
git pull
git checkout -b release/sprint-# develop
git push --set-upstream origin release/sprint-#
```
Using git-flow extensions:
```
git flow release start sprint-#
```

### Create and deploy a hotfix
* Developer makes sure their local main and develop branches are up to date:
Without the git-flow extensions:
```
git checkout develop
git pull
git checkout -b release/sprint-# develop
git push --set-upstream origin release/sprint-#
```

```
git checkout develop
git pull
git checkout main
git pull
```
### Create and deploy a hotfix

* Developer creates a hotfix branch, commits changes, and **makes a PR to the `main` and `develop` branches**:
Using git-flow extensions:
```
git flow hotfix start my-fix
# Work happens here
git flow hotfix finish my-fix
```

```
git checkout -b hotfix/my-fix main
# Work happens here
git push --set-upstream origin hotfix/my-fix
```
Without the git-flow extensions:
```
git checkout -b hotfix/my-fix main
# Work happens here
git push --set-upstream origin hotfix/my-fix
```

* Developer creates a hotfix branch, commits changes, and **makes a PR to the `main` and `develop` branches**:
* Reviewer merges hotfix/my-fix branch into `develop` and `main`
* [auto] `develop` is deployed to `dev`. Make sure the build passes before deploying to `main`.
* Developer deploys hotfix/my-fix branch to main using **Deploying a release to production** instructions below

### Deploying a release to production
* Developer creates a PR in GitHub to merge release/sprint-# branch into the `main` branch
* Reviewer approves PR and merges into `main`
* Reviewer approves PR and merges into `main` (At this point the code is automatically deployed)
* Check CircleCI for passing pipeline tests
* If tests pass, continue
* (If commits were made to release/sprint-#) Developer creates a PR in GitHub to merge release/sprint-# branch into the `develop` branch
* Reviewer approves PR and merges into `develop`
* Delete release/sprint-# branch
* In GitHub, go to `Code -> tags -> releases -> Draft a new release`
* Publish a new release using tag sprint-#, be sure to Auto-generate release notes
* Deploy `sprint-#` tag to production


## Additional developer notes
Expand Down
2 changes: 1 addition & 1 deletion bin/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ cd django-backend
./manage.py migrate --noinput

# Run application
python wait_for_db.py && gunicorn --bind 0.0.0.0:8080 fecfiler.wsgi -w 9 -t 200 --reload
python wait_for_db.py && gunicorn --bind 0.0.0.0:8080 fecfiler.wsgi -w 9 -t 200
39 changes: 39 additions & 0 deletions bin/update-licence-report.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash

CURRENT_DIR=${PWD##*/}
OUTFILE="./docs/license_report.md"

echo "Saving report as a markdown formatted file in ${OUTFILE}"

if [ "$CURRENT_DIR" != "fecfile-web-api" ]; then
echo "Run this script from the root directory of the fecfile-web-api repository:"
fi;

mkdir -p docs

echo "The following dependencies are used by this application:" > "$OUTFILE"
echo "" >> "$OUTFILE"
echo "" >> "$OUTFILE"
echo "| Package | Version | License |" >> "$OUTFILE"
echo "| --- | --- | --- |" >> "$OUTFILE"

liccheck |
grep ": " |
sed "s/://" |
sed "s/\[//" |
sed "s/\]//" |
sed "s/'//g" |
awk '{
gsub(/\(/, "", $2)
gsub(/\)/, "", $2)
printf "| %s | %s | ", $1, $2
for (i=3; i <= NF; i++) printf "%s ", $i
printf "|\n"
}' >> "$OUTFILE"

echo "" >> "$OUTFILE"





24 changes: 3 additions & 21 deletions django-backend/.flake8
Original file line number Diff line number Diff line change
@@ -1,24 +1,6 @@
[flake8]
max-line-length = 160
ignore =
E501 # line length,
W291 # trailing whitespace
W503 # line break before binary operator
E711 # comparison to None should be 'if cond is None:'
E712 # comparison to False should be 'if cond is False:' or 'if not cond:'
E713 # test for membership should be 'not in'
E722 # do not use bare 'except'
F401 # 'django.contrib.admin' imported but unused
F403 # 'from .views import *' used; unable to detect undefined names
F523 # '...'.format(...) has unused arguments at position(s): 0
F524 # '...'.format(...) is missing argument(s) for placeholder(s): 1
F632 # use ==/!= to compare constant literals (str, bytes, int, float, tuple)
F811 # redefinition of unused 'datetime' from line 11
F821 # undefined name 'get_entities'
F841 # local variable 'e' is assigned to but never used
N802 # function names should be lowercase
N802 # function name should be lowercase
N806 # variable in function should be lowercase
N803 # argument name should be lowercase
N801 # class name should use CapWords convention
N816 # variable in global scope should not be mixedCase
exclude:
fecfiler/core/jsonsqlgenerate.py # this file needs significant work
W503 # line break before binary operator
5 changes: 2 additions & 3 deletions django-backend/fecfiler/authentication/admin.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
from django.contrib import admin
from .models import Account
from .forms import AccountCreationForm
from django.contrib.auth.admin import UserAdmin


class AccountAdmin(UserAdmin):
add_form_template = 'admin/authentication/account/add_form.html'
add_form_template = "admin/authentication/account/add_form.html"
add_form = AccountCreationForm


# admin.site.register(Account, AccountAdmin)
10 changes: 5 additions & 5 deletions django-backend/fecfiler/authentication/auth_enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@


class Roles(Enum):
C_ADMIN = 'C_ADMIN'
BC_ADMIN = 'BC_ADMIN'
ADMIN = 'ADMIN'
REVIEWER = 'REVIEWER'
EDITOR = 'EDITOR'
C_ADMIN = "C_ADMIN"
BC_ADMIN = "BC_ADMIN"
ADMIN = "ADMIN"
REVIEWER = "REVIEWER"
EDITOR = "EDITOR"
14 changes: 10 additions & 4 deletions django-backend/fecfiler/authentication/authorization.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@

def is_not_treasurer(request):
is_allowed = False
if request.method == 'GET':
if request.method == "GET":
is_allowed = True
elif request.user.role == Roles.C_ADMIN.value or request.user.role == Roles.BC_ADMIN.value:
elif (
request.user.role == Roles.C_ADMIN.value
or request.user.role == Roles.BC_ADMIN.value
):
is_allowed = True
if not is_allowed:
raise Exception("User is not allowed to access this API ")
Expand All @@ -14,7 +17,7 @@ def is_not_treasurer(request):
def is_read_only_or_filer_reports(request):
is_allowed = False
if request.user.role == Roles.REVIEWER.value:
if request.method == 'GET':
if request.method == "GET":
is_allowed = True
elif request.user.role != Roles.REVIEWER.value:
is_allowed = True
Expand All @@ -24,7 +27,10 @@ def is_read_only_or_filer_reports(request):

def is_read_only_or_filer_submit(request):
is_allowed = False
if request.user.role != Roles.REVIEWER.value or request.user.role != Roles.EDITOR.value:
if (
request.user.role != Roles.REVIEWER.value
or request.user.role != Roles.EDITOR.value
):
is_allowed = True
if not is_allowed:
raise Exception("User is not allowed to access this API ")
Expand Down
6 changes: 2 additions & 4 deletions django-backend/fecfiler/authentication/forms.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
from django import forms
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.forms import UserCreationForm
from .models import Account


class AccountCreationForm(UserCreationForm):

class Meta:
model = Account
fields = ("username",)
Expand All @@ -15,6 +13,6 @@ def clean_username(self):
if Account.objects.filter(username=username).count() == 0:
return username
raise forms.ValidationError(
self.error_messages['duplicate_username'],
code='duplicate_username',
self.error_messages["duplicate_username"],
code="duplicate_username",
)
Loading

0 comments on commit 2ee4831

Please sign in to comment.