Skip to content

Commit 62ab4ee

Browse files
authored
Merge pull request #1805 from GSA/main
Production Deploy 06/30/2025
2 parents c3ac021 + 0b5efda commit 62ab4ee

File tree

39 files changed

+1856
-1083
lines changed

39 files changed

+1856
-1083
lines changed

.github/actions/setup-project/action.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ runs:
99
sudo apt-get update \
1010
&& sudo apt-get install -y --no-install-recommends \
1111
libcurl4-openssl-dev
12-
- name: Set up Python 3.12.2
12+
- name: Set up Python 3.12.9
1313
uses: actions/setup-python@v4
1414
with:
15-
python-version: "3.12.2"
15+
python-version: "3.12.9"
1616
- name: Install poetry
1717
shell: bash
1818
run: pip install poetry==2.1.3

.github/workflows/checks.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ jobs:
6464
NOTIFY_E2E_TEST_PASSWORD: ${{ secrets.NOTIFY_E2E_TEST_PASSWORD }}
6565
- name: Check coverage threshold
6666
# TODO get this back up to 95
67-
run: poetry run coverage report -m --fail-under=93
67+
run: poetry run coverage report -m --fail-under=92
6868

6969
validate-new-relic-config:
7070
runs-on: ubuntu-latest

.github/workflows/drift.yml

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,25 @@ jobs:
2424
terraform_wrapper: false
2525

2626
- name: Check for drift
27-
uses: dflook/terraform-check@v1
2827
env:
2928
AWS_ACCESS_KEY_ID: ${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
3029
AWS_SECRET_ACCESS_KEY: ${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
3130
TF_VAR_cf_user: ${{ secrets.CLOUDGOV_USERNAME }}
3231
TF_VAR_cf_password: ${{ secrets.CLOUDGOV_PASSWORD }}
33-
with:
34-
path: terraform/staging
32+
run: |
33+
cd terraform/staging
34+
terraform init
35+
terraform plan -detailed-exitcode
36+
exit_code=$?
37+
if [ $exit_code -eq 0 ]; then
38+
echo "No changes detected. Intrastructure is up-to-date."
39+
elif [ $exit_code -eq 2 ]; then
40+
echo "Changes detected. Infrastructure drift found."
41+
exit 1
42+
else
43+
echo "Error running terraform plan."
44+
exit $exit_code
45+
fi
3546
3647
check_demo_drift:
3748
runs-on: ubuntu-latest
@@ -52,14 +63,25 @@ jobs:
5263
terraform_wrapper: false
5364

5465
- name: Check for drift
55-
uses: dflook/terraform-check@v1
5666
env:
5767
AWS_ACCESS_KEY_ID: ${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
5868
AWS_SECRET_ACCESS_KEY: ${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
5969
TF_VAR_cf_user: ${{ secrets.CLOUDGOV_USERNAME }}
6070
TF_VAR_cf_password: ${{ secrets.CLOUDGOV_PASSWORD }}
61-
with:
62-
path: terraform/demo
71+
run: |
72+
cd terraform/demo
73+
terraform init
74+
terraform plan -detailed-exitcode
75+
exit_code=$?
76+
if [ $exit_code -eq 0 ]; then
77+
echo "No changes detected. Intrastructure is up-to-date."
78+
elif [ $exit_code -eq 2 ]; then
79+
echo "Changes detected. Infrastructure drift found."
80+
exit 1
81+
else
82+
echo "Error running terraform plan."
83+
exit $exit_code
84+
fi
6385
6486
check_prod_drift:
6587
runs-on: ubuntu-latest
@@ -80,11 +102,22 @@ jobs:
80102
terraform_wrapper: false
81103

82104
- name: Check for drift
83-
uses: dflook/terraform-check@v1
84105
env:
85106
AWS_ACCESS_KEY_ID: ${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
86107
AWS_SECRET_ACCESS_KEY: ${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
87108
TF_VAR_cf_user: ${{ secrets.CLOUDGOV_USERNAME }}
88109
TF_VAR_cf_password: ${{ secrets.CLOUDGOV_PASSWORD }}
89-
with:
90-
path: terraform/production
110+
run: |
111+
cd terraform/production
112+
terraform init
113+
terraform plan -detailed-exitcode
114+
exit_code=$?
115+
if [ $exit_code -eq 0 ]; then
116+
echo "No changes detected. Intrastructure is up-to-date."
117+
elif [ $exit_code -eq 2 ]; then
118+
echo "Changes detected. Infrastructure drift found."
119+
exit 1
120+
else
121+
echo "Error running terraform plan."
122+
exit $exit_code
123+
fi

README.md

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ It's cloned from the brilliant work of the team at
99
This repo contains:
1010

1111
- A public-facing REST API for Notify.gov, which teams can integrate with using
12-
[API clients built by UK](https://www.notifications.service.gov.uk/documentation).
12+
[API clients built by UK](https://www.notifications.service.gov.uk/documentation).
1313
- An internal-only REST API built using Flask to manage services, users,
1414
templates, etc., which the
1515
[Notify.gov Admin UI](http://github.com/18F/notifications-admin) talks to.
@@ -18,7 +18,6 @@ This repo contains:
1818

1919
Our other repositories are:
2020

21-
- [notifications-admin](https://github.com/GSA/notifications-admin)
2221
- [us-notify-compliance](https://github.com/GSA/us-notify-compliance/)
2322
- [notify-python-demo](https://github.com/GSA/notify-python-demo)
2423

@@ -53,7 +52,7 @@ recommended. This helps avoid some known installation issues. Start by following
5352
the installation instructions on the Homebrew homepage.
5453

5554
**Note:** You will also need Xcode or the Xcode Command Line Tools installed. The
56-
quickest way to do this is is by installing the command line tools in the shell:
55+
quickest way to do this is by installing the command line tools in the shell:
5756

5857
```sh
5958
xcode-select –-install
@@ -71,11 +70,13 @@ Your system `$PATH` environment variable is likely set in one of these
7170
locations:
7271

7372
For BASH shells:
73+
7474
- `~/.bashrc`
7575
- `~/.bash_profile`
7676
- `~/.profile`
7777

7878
For ZSH shells:
79+
7980
- `~/.zshrc`
8081
- `~/.zprofile`
8182

@@ -85,7 +86,7 @@ environments.
8586
Which file you need to modify depends on whether or not you are running an
8687
interactive shell or a login shell
8788
(see [this Stack Overflow post](https://stackoverflow.com/questions/18186929/what-are-the-differences-between-a-login-shell-and-interactive-shell)
88-
for an explanation of the differences). If you're still not sure, please ask
89+
for an explanation of the differences). If you're still not sure, please ask
8990
the team for help!
9091

9192
Once you determine which file you'll need to modify, add these lines before any
@@ -147,7 +148,7 @@ tfenv use 1.7.x # x = the patch version installed
147148
#### Python Installation
148149

149150
Now we're going to install a tool to help us manage Python versions and
150-
virtual environments on our system. First, we'll install
151+
virtual environments on our system. First, we'll install
151152
[pyenv](https://github.com/pyenv/pyenv) and one of its plugins,
152153
[pyenv-virtualenv](https://github.com/pyenv/pyenv-virtualenv), with Homebrew:
153154

@@ -201,10 +202,6 @@ requires a version number to be included with it when installing it:
201202
brew install postgresql@15
202203
```
203204

204-
_NOTE: This project currently works with PostgreSQL version 15.x; version 12.x is currently used in our hosted environments._
205-
206-
_NOTE: If you have a pre-existing instance of PSQL installed because of another product like PGAdmin, your database configuration may differ from the instructions above, which uses Homebrew to install and configure PostgreSQL. If this is the case for you, you may have to either account for slightly different user permissions with the database, or uninstall PGAdmin and/or PostgreSQL itself, and reinstall it with Homebrew to follow the steps above._
207-
208205
You'll now need to modify (or create, if it doesn't already exist) the `$PATH`
209206
environment variable to include the PostgreSQL binaries. Open the file you have
210207
worked with before to adjust your shell environment with the previous steps and
@@ -224,6 +221,10 @@ this, which will include the PostgreSQL binaries:
224221
export PATH="/opt/homebrew/opt/postgresql@15/bin:$PATH"
225222
```
226223

224+
_NOTE: This project currently works with PostgreSQL version 15.x; version 12.x is currently used in our hosted environments._
225+
226+
_NOTE: If you have a pre-existing instance of PSQL installed because of another product like PGAdmin, your database configuration may differ from the instructions above, which uses Homebrew to install and configure PostgreSQL. If this is the case for you, you may have to either account for slightly different user permissions with the database, or uninstall PGAdmin and/or PostgreSQL itself, and reinstall it with Homebrew to follow the steps above._
227+
227228
_NOTE: You don't want to overwrite your existing `$PATH` environment variable! Hence the reason why it is included on the end like this; paths are separated by a colon._
228229

229230
#### Starting PostgreSQL and Redis
@@ -259,23 +260,24 @@ git clone git@github.com:GSA/notifications-api.git
259260

260261
Now go into the project directory (`notifications-api` by default), create a
261262
virtual environment, and set the local Python version to point to the virtual
262-
environment (assumes version Python `3.12.2` is what is installed on your
263+
environment (assumes version Python `3.12.9` is what is installed on your
263264
machine):
264265

265266
```sh
266267
cd notifications-api
267-
pyenv virtualenv 3.12.2 notify-api
268+
pyenv virtualenv 3.12.9 notify-api
268269
pyenv local notify-api
269270
```
270271

271-
_If you're not sure which version of Python was installed with `pyenv`, you can check by running `pyenv versions` and it'll list everything available currently._
272+
_NOTE: If you're not sure which version of Python was installed with `pyenv`, you can check by running `pyenv versions` and it'll list everything available currently._
272273

273274
Now [log into cloud.gov](https://cloud.gov/docs/getting-started/setup/#set-up-the-command-line)
274275
in the command line by using this command:
275276

276277
```sh
277278
cf login -a api.fr.cloud.gov --sso
278279
```
280+
279281
If you are offered a choice of orgs, select `gsa-tts-benefits-studio`.
280282
For the space, choose `notify-local-dev` to start with (assuming you are
281283
setting up local development).
@@ -317,7 +319,7 @@ we'll use `3.13` in our example here since we recently upgraded to this version:
317319
pyenv install 3.13
318320
```
319321

320-
Next, delete the virtual environment you previously had set up. If you followed
322+
Next, delete the virtual environment you previously had set up. If you followed
321323
the instructions above with the first-time set up, you can do this with `pyenv`:
322324

323325
```sh
@@ -329,17 +331,16 @@ environment with the newer version of Python you just installed:
329331

330332
```sh
331333
cd notifications-api
332-
pyenv virtualenv 3.12.2 notify-api
334+
pyenv virtualenv 3.12.9 notify-api
333335
pyenv local notify-api
334336
```
335337

336338
At this point, proceed with the rest of the instructions here in the README and
337339
you'll be set with an upgraded version of Python.
338340

339-
_If you're not sure about the details of your current virtual environment, you can run `poetry env info` to get more information. If you've been using `pyenv` for everything, you can also see all available virtual environments with `pyenv virtualenvs`._
340-
341+
_NOTE: If you're not sure about the details of your current virtual environment, you can run `poetry env info` to get more information. If you've been using `pyenv` for everything, you can also see all available virtual environments with `pyenv virtualenvs`._
341342

342-
#### Poetry upgrades ####
343+
#### Poetry upgrades
343344

344345
If you are doing a new project setup, then after you install poetry you need to install the export plugin
345346

@@ -356,7 +357,7 @@ poetry self add poetry-export-plugin
356357

357358
### Final environment setup
358359

359-
There's one final thing to adjust in the newly created `.env` file. This
360+
There's one final thing to adjust in the newly created `.env` file. This
360361
project has support for end-to-end (E2E) tests and has some additional checks
361362
for the presence of an E2E test user so that it can be authenticated properly.
362363

@@ -380,8 +381,8 @@ variable to something else, preferably a lengthy passphrase.**
380381
With those two environment variable set, the database migrations will run
381382
properly and an E2E test user will be ready to go for use in the admin project.
382383

383-
_Note: Whatever you set these two environment variables to, you'll need to
384-
match their values on the admin side. Please see the admin README and
384+
_Note: Whatever you set these two environment variables to, you'll need to
385+
match their values on the admin side. Please see the admin README and
385386
documentation for more details._
386387

387388
## Running the Project and Routine Maintenance
@@ -407,7 +408,7 @@ make run-procfile
407408
If it runs correctly, you will be able to visit http://127.0.0.1:6011/ and see
408409
JSON from the API in your web browser.
409410

410-
This will run all of the services within the same shell session. If you need to
411+
This will run all of the services within the same shell session. If you need to
411412
run them separately to help with debugging or tracing logs, you can do so by
412413
opening three sepearate shell sessions and running one of these commands in each
413414
one separately:
@@ -419,16 +420,27 @@ one separately:
419420
## Python Dependency Management
420421

421422
We're using [`Poetry`](https://python-poetry.org/) for managing our Python
422-
dependencies and local virtual environments. When it comes to managing the
423-
Python dependencies, there are a couple of things to bear in mind.
423+
dependencies and local virtual environments.
424+
425+
This project has two key dependency files that must be managed together:
426+
427+
- `pyproject.toml` - Contains the dependency specifications
428+
- `poetry.lock` - Contains the exact versions of all dependencies (including transitive ones)
424429

425-
For situations where you manually manipulate the `pyproject.toml` file, you
426-
should use the `make py-lock` command to sync the `poetry.lock` file. This will
430+
### Managing Dependencies
431+
432+
There are two approaches for updating dependencies:
433+
434+
#### 1. Manual manipulation of `pyproject.toml`
435+
436+
If you manually edit the `pyproject.toml` file, you should use the `make py-lock` command to sync the `poetry.lock` file. This will
427437
ensure that you don't inadvertently bring in other transitive dependency updates
428438
that have not been fully tested with the project yet.
429439

430-
If you're just trying to update a dependency to a newer (or the latest) version,
431-
you should let Poetry take care of that for you by running the following:
440+
#### 2. Using Poetry to update dependencies (recommended)
441+
442+
If you're updating a dependency to a newer (or the latest) version,
443+
let Poetry handle it by running:
432444

433445
```sh
434446
poetry update <dependency> [<dependency>...]
@@ -441,9 +453,9 @@ will do the following for you:
441453
- Install the new versions
442454
- Update and sync the `poetry.lock` file
443455

444-
In either situation, once you are finished and have verified the dependency
445-
changes are working, please be sure to commit both the `pyproject.toml` and
446-
`poetry.lock` files.
456+
**Important:** In either situation, once you are finished and have verified the dependency
457+
changes are working, you must commit both the `pyproject.toml` and
458+
`poetry.lock` files together.
447459

448460
## Known Installation Issues
449461

@@ -513,7 +525,7 @@ instructions above for more details.
513525
- [Pull Requests](.docs/all.md#pull-requests)
514526
- [Getting Started](.docs/all.md#getting-started)
515527
- [Description](.docs/all.md#description)
516-
- [TODO (optional)](.docs/all.md#todo-(optional))
528+
- [TODO (optional)](<.docs/all.md#todo-(optional)>)
517529
- [Security Considerations](.docs/all.md#security-considerations)
518530
- [Code Reviews](.docs/all.md#code-reviews)
519531
- [For the reviewer](.docs/all.md#for-the-reviewer)

app/authentication/auth.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
import uuid
33

44
from flask import current_app, g, request
5+
from sqlalchemy.orm.exc import NoResultFound
6+
7+
from app.serialised_models import SerialisedService
58
from notifications_python_client.authentication import (
69
decode_jwt_token,
710
get_token_issuer,
@@ -13,9 +16,6 @@
1316
TokenExpiredError,
1417
TokenIssuerError,
1518
)
16-
from sqlalchemy.orm.exc import NoResultFound
17-
18-
from app.serialised_models import SerialisedService
1919
from notifications_utils import request_helper
2020

2121
# stvnrlly - this is silly, but bandit has a multiline string bug (https://github.com/PyCQA/bandit/issues/658)

app/commands.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
from click_datetime import Datetime as click_dt
1212
from faker import Faker
1313
from flask import current_app, json
14-
from notifications_python_client.authentication import create_jwt_token
1514
from sqlalchemy import and_, select, text, update
1615
from sqlalchemy.exc import IntegrityError
1716
from sqlalchemy.orm.exc import NoResultFound
@@ -58,6 +57,7 @@
5857
User,
5958
)
6059
from app.utils import utc_now
60+
from notifications_python_client.authentication import create_jwt_token
6161
from notifications_utils.recipients import RecipientCSV
6262
from notifications_utils.template import SMSMessageTemplate
6363
from tests.app.db import (

app/config_files/templates.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
"Notify.gov makes it easy to keep people updated by helping you send text messages.",
2121
"",
2222
"",
23+
"If you have not done so, please log out before joining.",
24+
"",
2325
"[Join Service](((url)))",
2426
"If you’re new to Notify.gov you will first be directed to Login.gov create an account with us.",
2527
"",

0 commit comments

Comments
 (0)