Files
notifications-admin/Makefile

180 lines
6.1 KiB
Makefile
Raw Normal View History

.DEFAULT_GOAL := help
SHELL := /bin/bash
DATE = $(shell date +%Y-%m-%dT%H:%M:%S)
APP_VERSION_FILE = app/version.py
2016-08-26 16:18:13 +01:00
GIT_BRANCH ?= $(shell git symbolic-ref --short HEAD 2> /dev/null || echo "detached")
2017-02-01 15:44:10 +00:00
GIT_COMMIT ?= $(shell git rev-parse HEAD 2> /dev/null || echo "")
2016-12-08 16:50:37 +00:00
CF_API ?= api.cloud.service.gov.uk
CF_ORG ?= govuk-notify
CF_SPACE ?= ${DEPLOY_ENV}
CF_HOME ?= ${HOME}
CF_APP ?= notify-admin
CF_MANIFEST_PATH ?= /tmp/manifest.yml
$(eval export CF_HOME)
2016-12-08 16:50:37 +00:00
NOTIFY_CREDENTIALS ?= ~/.notify-credentials
VIRTUALENV_ROOT := $(shell [ -z $$VIRTUAL_ENV ] && echo $$(pwd)/venv || echo $$VIRTUAL_ENV)
2020-03-03 12:05:56 +00:00
## DEVELOPMENT
.PHONY: bootstrap
bootstrap: generate-version-file ## Set up everything to run the app
pip3 install -r requirements_for_test.txt
source $(HOME)/.nvm/nvm.sh && nvm install && npm ci --no-audit
2022-06-13 14:26:46 -07:00
source $(HOME)/.nvm/nvm.sh && npm run build
.PHONY: watch-frontend
watch-frontend: ## Build frontend and watch for changes
2022-06-13 14:26:46 -07:00
npm run watch
.PHONY: run-flask
run-flask: ## Run flask
2022-06-13 14:31:51 -07:00
flask run -p 6012 --host=0.0.0.0
.PHONY: npm-audit
npm-audit: ## Check for vulnerabilities in NPM packages
source $(HOME)/.nvm/nvm.sh && npm run audit
.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: virtualenv
virtualenv:
[ -z $$VIRTUAL_ENV ] && [ ! -d venv ] && python3 -m venv venv || true
.PHONY: upgrade-pip
upgrade-pip: virtualenv
${VIRTUALENV_ROOT}/bin/pip install --upgrade pip
.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: ## Run tests
flake8 .
isort --check-only ./app ./tests
source $(HOME)/.nvm/nvm.sh && npm test
py.test -n auto --maxfail=10 tests/
.PHONY: fix-imports
fix-imports: ## Fix imports using isort
isort ./app ./tests
.PHONY: freeze-requirements
freeze-requirements: ## create static requirements.txt
${VIRTUALENV_ROOT}/bin/pip install --upgrade pip-tools
${VIRTUALENV_ROOT}/bin/pip-compile requirements.in
2016-12-08 16:50:37 +00:00
.PHONY: clean
clean:
rm -rf node_modules cache target ${CF_MANIFEST_PATH}
2016-12-08 16:50:37 +00:00
2020-03-03 12:05:56 +00:00
## DEPLOYMENT
.PHONY: check-env-vars
check-env-vars: ## Check mandatory environment variables
$(if ${DEPLOY_ENV},,$(error Must specify DEPLOY_ENV))
$(if ${DNS_NAME},,$(error Must specify DNS_NAME))
.PHONY: preview
preview: ## Set environment to preview
$(eval export DEPLOY_ENV=preview)
$(eval export DNS_NAME="notify.works")
@true
.PHONY: staging
staging: ## Set environment to staging
$(eval export DEPLOY_ENV=staging)
$(eval export DNS_NAME="staging-notify.works")
@true
.PHONY: production
production: ## Set environment to production
$(eval export DEPLOY_ENV=production)
$(eval export DNS_NAME="notifications.service.gov.uk")
@true
2016-12-08 16:50:37 +00:00
.PHONY: cf-login
cf-login: ## Log in to Cloud Foundry
$(if ${CF_USERNAME},,$(error Must specify CF_USERNAME))
$(if ${CF_PASSWORD},,$(error Must specify CF_PASSWORD))
$(if ${CF_SPACE},,$(error Must specify CF_SPACE))
@echo "Logging in to Cloud Foundry on ${CF_API}"
@cf login -a "${CF_API}" -u ${CF_USERNAME} -p "${CF_PASSWORD}" -o "${CF_ORG}" -s "${CF_SPACE}"
.PHONY: generate-manifest
generate-manifest:
$(if ${CF_APP},,$(error Must specify CF_APP))
$(if ${CF_SPACE},,$(error Must specify CF_SPACE))
$(if $(shell which gpg2), $(eval export GPG=gpg2), $(eval export GPG=gpg))
$(if ${GPG_PASSPHRASE_TXT}, $(eval export DECRYPT_CMD=echo -n $$$${GPG_PASSPHRASE_TXT} | ${GPG} --quiet --batch --passphrase-fd 0 --pinentry-mode loopback -d), $(eval export DECRYPT_CMD=${GPG} --quiet --batch -d))
@jinja2 --strict manifest.yml.j2 \
-D environment=${CF_SPACE} \
-D CF_APP=${CF_APP} \
--format=yaml \
<(${DECRYPT_CMD} ${NOTIFY_CREDENTIALS}/credentials/${CF_SPACE}/paas/environment-variables.gpg) 2>&1
.PHONY: upload-static ## Upload the static files to be served from S3
upload-static:
aws s3 cp --region eu-west-1 --recursive --cache-control max-age=315360000,immutable ./app/static s3://${DNS_NAME}-static
2016-12-08 16:50:37 +00:00
.PHONY: cf-deploy
cf-deploy: ## Deploys the app to Cloud Foundry
2017-02-14 16:17:30 +00:00
$(if ${CF_SPACE},,$(error Must specify CF_SPACE))
@cf app --guid notify-admin || exit 1
# cancel any existing deploys to ensure we can apply manifest (if a deploy is in progress you'll see ScaleDisabledDuringDeployment)
cf cancel-deployment ${CF_APP} || true
# generate manifest (including secrets) and write it to CF_MANIFEST_PATH (in /tmp/)
make -s CF_APP=${CF_APP} generate-manifest > ${CF_MANIFEST_PATH}
# reads manifest from CF_MANIFEST_PATH
CF_STARTUP_TIMEOUT=10 cf push ${CF_APP} --strategy=rolling -f ${CF_MANIFEST_PATH}
# delete old manifest file
rm -f ${CF_MANIFEST_PATH}
2017-02-14 16:17:30 +00:00
Add config to deploy a prototype version of admin Sometimes we want to make changes to the admin app for doing user research that we don’t want all users to see (because we’re not sure if they’re the right changes to be making). Previously this meant doing the research using a team member’s computer, with the app running locally. This was bad for three reasons: - requires the time of someone who has the code running locally - requires the participant to use an unfamiliar computer - means the participant doesn’t have access to their own Notify account (or an account that we’ve set up for doing user research with) The dream* would be to have two versions of the frontend app running side by side in production. This commit makes the dream real – the two versions of admin are: - the normal admin app, accessible on `www.notifications.service.gov.uk` - a prototype version meant to be pushed to from a developer’s local machine**, on a `cloudapps.digital` subdomain Both of these apps share the same backing services, eg config, API instance, queues, etc, etc. Which means that the prototype version can be logged into with the same username and password, and the user will see their service and all their templates when they do so. Ideally this wouldn’t mean creating a separate base manifest. However it’s a feature of Cloud Foundry that you can override the application name. Which means a separate base manifest and a bit of duplication. 😞 * actually the real dream would be to have a version of admin deployed for each branch of the admin app, but this might get a bit resource intensive. ** by running `CF_SPACE=preview make preview cf-deploy-prototype`, where `preview` is the name of the space you want to deploy to
2017-05-05 08:41:55 +01:00
.PHONY: cf-deploy-prototype
cf-deploy-prototype: cf-target ## Deploys the first prototype to Cloud Foundry
make -s CF_APP=notify-admin-prototype generate-manifest > ${CF_MANIFEST_PATH}
cf push notify-admin-prototype --strategy=rolling -f ${CF_MANIFEST_PATH}
rm -f ${CF_MANIFEST_PATH}
Add config to deploy a prototype version of admin Sometimes we want to make changes to the admin app for doing user research that we don’t want all users to see (because we’re not sure if they’re the right changes to be making). Previously this meant doing the research using a team member’s computer, with the app running locally. This was bad for three reasons: - requires the time of someone who has the code running locally - requires the participant to use an unfamiliar computer - means the participant doesn’t have access to their own Notify account (or an account that we’ve set up for doing user research with) The dream* would be to have two versions of the frontend app running side by side in production. This commit makes the dream real – the two versions of admin are: - the normal admin app, accessible on `www.notifications.service.gov.uk` - a prototype version meant to be pushed to from a developer’s local machine**, on a `cloudapps.digital` subdomain Both of these apps share the same backing services, eg config, API instance, queues, etc, etc. Which means that the prototype version can be logged into with the same username and password, and the user will see their service and all their templates when they do so. Ideally this wouldn’t mean creating a separate base manifest. However it’s a feature of Cloud Foundry that you can override the application name. Which means a separate base manifest and a bit of duplication. 😞 * actually the real dream would be to have a version of admin deployed for each branch of the admin app, but this might get a bit resource intensive. ** by running `CF_SPACE=preview make preview cf-deploy-prototype`, where `preview` is the name of the space you want to deploy to
2017-05-05 08:41:55 +01:00
2018-02-07 17:28:04 +00:00
.PHONY: cf-deploy-prototype-2
cf-deploy-prototype-2: cf-target ## Deploys the second prototype to Cloud Foundry
make -s CF_APP=notify-admin-prototype-2 generate-manifest > ${CF_MANIFEST_PATH}
cf push notify-admin-prototype-2 --strategy=rolling -f ${CF_MANIFEST_PATH}
rm -f ${CF_MANIFEST_PATH}
2018-02-07 17:28:04 +00:00
2017-02-14 16:17:30 +00:00
.PHONY: cf-rollback
cf-rollback: cf-target ## Rollbacks the app to the previous release
cf cancel-deployment ${CF_APP}
rm -f ${CF_MANIFEST_PATH}
2016-12-08 16:50:37 +00:00
.PHONY: cf-target
cf-target: check-env-vars
@cf target -o ${CF_ORG} -s ${CF_SPACE}
.PHONY: cf-failwhale-deployed
cf-failwhale-deployed:
@cf app notify-admin-failwhale --guid || (echo "notify-admin-failwhale is not deployed on ${CF_SPACE}" && exit 1)
.PHONY: enable-failwhale
enable-failwhale: cf-target cf-failwhale-deployed ## Enable the failwhale app and disable admin
@cf map-route notify-admin-failwhale ${DNS_NAME} --hostname www
@cf unmap-route notify-admin ${DNS_NAME} --hostname www
@echo "Failwhale is enabled"
.PHONY: disable-failwhale
disable-failwhale: cf-target cf-failwhale-deployed ## Disable the failwhale app and enable admin
@cf map-route notify-admin ${DNS_NAME} --hostname www
@cf unmap-route notify-admin-failwhale ${DNS_NAME} --hostname www
@echo "Failwhale is disabled"