Skip to content

Commit 251055c

Browse files
CCM-11029: provider-side contract tests (#678)
Co-authored-by: Chris Elliott <[email protected]>
1 parent c29abae commit 251055c

File tree

24 files changed

+1586
-77
lines changed

24 files changed

+1586
-77
lines changed

.github/workflows/cicd-1-pull-request.yaml

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ concurrency:
1111
group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}
1212
cancel-in-progress: false
1313

14+
permissions:
15+
id-token: write
16+
contents: write
17+
packages: read
1418

1519
jobs:
1620
metadata:
@@ -77,9 +81,23 @@ jobs:
7781
export DOES_PULL_REQUEST_EXIST="${{ steps.pr_exists.outputs.does_pull_request_exist }}"
7882
export IS_VERSION_PRERELEASE="${{ steps.variables.outputs.is_version_prerelease }}"
7983
make list-variables
84+
85+
dependencies:
86+
name: Install / cache dependencies
87+
needs: [metadata]
88+
runs-on: ubuntu-latest
89+
steps:
90+
- name: "Checkout code"
91+
uses: actions/[email protected]
92+
- name: "Install / cache node_modules"
93+
uses: ./.github/actions/node-modules-cache
94+
with:
95+
node_version: "${{ inputs.nodejs_version }}"
96+
skip_restore: true
97+
8098
commit-stage: # Recommended maximum execution time is 2 minutes
8199
name: "Commit stage"
82-
needs: [metadata]
100+
needs: [metadata, dependencies]
83101
uses: ./.github/workflows/stage-1-commit.yaml
84102
with:
85103
build_datetime: "${{ needs.metadata.outputs.build_datetime }}"
@@ -92,7 +110,7 @@ jobs:
92110
secrets: inherit
93111
test-stage: # Recommended maximum execution time is 5 minutes
94112
name: "Test stage"
95-
needs: [metadata, commit-stage]
113+
needs: [metadata, dependencies, commit-stage]
96114
uses: ./.github/workflows/stage-2-test.yaml
97115
with:
98116
build_datetime: "${{ needs.metadata.outputs.build_datetime }}"
@@ -105,7 +123,7 @@ jobs:
105123
secrets: inherit
106124
acceptance-stage: # Recommended maximum execution time is 10 minutes
107125
name: "Acceptance stage"
108-
needs: [metadata, test-stage]
126+
needs: [metadata, dependencies, test-stage]
109127
uses: ./.github/workflows/stage-4-acceptance.yaml
110128
if: needs.metadata.outputs.does_pull_request_exist == 'true' || (github.event_name == 'pull_request' && (github.event.action == 'opened' || github.event.action == 'reopened')) || (github.event_name == 'push' && github.ref == 'refs/heads/main')
111129
secrets: inherit

.github/workflows/pr_closed.yaml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,29 @@ jobs:
9999
echo "version_changed=true" >> $GITHUB_OUTPUT
100100
fi
101101
102+
test-contract-provider:
103+
name: "Test contracts (provider)"
104+
needs: check-event-schemas-version-change
105+
if: needs.check-event-schemas-version-change.outputs.version_changed == 'true'
106+
runs-on: ubuntu-latest
107+
permissions:
108+
contents: read
109+
packages: read
110+
steps:
111+
- name: "Checkout code"
112+
uses: actions/[email protected]
113+
- name: "Install dependencies"
114+
run: npm ci
115+
- name: "Run provider contract tests"
116+
run: make test-contract-provider
117+
env:
118+
GITHUB_PACKAGES_TOKEN: ${{ secrets.GITHUB_TOKEN }}
119+
102120
publish-event-schemas:
103121
name: Publish event schemas package to GitHub package registry
104-
needs: check-event-schemas-version-change
122+
needs:
123+
- check-event-schemas-version-change
124+
- test-contract-provider
105125
if: needs.check-event-schemas-version-change.outputs.version_changed == 'true'
106126
runs-on: ubuntu-latest
107127
permissions:

.github/workflows/stage-1-commit.yaml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ jobs:
7272
needs: detect-terraform-changes
7373
if: needs.detect-terraform-changes.outputs.terraform_changed == 'true'
7474
permissions:
75-
contents: write
75+
contents: write
7676
steps:
7777
- name: "Checkout code"
7878
uses: actions/[email protected]
@@ -248,8 +248,10 @@ jobs:
248248
- name: "Checkout code"
249249
uses: actions/checkout@v4
250250

251-
- name: Install dependencies
252-
run: npm ci
251+
- name: "Restore node_modules from cache"
252+
uses: ./.github/actions/node-modules-cache
253+
with:
254+
node_version: "${{ inputs.nodejs_version }}"
253255

254256
- name: Re-generate schemas
255257
run: npm --workspace packages/event-schemas run generate-json-schemas

.github/workflows/stage-2-test.yaml

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,6 @@ permissions:
4141
contents: read # This is required for actions/checkout
4242

4343
jobs:
44-
install-dependencies:
45-
name: "Install dependencies"
46-
runs-on: ubuntu-latest
47-
timeout-minutes: 5
48-
steps:
49-
- name: "Checkout code"
50-
uses: actions/[email protected]
51-
- name: "Restore node_modules from cache"
52-
uses: ./.github/actions/node-modules-cache
53-
with:
54-
node_version: "${{ inputs.nodejs_version }}"
55-
skip_restore: true
56-
5744
discover-workspaces:
5845
runs-on: ubuntu-latest
5946
outputs:
@@ -70,7 +57,6 @@ jobs:
7057
name: "Check generated dependencies"
7158
runs-on: ubuntu-latest
7259
timeout-minutes: 5
73-
needs: [install-dependencies]
7460
steps:
7561
- name: "Checkout code"
7662
uses: actions/[email protected]
@@ -87,7 +73,7 @@ jobs:
8773
name: "Unit tests"
8874
runs-on: ubuntu-latest
8975
timeout-minutes: 5
90-
needs: [install-dependencies, discover-workspaces]
76+
needs: [discover-workspaces]
9177
strategy:
9278
fail-fast: false
9379
matrix:
@@ -130,7 +116,6 @@ jobs:
130116
name: "Linting"
131117
runs-on: ubuntu-latest
132118
timeout-minutes: 5
133-
needs: [install-dependencies]
134119
steps:
135120
- name: "Checkout code"
136121
uses: actions/[email protected]
@@ -149,7 +134,6 @@ jobs:
149134
name: "Typecheck"
150135
runs-on: ubuntu-latest
151136
timeout-minutes: 5
152-
needs: [install-dependencies]
153137
steps:
154138
- name: "Checkout code"
155139
uses: actions/[email protected]
@@ -164,6 +148,25 @@ jobs:
164148
run: |
165149
make test-typecheck
166150
151+
test-contract-provider:
152+
name: "Test contracts (provider)"
153+
runs-on: ubuntu-latest
154+
permissions:
155+
contents: read
156+
packages: read
157+
steps:
158+
- name: "Checkout code"
159+
uses: actions/[email protected]
160+
- name: "Restore node_modules from cache"
161+
uses: ./.github/actions/node-modules-cache
162+
with:
163+
node_version: "${{ inputs.nodejs_version }}"
164+
- name: "Run provider contract tests"
165+
run: make test-contract-provider
166+
env:
167+
GITHUB_PACKAGES_TOKEN: ${{ secrets.GITHUB_TOKEN }}
168+
169+
167170
merge-coverage:
168171
name: "Merge coverage"
169172
runs-on: ubuntu-latest

infrastructure/terraform/components/app/README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212

1313
| Name | Description | Type | Default | Required |
1414
|------|-------------|------|---------|:--------:|
15-
| <a name="input_AMPLIFY_BASIC_AUTH_SECRET"></a> [AMPLIFY\_BASIC\_AUTH\_SECRET](#input\_AMPLIFY\_BASIC\_AUTH\_SECRET) | Secret key/password to use for Amplify Basic Auth - This is entended to be read from CI variables and not commited to any codebase | `string` | `"unset"` | no |
16-
| <a name="input_CSRF_SECRET"></a> [CSRF\_SECRET](#input\_CSRF\_SECRET) | Secure cryptographic key to be used for generating CSRF tokens - This is entended to be read from CI variables and not commited to any codebase | `string` | n/a | yes |
15+
| <a name="input_AMPLIFY_BASIC_AUTH_SECRET"></a> [AMPLIFY\_BASIC\_AUTH\_SECRET](#input\_AMPLIFY\_BASIC\_AUTH\_SECRET) | Secret key/password to use for Amplify Basic Auth - This is intended to be read from CI variables and not committed to any codebase | `string` | `"unset"` | no |
16+
| <a name="input_CSRF_SECRET"></a> [CSRF\_SECRET](#input\_CSRF\_SECRET) | Secure cryptographic key to be used for generating CSRF tokens - This is intended to be read from CI variables and not committed to any codebase | `string` | n/a | yes |
1717
| <a name="input_aws_account_id"></a> [aws\_account\_id](#input\_aws\_account\_id) | The AWS Account ID (numeric) | `string` | n/a | yes |
1818
| <a name="input_aws_principal_org_id"></a> [aws\_principal\_org\_id](#input\_aws\_principal\_org\_id) | The AWS Org ID (numeric) | `string` | n/a | yes |
1919
| <a name="input_backup_report_recipient"></a> [backup\_report\_recipient](#input\_backup\_report\_recipient) | Primary recipient of the Backup reports | `string` | `""` | no |
@@ -26,15 +26,15 @@
2626
| <a name="input_data_plane_bus_arn"></a> [data\_plane\_bus\_arn](#input\_data\_plane\_bus\_arn) | Data plane event bus arn | `string` | n/a | yes |
2727
| <a name="input_default_tags"></a> [default\_tags](#input\_default\_tags) | A map of default tags to apply to all taggable resources within the component | `map(string)` | `{}` | no |
2828
| <a name="input_destination_vault_arn"></a> [destination\_vault\_arn](#input\_destination\_vault\_arn) | ARN of the backup vault in the destination account, if this environment should be backed up | `string` | `null` | no |
29-
| <a name="input_enable_amplify_basic_auth"></a> [enable\_amplify\_basic\_auth](#input\_enable\_amplify\_basic\_auth) | Enable a basic set of credentials in the form of a dynamicly generated username and password for the amplify app branches. Not intended for production use | `bool` | `true` | no |
29+
| <a name="input_enable_amplify_basic_auth"></a> [enable\_amplify\_basic\_auth](#input\_enable\_amplify\_basic\_auth) | Enable a basic set of credentials in the form of a dynamically generated username and password for the amplify app branches. Not intended for production use | `bool` | `true` | no |
3030
| <a name="input_enable_amplify_branch_auto_build"></a> [enable\_amplify\_branch\_auto\_build](#input\_enable\_amplify\_branch\_auto\_build) | Enable automatic building of branches | `bool` | `false` | no |
31-
| <a name="input_enable_cognito_built_in_idp"></a> [enable\_cognito\_built\_in\_idp](#input\_enable\_cognito\_built\_in\_idp) | Enable the use of Cognito as an IDP; CIS2 is prefered | `bool` | `false` | no |
31+
| <a name="input_enable_cognito_built_in_idp"></a> [enable\_cognito\_built\_in\_idp](#input\_enable\_cognito\_built\_in\_idp) | Enable the use of Cognito as an IDP; CIS2 is preferred | `bool` | `false` | no |
3232
| <a name="input_enable_event_caching"></a> [enable\_event\_caching](#input\_enable\_event\_caching) | Enable caching of events to an S3 bucket | `bool` | `true` | no |
3333
| <a name="input_environment"></a> [environment](#input\_environment) | The name of the tfscaffold environment | `string` | n/a | yes |
3434
| <a name="input_event_delivery_logging"></a> [event\_delivery\_logging](#input\_event\_delivery\_logging) | Enable SNS Event Delivery logging | `bool` | `true` | no |
3535
| <a name="input_event_delivery_logging_success_sample_percentage"></a> [event\_delivery\_logging\_success\_sample\_percentage](#input\_event\_delivery\_logging\_success\_sample\_percentage) | Enable caching of events to an S3 bucket | `number` | `0` | no |
3636
| <a name="input_external_email_domain"></a> [external\_email\_domain](#input\_external\_email\_domain) | Externally managed domain used to create an SES identity for sending emails from. Validation DNS records will need to be manually configured in the DNS provider. | `string` | `null` | no |
37-
| <a name="input_group"></a> [group](#input\_group) | The group variables are being inherited from (often synonmous with account short-name) | `string` | n/a | yes |
37+
| <a name="input_group"></a> [group](#input\_group) | The group variables are being inherited from (often synonymous with account short-name) | `string` | n/a | yes |
3838
| <a name="input_kms_deletion_window"></a> [kms\_deletion\_window](#input\_kms\_deletion\_window) | When a kms key is deleted, how long should it wait in the pending deletion state? | `string` | `"30"` | no |
3939
| <a name="input_letter_suppliers"></a> [letter\_suppliers](#input\_letter\_suppliers) | Letter suppliers enabled in the environment | <pre>map(object({<br/> email_addresses = list(string)<br/> enable_polling = bool<br/> default_supplier = optional(bool)<br/> }))</pre> | `{}` | no |
4040
| <a name="input_log_retention_in_days"></a> [log\_retention\_in\_days](#input\_log\_retention\_in\_days) | The retention period in days for the Cloudwatch Logs events to be retained, default of 0 is indefinite | `number` | `0` | no |
Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
1+
# pre.sh runs in the same shell as terraform.sh, not in a subshell
2+
# any variables set or changed, any change of directory will persist once this script exits and returns control to terraform.sh
3+
14
echo "Running app pre.sh"
25

6+
# change to monorepo root
7+
cd $(git rev-parse --show-toplevel)
8+
39
npm ci
410

511
npm run generate-dependencies --workspaces --if-present
612

713
npm run lambda-build --workspaces --if-present
814

9-
$(git rev-parse --show-toplevel)/lambdas/layers/pdfjs/build.sh
15+
lambdas/layers/pdfjs/build.sh
16+
17+
# revert back to original directory
18+
cd -

infrastructure/terraform/components/app/variables.tf

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ variable "region" {
2929

3030
variable "group" {
3131
type = string
32-
description = "The group variables are being inherited from (often synonmous with account short-name)"
32+
description = "The group variables are being inherited from (often synonymous with account short-name)"
3333
}
3434

3535
##
@@ -88,28 +88,28 @@ variable "cognito_user_pool_additional_callback_urls" {
8888

8989
variable "enable_cognito_built_in_idp" {
9090
type = bool
91-
description = "Enable the use of Cognito as an IDP; CIS2 is prefered"
91+
description = "Enable the use of Cognito as an IDP; CIS2 is preferred"
9292
default = false
9393
}
9494

9595
variable "enable_amplify_basic_auth" {
9696
type = bool
97-
description = "Enable a basic set of credentials in the form of a dynamicly generated username and password for the amplify app branches. Not intended for production use"
97+
description = "Enable a basic set of credentials in the form of a dynamically generated username and password for the amplify app branches. Not intended for production use"
9898
default = true
9999
}
100100

101101
# Github Environments only handles uppercase envvars
102102
variable "AMPLIFY_BASIC_AUTH_SECRET" {
103103
# Github only does uppercase env vars
104104
type = string
105-
description = "Secret key/password to use for Amplify Basic Auth - This is entended to be read from CI variables and not commited to any codebase"
105+
description = "Secret key/password to use for Amplify Basic Auth - This is intended to be read from CI variables and not committed to any codebase"
106106
default = "unset"
107107
}
108108

109109
variable "CSRF_SECRET" {
110110
# Github only does uppercase env vars
111111
type = string
112-
description = "Secure cryptographic key to be used for generating CSRF tokens - This is entended to be read from CI variables and not commited to any codebase"
112+
description = "Secure cryptographic key to be used for generating CSRF tokens - This is intended to be read from CI variables and not committed to any codebase"
113113
}
114114

115115
variable "branch_name" {

infrastructure/terraform/components/sandbox/pre.sh

100644100755
Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,35 @@ REGION=$1
22
ENVIRONMENT=$2
33
ACTION=$3
44

5-
echo Running pre.sh
5+
# pre.sh runs in the same shell as terraform.sh, not in a subshell
6+
# any variables set or changed, and change of directory will persist once this script exits and returns control to terraform.sh
7+
8+
echo "Running sandbox pre.sh"
69
echo "REGION=$REGION"
710
echo "ENVIRONMENT=$ENVIRONMENT"
811
echo "ACTION=$ACTION"
912

13+
# change to monorepo root
14+
cd $(git rev-parse --show-toplevel)
15+
1016
if [ "${ACTION}" == "apply" ]; then
1117
echo "Building lambdas for distribution"
1218

13-
if [ -z "$SKIP_SANDBOX_INSTALL" ]; then npm ci; fi
19+
if [[ -z $SKIP_SANDBOX_INSTALL ]]; then
20+
echo "Installing dependencies"
21+
npm ci;
22+
else
23+
echo "Skipping dependency installation"
24+
fi
1425

1526
npm run generate-dependencies --workspaces --if-present
1627

1728
npm run lambda-build --workspaces --if-present
1829

19-
$(git rev-parse --show-toplevel)/lambdas/layers/pdfjs/build.sh
30+
lambdas/layers/pdfjs/build.sh
2031
else
2132
echo "Skipping lambda build for action $ACTION"
2233
fi
34+
35+
# revert back to original directory
36+
cd -

lambdas/event-publisher/src/__tests__/domain/event-builder.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { EventBuilder } from '../../domain/event-builder';
1+
import { VERSION } from '@nhsdigital/nhs-notify-event-schemas-template-management';
22
import { createMockLogger } from 'nhs-notify-web-template-management-test-helper-utils/mock-logger';
3+
import { EventBuilder } from '../../domain/event-builder';
34
import { PublishableEventRecord } from '../../domain/input-schemas';
45
import { shouldPublish } from '../../domain/should-publish';
56

@@ -201,7 +202,7 @@ const expectedEvent = (status: string, type: string, dataschema: string) => ({
201202
type,
202203
specversion: '1.0',
203204
dataschema,
204-
dataschemaversion: '1.1.1',
205+
dataschemaversion: VERSION,
205206
plane: 'control',
206207
subject: '92b676e9-470f-4d04-ab14-965ef145e15d',
207208
data: {

0 commit comments

Comments
 (0)