Skip to content

Commit c935cf1

Browse files
authored
Merge pull request #2724 from GSA/main
Production Deploy 06/30/2025
2 parents 672a1c6 + db20c88 commit c935cf1

File tree

89 files changed

+7295
-9195
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+7295
-9195
lines changed

.ds.baseline

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@
469469
"filename": "tests/app/main/test_errorhandlers.py",
470470
"hashed_secret": "005fa73b3f2be8f0d71d361c1f0a9d787cd09b4e",
471471
"is_verified": false,
472-
"line_number": 33,
472+
"line_number": 34,
473473
"is_secret": false
474474
}
475475
],
@@ -527,23 +527,23 @@
527527
"filename": "tests/app/main/views/test_register.py",
528528
"hashed_secret": "bdbb156d25d02fd7792865824201dda1c60f4473",
529529
"is_verified": false,
530-
"line_number": 122,
530+
"line_number": 114,
531531
"is_secret": false
532532
},
533533
{
534534
"type": "Secret Keyword",
535535
"filename": "tests/app/main/views/test_register.py",
536536
"hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8",
537537
"is_verified": false,
538-
"line_number": 199,
538+
"line_number": 184,
539539
"is_secret": false
540540
},
541541
{
542542
"type": "Secret Keyword",
543543
"filename": "tests/app/main/views/test_register.py",
544544
"hashed_secret": "bb5b7caa27d005d38039e3797c3ddb9bcd22c3c8",
545545
"is_verified": false,
546-
"line_number": 272,
546+
"line_number": 255,
547547
"is_secret": false
548548
}
549549
],
@@ -634,5 +634,5 @@
634634
}
635635
]
636636
},
637-
"generated_at": "2025-06-04T16:12:20Z"
637+
"generated_at": "2025-06-18T17:05:12Z"
638638
}

.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/drift.yml

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,26 @@ 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
46+
3547
3648
check_demo_drift:
3749
runs-on: ubuntu-latest
@@ -52,14 +64,25 @@ jobs:
5264
terraform_wrapper: false
5365

5466
- name: Check for drift
55-
uses: dflook/terraform-check@v1
5667
env:
5768
AWS_ACCESS_KEY_ID: ${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
5869
AWS_SECRET_ACCESS_KEY: ${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
5970
TF_VAR_cf_user: ${{ secrets.CLOUDGOV_USERNAME }}
6071
TF_VAR_cf_password: ${{ secrets.CLOUDGOV_PASSWORD }}
61-
with:
62-
path: terraform/demo
72+
run: |
73+
cd terraform/demo
74+
terraform init
75+
terraform plan -detailed-exitcode
76+
exit_code=$?
77+
if [ $exit_code -eq 0 ]; then
78+
echo "No changes detected. Intrastructure is up-to-date."
79+
elif [ $exit_code -eq 2 ]; then
80+
echo "Changes detected. Infrastructure drift found."
81+
exit 1
82+
else
83+
echo "Error running terraform plan."
84+
exit $exit_code
85+
fi
6386
6487
check_prod_drift:
6588
runs-on: ubuntu-latest
@@ -80,11 +103,22 @@ jobs:
80103
terraform_wrapper: false
81104

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

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,12 +243,12 @@ git clone git@github.com:GSA/notifications-admin.git
243243

244244
Now go into the project directory (`notifications-admin` by default), create a
245245
virtual environment, and set the local Python version to point to the virtual
246-
environment (assumes version Python `3.12.2` is what is installed on your
246+
environment (assumes version Python `3.12.9` is what is installed on your
247247
machine):
248248

249249
```sh
250250
cd notifications-admin
251-
pyenv virtualenv 3.12.2 notify-admin
251+
pyenv virtualenv 3.12.9 notify-admin
252252
pyenv local notify-admin
253253
```
254254

@@ -299,7 +299,7 @@ environment with the newer version of Python you just installed:
299299

300300
```sh
301301
cd notifications-admin
302-
pyenv virtualenv 3.12.2 notify-admin
302+
pyenv virtualenv 3.12.9 notify-admin
303303
pyenv local notify-admin
304304
```
305305

app/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
from flask_wtf import CSRFProtect
2525
from flask_wtf.csrf import CSRFError
2626
from itsdangerous import BadSignature
27-
from notifications_python_client.errors import HTTPError
2827
from werkzeug.exceptions import HTTPException as WerkzeugHTTPException
2928
from werkzeug.exceptions import abort
3029
from werkzeug.local import LocalProxy
@@ -35,6 +34,7 @@
3534
from app.extensions import redis_client
3635
from app.formatters import (
3736
convert_markdown_template,
37+
convert_time_unixtimestamp,
3838
convert_to_boolean,
3939
format_auth_type,
4040
format_billions,
@@ -111,6 +111,7 @@
111111
from app.url_converters import SimpleDateTypeConverter, TemplateTypeConverter
112112
from app.utils.api_health import is_api_down
113113
from app.utils.govuk_frontend_jinja.flask_ext import init_govuk_frontend
114+
from notifications_python_client.errors import HTTPError
114115
from notifications_utils import logging, request_helper
115116
from notifications_utils.formatters import (
116117
formatted_list,
@@ -672,6 +673,7 @@ def add_template_filters(application):
672673
format_thousands,
673674
id_safe,
674675
convert_to_boolean,
676+
convert_time_unixtimestamp,
675677
format_list_items,
676678
iteration_count,
677679
recipient_count,

app/assets/javascripts/collapsibleCheckboxes.js

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
const buttonContent = this.buttonContent[buttonState](this.fieldLabel);
6464
const stickyClass = expanded ? ' js-stick-at-bottom-when-scrolling' : '';
6565

66-
return $(`<div class="selection-footer${stickyClass}">
66+
return $(`<div class="selection-footer${stickyClass} margin-top-2">
6767
<button
6868
class="govuk-button govuk-button--secondary selection-footer__button usa-button usa-button--outline"
6969
aria-expanded="${expanded ? 'true' : 'false'}"
@@ -78,8 +78,6 @@
7878

7979
this.module.$formGroup.append(this.$el);
8080

81-
// make footer sticky if expanded, clear up from it being sticky if not
82-
GOVUK.stickAtBottomWhenScrolling.recalculate();
8381
};
8482

8583
function CollapsibleCheckboxes () {}
@@ -97,6 +95,7 @@
9795
this.total = this.$checkboxes.length;
9896
this.legendText = this.$fieldset.find('legend').first().text().trim();
9997
this.expanded = false;
98+
this.checkUncheckButtonsAdded = false;
10099

101100
this.addHeadingHideLegend();
102101

@@ -124,6 +123,44 @@
124123

125124
this.$fieldset.find('legend').addClass('usa-sr-only');
126125
};
126+
CollapsibleCheckboxes.prototype.addCheckUncheckAllButtons = function() {
127+
const $buttonsContainer = $('<div class="check-uncheck-all-buttons margin-bottom-2"></div>');
128+
129+
this.$toggleAllButton = $('<button type="button" class="usa-button usa-button--outline usa-button--small">Select all</button>');
130+
131+
$buttonsContainer.append(this.$toggleAllButton);
132+
133+
this.summary.$el.after($buttonsContainer);
134+
135+
this.$toggleAllButton.on('click', this.toggleAll.bind(this));
136+
137+
this.updateToggleButtonText();
138+
};
139+
CollapsibleCheckboxes.prototype.toggleAll = function(e) {
140+
e.preventDefault();
141+
const allChecked = this.$checkboxes.filter(':checked').length === this.$checkboxes.length;
142+
143+
if (allChecked) {
144+
this.$checkboxes.prop('checked', false);
145+
} else {
146+
this.$checkboxes.prop('checked', true);
147+
}
148+
149+
this.handleSelection();
150+
this.updateToggleButtonText();
151+
};
152+
CollapsibleCheckboxes.prototype.updateToggleButtonText = function() {
153+
if (!this.$toggleAllButton) return;
154+
155+
const checkedCount = this.$checkboxes.filter(':checked').length;
156+
const allChecked = checkedCount === this.$checkboxes.length;
157+
158+
if (allChecked) {
159+
this.$toggleAllButton.text('Deselect all');
160+
} else {
161+
this.$toggleAllButton.text('Select all');
162+
}
163+
};
127164
CollapsibleCheckboxes.prototype.expand = function(e) {
128165
if (e !== undefined) { e.preventDefault(); }
129166

@@ -132,6 +169,15 @@
132169
this.expanded = true;
133170
this.summary.update(this.getSelection());
134171
this.footer.update(this.expanded);
172+
173+
if (!this.checkUncheckButtonsAdded) {
174+
this.addCheckUncheckAllButtons();
175+
this.checkUncheckButtonsAdded = true;
176+
} else {
177+
if (this.$toggleAllButton) {
178+
this.$toggleAllButton.parent().show();
179+
}
180+
}
135181
}
136182

137183
// shift focus whether expanded or not
@@ -145,6 +191,10 @@
145191
this.expanded = false;
146192
this.summary.update(this.getSelection());
147193
this.footer.update(this.expanded);
194+
195+
if (this.$toggleAllButton) {
196+
this.$toggleAllButton.parent().hide();
197+
}
148198
}
149199

150200
// shift focus whether expanded or not
@@ -159,6 +209,7 @@
159209
};
160210
CollapsibleCheckboxes.prototype.handleSelection = function(e) {
161211
this.summary.update(this.getSelection(), this.total, this.fieldLabel);
212+
this.updateToggleButtonText();
162213
};
163214
CollapsibleCheckboxes.prototype.bindEvents = function() {
164215
const self = this;

app/assets/sass/uswds/_uswds-theme-custom-styles.scss

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,11 +547,17 @@ td.table-empty-message {
547547
background-color: #a1d3ff;
548548
}
549549

550+
#template-list,
551+
#template-list > div,
552+
.sticky-scroll-area {
553+
position: relative;
554+
}
555+
550556
#template-list {
551557
max-height: 500px;
552558
overflow-y: auto;
553559
padding: units(1) 0 units(1) units(1);
554-
margin: units(2) 0 units(5);
560+
margin: units(2) 0 units(6);
555561
ul {
556562
padding: 0;
557563
margin: 0;
@@ -1077,3 +1083,15 @@ nav.nav {
10771083
.usa-site-alert .usa-alert .usa-alert__body {
10781084
max-width: 75rem;
10791085
}
1086+
1087+
.usa-form-group--nested {
1088+
margin-top: 0;
1089+
}
1090+
1091+
.selection-content > ul > li.usa-checkbox {
1092+
margin-top: 1rem;
1093+
}
1094+
1095+
.selection-content .usa-form-group--nested li.usa-checkbox {
1096+
margin-top: 0;
1097+
}

0 commit comments

Comments
 (0)