Files

170 lines
5.0 KiB
Makefile
Raw Permalink Normal View History

.DEFAULT_GOAL := help
SHELL := /bin/bash
DATE = $(shell date +%Y-%m-%d:%H:%M:%S)
APP_VERSION_FILE = app/version.py
2016-08-26 16:18:04 +01:00
GIT_BRANCH ?= $(shell git symbolic-ref --short HEAD 2> /dev/null || echo "detached")
GIT_COMMIT ?= $(shell git rev-parse HEAD 2> /dev/null || echo "")
GIT_HOOKS_PATH ?= $(shell git config --global core.hooksPath || echo "")
## DEVELOPMENT
2025-01-06 07:37:21 -08:00
## TODO this line should go under `make generate-version-file`
## poetry self update
.PHONY: bootstrap
2022-10-26 14:05:37 +00:00
bootstrap: ## Set up everything to run the app
2022-10-26 15:26:53 -04:00
make generate-version-file
poetry sync --no-root
2023-11-17 09:14:12 -05:00
poetry run pre-commit install
createdb notification_api || true
createdb test_notification_api || true
2023-08-31 11:00:55 -07:00
(poetry run flask db upgrade) || true
.PHONY: bootstrap-with-git-hooks
bootstrap-with-git-hooks: ## Sets everything up and accounts for pre-existing git hooks
2022-10-26 15:26:53 -04:00
make generate-version-file
poetry sync --no-root
git config --global --unset-all core.hooksPath
2023-11-17 09:14:12 -05:00
poetry run pre-commit install
git config --global core.hookspath "${GIT_HOOKS_PATH}"
createdb notification_api || true
createdb test_notification_api || true
2023-08-31 11:00:55 -07:00
(poetry run flask db upgrade) || true
.PHONY: bootstrap-with-docker
bootstrap-with-docker: ## Build the image to run the app in Docker
docker build -f docker/Dockerfile -t notifications-api .
2022-11-01 09:54:31 -04:00
.PHONY: run-procfile
run-procfile:
2023-08-31 11:00:55 -07:00
poetry run honcho start -f Procfile.dev
2022-11-01 09:54:31 -04:00
2025-01-23 13:41:13 -08:00
.PHONY: tada
tada:
poetry run isort .
poetry run black .
poetry run flake8 .
.PHONY: avg-complexity
avg-complexity:
echo "*** Shows average complexity in radon of all code ***"
2023-08-31 11:00:55 -07:00
poetry run radon cc ./app -a -na
.PHONY: too-complex
too-complex:
2023-08-07 10:59:51 -07:00
echo "*** Shows code that got a rating of C, D or F in radon ***"
2023-08-31 11:00:55 -07:00
poetry run radon cc ./app -a -nc
.PHONY: run-flask
2025-04-09 16:56:42 -07:00
run-flask:
poetry run newrelic-admin run-program flask run -p 6011 --host=0.0.0.0
.PHONY: run-celery
2022-06-13 13:45:07 -07:00
run-celery: ## Run celery, TODO remove purge for staging/prod
2023-08-31 11:00:55 -07:00
poetry run celery -A run_celery.notify_celery purge -f
poetry run newrelic-admin run-program celery \
-A run_celery.notify_celery worker \
--pidfile="/tmp/celery.pid" \
--loglevel=INFO \
--pool=gevent
--concurrency=20
.PHONY: dead-code
2024-06-19 13:00:54 -07:00
dead-code: ## Use 60 to look for suspected dead code
2023-08-31 11:00:55 -07:00
poetry run vulture ./app --min-confidence=100
.PHONY: run-celery-beat
run-celery-beat: ## Run celery beat
2023-08-31 11:00:55 -07:00
poetry run celery \
2022-06-13 13:45:07 -07:00
-A run_celery.notify_celery beat \
--loglevel=INFO
2023-05-09 21:54:22 -04:00
.PHONY: cloudgov-user-report
2023-05-09 21:44:15 -04:00
cloudgov-user-report:
2023-08-31 11:00:55 -07:00
@poetry run python -m terraform.ops.cloudgov_user_report
2023-05-09 21:44:15 -04:00
.PHONY: help
help:
@cat $(MAKEFILE_LIST) | grep -E '^[a-zA-Z_-]+:.*?## .*$$' | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
.PHONY: generate-version-file
generate-version-file: ## Generates the app version file
@echo -e "__git_commit__ = \"${GIT_COMMIT}\"\n__time__ = \"${DATE}\"" > ${APP_VERSION_FILE}
.PHONY: test
test: export NEW_RELIC_ENVIRONMENT=test
test: ## Run tests and create coverage report
2023-08-31 11:00:55 -07:00
poetry run black .
poetry run flake8 .
2025-01-07 07:13:32 -08:00
poetry run isort ./app ./tests
2024-10-01 13:21:05 -07:00
poetry run coverage run --omit=*/migrations/*,*/tests/* -m pytest --maxfail=10
2024-05-31 07:38:27 -07:00
2025-07-08 10:44:02 -07:00
poetry run coverage report -m --fail-under=95
2023-08-31 11:00:55 -07:00
poetry run coverage html -d .coverage_cache
.PHONY: test-debug
test-debug:
poetry run pytest --pdb -x
.PHONY: py-lock
py-lock: ## Syncs dependencies and updates lock file without performing recursive internal updates
poetry sync --no-root
2025-05-27 14:14:44 -07:00
poetry lock
Pin all application requirements in requirements.txt The list of top-level dependencies is moved to requirements-app.txt, which is used by `make freeze-requirements` to generate the full list of requirements in requirements.txt. This is based on alphagov/digitalmarketplace-api#615, so rationale from that PR applies here. We had a problem with unpinned packages on new deployments leading to failed tests (e.g. alphagov/notifications-admin#2144) which is why we're implementing this now. After re-evaluating pipenv again, this still seems like the least disruptive approach: * pyup.io has experimental support for Pipfile, but doesn't respect version ranges or updating hashes in the lock file * CloudFoundry buildpack recognizes and supports Pipfiles out of the box, but the support is relatively new. For example until recently CF would install dev packages during deployment. It's also based on generating a requirements file from the Pipfile, which doesn't properly support pinning VCS dependencies (eg it doesn't set the #egg= version, meaning pip will not upgrade the package if it's already installed). * pipenv has a strict dependency resolution algorithm, which doesn't appear to be well documented and can cause some unexpected failures. For example, pipenv doesn't seem to be able to install `awscli-cwlogs` package at all, believing it to have a version conflict for `botocore` (which it doesn't list as a direct dependency) while neither `pip` nor `pip-tools` highlight any issues with it. * While trying out `pipenv install` on our list of dependencies it would regularly fail to install utils with a "Will try again." message. While the installation succeeds after a retry, this doesn't inspire confidence. * The switch to Pipfile and pipenv-managed virtualenvs requires a series of changes to `make` targets and scripts - replacing `pip install` with `pipenv`, removing references to requirements files and prefixing commands with `pipenv run`. While it's likely to simplify the overall process of managing dependencies, it would require time to properly implement across our applications and environments (Jenkins, PaaS, docker containers, and dev machines).
2018-07-10 14:50:30 +01:00
.PHONY: freeze-requirements
freeze-requirements: ## Pin all requirements including sub dependencies into requirements.txt
2025-05-28 08:10:28 -07:00
poetry export --output > requirements.txt
Pin all application requirements in requirements.txt The list of top-level dependencies is moved to requirements-app.txt, which is used by `make freeze-requirements` to generate the full list of requirements in requirements.txt. This is based on alphagov/digitalmarketplace-api#615, so rationale from that PR applies here. We had a problem with unpinned packages on new deployments leading to failed tests (e.g. alphagov/notifications-admin#2144) which is why we're implementing this now. After re-evaluating pipenv again, this still seems like the least disruptive approach: * pyup.io has experimental support for Pipfile, but doesn't respect version ranges or updating hashes in the lock file * CloudFoundry buildpack recognizes and supports Pipfiles out of the box, but the support is relatively new. For example until recently CF would install dev packages during deployment. It's also based on generating a requirements file from the Pipfile, which doesn't properly support pinning VCS dependencies (eg it doesn't set the #egg= version, meaning pip will not upgrade the package if it's already installed). * pipenv has a strict dependency resolution algorithm, which doesn't appear to be well documented and can cause some unexpected failures. For example, pipenv doesn't seem to be able to install `awscli-cwlogs` package at all, believing it to have a version conflict for `botocore` (which it doesn't list as a direct dependency) while neither `pip` nor `pip-tools` highlight any issues with it. * While trying out `pipenv install` on our list of dependencies it would regularly fail to install utils with a "Will try again." message. While the installation succeeds after a retry, this doesn't inspire confidence. * The switch to Pipfile and pipenv-managed virtualenvs requires a series of changes to `make` targets and scripts - replacing `pip install` with `pipenv`, removing references to requirements files and prefixing commands with `pipenv run`. While it's likely to simplify the overall process of managing dependencies, it would require time to properly implement across our applications and environments (Jenkins, PaaS, docker containers, and dev machines).
2018-07-10 14:50:30 +01:00
.PHONY: audit
audit:
2023-08-31 11:00:55 -07:00
poetry requirements > requirements.txt
poetry requirements --dev > requirements_for_test.txt
poetry run pip-audit -r requirements.txt --skip-editable
poetry run pip-audit -r requirements_for_test.txt --skip-editable
2022-08-12 17:19:28 -04:00
.PHONY: static-scan
static-scan:
2023-08-31 11:00:55 -07:00
poetry run bandit -r app/
2022-08-12 17:19:28 -04:00
2016-12-08 12:12:45 +00:00
.PHONY: clean
clean:
rm -rf node_modules cache target venv .coverage build tests/.cache ${CF_MANIFEST_PATH}
2016-12-08 12:12:45 +00:00
## DEPLOYMENT
2022-10-20 14:04:10 -04:00
# .PHONY: cf-deploy-failwhale
# cf-deploy-failwhale:
# $(if ${CF_SPACE},,$(error Must target space, eg `make preview cf-deploy-failwhale`))
# cd ./paas-failwhale; cf push notify-api-failwhale -f manifest.yml
# .PHONY: enable-failwhale
# enable-failwhale: ## Enable the failwhale app and disable api
# $(if ${DNS_NAME},,$(error Must target space, eg `make preview enable-failwhale`))
# # make sure failwhale is running first
# cf start notify-api-failwhale
# cf map-route notify-api-failwhale ${DNS_NAME} --hostname api
# cf unmap-route notify-api ${DNS_NAME} --hostname api
# @echo "Failwhale is enabled"
# .PHONY: disable-failwhale
# disable-failwhale: ## Disable the failwhale app and enable api
# $(if ${DNS_NAME},,$(error Must target space, eg `make preview disable-failwhale`))
# cf map-route notify-api ${DNS_NAME} --hostname api
# cf unmap-route notify-api-failwhale ${DNS_NAME} --hostname api
# cf stop notify-api-failwhale
# @echo "Failwhale is disabled"
.PHONY: test-single
test-single: export NEW_RELIC_ENVIRONMENT=test
test-single: ## Run a single test file
2025-02-27 16:09:49 -05:00
poetry run pytest -s $(TEST_FILE)