Skip to content
Merged
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
b4cf24f
CCM-11029: provider contract tests
harrim91 Sep 10, 2025
3849dc2
CCM-11029: syntax fix
harrim91 Sep 10, 2025
e1fd1a4
CCM-11029: configure install from github packages
harrim91 Sep 11, 2025
9ea1e08
CCM-11029: add ci scripts
harrim91 Sep 11, 2025
9726c71
CCM-11029: run pre.sh from root
harrim91 Sep 11, 2025
e0c2dbd
CCM-11029: cd back to original location
harrim91 Sep 11, 2025
bc6e045
CCM-11029: logging
harrim91 Sep 11, 2025
0cc8955
CCM-11029: error handling in pre.sh
harrim91 Sep 12, 2025
f3fc7cd
CCM-11029: handle unset env var
harrim91 Sep 12, 2025
168efee
Merge branch 'main' into feature/CCM-11029_run-pact-tests
harrim91 Sep 12, 2025
cc0a9c1
CCM-11029: post sync install
harrim91 Sep 12, 2025
2e2bb06
CCM-11029: debug log
harrim91 Sep 12, 2025
dc4739d
CCM-11029: more logging
harrim91 Sep 12, 2025
4fc8391
CCM-11029: revert things
harrim91 Sep 12, 2025
b66564e
CCM-11029: cd not pushd
harrim91 Sep 12, 2025
263d5e3
CCM-11029: add dedicated package read pat param
harrim91 Sep 12, 2025
79e4205
CCM-11029: fix amplify permissions
harrim91 Sep 12, 2025
c4ef7c6
CCM-11029: tidy
harrim91 Sep 12, 2025
e3677e7
CCM-11029: fake package change for testing
harrim91 Sep 15, 2025
c8ff76c
CCM-11029: lockfile
harrim91 Sep 15, 2025
2088251
CCM-11029: install script
harrim91 Sep 15, 2025
6a9ef5d
CCM-11029: revert testing changes
harrim91 Sep 15, 2025
184ee2d
CCM-11029: variable name
harrim91 Sep 15, 2025
9a5abf9
Merge branch 'main' into feature/CCM-11029_run-pact-tests
harrim91 Sep 17, 2025
6bf5c12
CCM-11029: always run contract tests in ci
harrim91 Sep 17, 2025
b414336
CCM-11029: workflow permissions
harrim91 Sep 17, 2025
9a8d5d1
CCM-11029: lower level permission
harrim91 Sep 17, 2025
d449617
CCM-11029: permissions tweak
harrim91 Sep 17, 2025
535336a
CCM-11029: set github token before running contract tests
harrim91 Sep 17, 2025
edb1ab9
CCM-11029: fix github token script
harrim91 Sep 18, 2025
739686f
Merge branch 'main' into feature/CCM-11029_run-pact-tests
harrim91 Sep 19, 2025
2509d17
CCM-11029: remove dupe ssh param
harrim91 Sep 22, 2025
27aa3b1
CCM-11029: Regenerate package lock
chris-elliott-nhsd Sep 22, 2025
bd87238
Revert "CCM-11029: remove dupe ssh param"
harrim91 Sep 23, 2025
00ab1b2
CCM-11029: lockfile
harrim91 Sep 23, 2025
cf60fde
CCM-11029: rename token env var
harrim91 Sep 23, 2025
99ba8a0
Merge branch 'main' into feature/CCM-11029_run-pact-tests
harrim91 Sep 24, 2025
041acf5
CCM-11029: lockfile
harrim91 Sep 24, 2025
a559b4b
CCM-11029: fix
harrim91 Sep 24, 2025
19143ea
CCM-11029: revert schema package readme
harrim91 Sep 24, 2025
b670d5a
CCM-11029: install contracts from tgz, revert all gh permission changes
harrim91 Sep 24, 2025
83d4842
Merge branch 'main' into feature/CCM-11029_run-pact-tests
harrim91 Sep 24, 2025
b6bdfdf
CCM-11029: fix unit test
harrim91 Sep 25, 2025
4a17028
CCM-11029: lockfile
harrim91 Sep 25, 2025
47a6183
CCM-11029: PR feedback
harrim91 Sep 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions .github/workflows/cicd-1-pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,23 @@
export DOES_PULL_REQUEST_EXIST="${{ steps.pr_exists.outputs.does_pull_request_exist }}"
export IS_VERSION_PRERELEASE="${{ steps.variables.outputs.is_version_prerelease }}"
make list-variables

dependencies:
name: Install / cache dependencies
needs: [metadata]
runs-on: ubuntu-latest
steps:
- name: "Checkout code"
uses: actions/checkout@v5.0.0
- name: "Install / cache node_modules"
uses: ./.github/actions/node-modules-cache
with:
node_version: "${{ inputs.nodejs_version }}"
skip_restore: true

commit-stage: # Recommended maximum execution time is 2 minutes

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
name: "Commit stage"
needs: [metadata]
needs: [metadata, dependencies]
uses: ./.github/workflows/stage-1-commit.yaml
with:
build_datetime: "${{ needs.metadata.outputs.build_datetime }}"
Expand All @@ -92,7 +106,7 @@
secrets: inherit
test-stage: # Recommended maximum execution time is 5 minutes
name: "Test stage"
needs: [metadata, commit-stage]
needs: [metadata, dependencies, commit-stage]
uses: ./.github/workflows/stage-2-test.yaml
with:
build_datetime: "${{ needs.metadata.outputs.build_datetime }}"
Expand All @@ -105,7 +119,7 @@
secrets: inherit
acceptance-stage: # Recommended maximum execution time is 10 minutes
name: "Acceptance stage"
needs: [metadata, test-stage]
needs: [metadata, dependencies, test-stage]
uses: ./.github/workflows/stage-4-acceptance.yaml
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')
secrets: inherit
Expand Down
22 changes: 21 additions & 1 deletion .github/workflows/pr_closed.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,29 @@ jobs:
echo "version_changed=true" >> $GITHUB_OUTPUT
fi

test-contract-provider:
name: "Test contracts (provider)"
needs: check-event-schemas-version-change
if: needs.check-event-schemas-version-change.outputs.version_changed == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
packages: read
steps:
- name: "Checkout code"
uses: actions/checkout@v5.0.0
- name: "Install dependencies"
run: npm ci
- name: "Run provider contract tests"
run: make test-contract-provider
env:
GITHUB_PACKAGES_TOKEN: ${{ secrets.GITHUB_TOKEN }}

publish-event-schemas:
name: Publish event schemas package to GitHub package registry
needs: check-event-schemas-version-change
needs:
- check-event-schemas-version-change
- test-contract-provider
if: needs.check-event-schemas-version-change.outputs.version_changed == 'true'
runs-on: ubuntu-latest
permissions:
Expand Down
8 changes: 5 additions & 3 deletions .github/workflows/stage-1-commit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ jobs:
needs: detect-terraform-changes
if: needs.detect-terraform-changes.outputs.terraform_changed == 'true'
permissions:
contents: write
contents: write
steps:
- name: "Checkout code"
uses: actions/checkout@v5.0.0
Expand Down Expand Up @@ -248,8 +248,10 @@ jobs:
- name: "Checkout code"
uses: actions/checkout@v4

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

- name: Re-generate schemas
run: npm --workspace packages/event-schemas run generate-json-schemas
Expand Down
37 changes: 20 additions & 17 deletions .github/workflows/stage-2-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,6 @@ permissions:
contents: read # This is required for actions/checkout

jobs:
install-dependencies:
name: "Install dependencies"
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: "Checkout code"
uses: actions/checkout@v5.0.0
- name: "Restore node_modules from cache"
uses: ./.github/actions/node-modules-cache
with:
node_version: "${{ inputs.nodejs_version }}"
skip_restore: true

discover-workspaces:
runs-on: ubuntu-latest
outputs:
Expand All @@ -70,7 +57,6 @@ jobs:
name: "Check generated dependencies"
runs-on: ubuntu-latest
timeout-minutes: 5
needs: [install-dependencies]
steps:
- name: "Checkout code"
uses: actions/checkout@v5.0.0
Expand All @@ -87,7 +73,7 @@ jobs:
name: "Unit tests"
runs-on: ubuntu-latest
timeout-minutes: 5
needs: [install-dependencies, discover-workspaces]
needs: [discover-workspaces]
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -130,7 +116,6 @@ jobs:
name: "Linting"
runs-on: ubuntu-latest
timeout-minutes: 5
needs: [install-dependencies]
steps:
- name: "Checkout code"
uses: actions/checkout@v5.0.0
Expand All @@ -149,7 +134,6 @@ jobs:
name: "Typecheck"
runs-on: ubuntu-latest
timeout-minutes: 5
needs: [install-dependencies]
steps:
- name: "Checkout code"
uses: actions/checkout@v5.0.0
Expand All @@ -164,6 +148,25 @@ jobs:
run: |
make test-typecheck

test-contract-provider:
name: "Test contracts (provider)"
runs-on: ubuntu-latest
permissions:
contents: read
packages: read
steps:
- name: "Checkout code"
uses: actions/checkout@v5.0.0
- name: "Restore node_modules from cache"
uses: ./.github/actions/node-modules-cache
with:
node_version: "${{ inputs.nodejs_version }}"
- name: "Run provider contract tests"
run: make test-contract-provider
env:
GITHUB_PACKAGES_TOKEN: ${{ secrets.GITHUB_TOKEN }}


merge-coverage:
name: "Merge coverage"
runs-on: ubuntu-latest
Expand Down
10 changes: 5 additions & 5 deletions infrastructure/terraform/components/app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <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 |
| <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 |
| <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 |
| <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 |
| <a name="input_aws_account_id"></a> [aws\_account\_id](#input\_aws\_account\_id) | The AWS Account ID (numeric) | `string` | n/a | yes |
| <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 |
| <a name="input_backup_report_recipient"></a> [backup\_report\_recipient](#input\_backup\_report\_recipient) | Primary recipient of the Backup reports | `string` | `""` | no |
Expand All @@ -26,15 +26,15 @@
| <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 |
| <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 |
| <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 |
| <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 |
| <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 |
| <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 |
| <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 |
| <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 |
| <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 |
| <a name="input_environment"></a> [environment](#input\_environment) | The name of the tfscaffold environment | `string` | n/a | yes |
| <a name="input_event_delivery_logging"></a> [event\_delivery\_logging](#input\_event\_delivery\_logging) | Enable SNS Event Delivery logging | `bool` | `true` | no |
| <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 |
| <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 |
| <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 |
| <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 |
| <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 |
| <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 |
| <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 |
Expand Down
11 changes: 10 additions & 1 deletion infrastructure/terraform/components/app/pre.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
# pre.sh runs in the same shell as terraform.sh, not in a subshell
# any variables set or changed, any change of directory will persist once this script exits and returns control to terraform.sh

echo "Running app pre.sh"

# change to monorepo root
cd $(git rev-parse --show-toplevel)

npm ci

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

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

$(git rev-parse --show-toplevel)/lambdas/layers/pdfjs/build.sh
lambdas/layers/pdfjs/build.sh

# revert back to original directory
cd -
10 changes: 5 additions & 5 deletions infrastructure/terraform/components/app/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ variable "region" {

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

##
Expand Down Expand Up @@ -88,28 +88,28 @@ variable "cognito_user_pool_additional_callback_urls" {

variable "enable_cognito_built_in_idp" {
type = bool
description = "Enable the use of Cognito as an IDP; CIS2 is prefered"
description = "Enable the use of Cognito as an IDP; CIS2 is preferred"
default = false
}

variable "enable_amplify_basic_auth" {
type = bool
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"
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"
default = true
}

# Github Environments only handles uppercase envvars
variable "AMPLIFY_BASIC_AUTH_SECRET" {
# Github only does uppercase env vars
type = string
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"
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"
default = "unset"
}

variable "CSRF_SECRET" {
# Github only does uppercase env vars
type = string
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"
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"
}

variable "branch_name" {
Expand Down
20 changes: 17 additions & 3 deletions infrastructure/terraform/components/sandbox/pre.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,35 @@ REGION=$1
ENVIRONMENT=$2
ACTION=$3

echo Running pre.sh
# pre.sh runs in the same shell as terraform.sh, not in a subshell
# any variables set or changed, and change of directory will persist once this script exits and returns control to terraform.sh

echo "Running sandbox pre.sh"
echo "REGION=$REGION"
echo "ENVIRONMENT=$ENVIRONMENT"
echo "ACTION=$ACTION"

# change to monorepo root
cd $(git rev-parse --show-toplevel)

if [ "${ACTION}" == "apply" ]; then
echo "Building lambdas for distribution"

if [ -z "$SKIP_SANDBOX_INSTALL" ]; then npm ci; fi
if [[ -z $SKIP_SANDBOX_INSTALL ]]; then
echo "Installing dependencies"
npm ci;
else
echo "Skipping dependency installation"
fi

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

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

$(git rev-parse --show-toplevel)/lambdas/layers/pdfjs/build.sh
lambdas/layers/pdfjs/build.sh
else
echo "Skipping lambda build for action $ACTION"
fi

# revert back to original directory
cd -
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { EventBuilder } from '../../domain/event-builder';
import { VERSION } from '@nhsdigital/nhs-notify-event-schemas-template-management';
import { createMockLogger } from 'nhs-notify-web-template-management-test-helper-utils/mock-logger';
import { EventBuilder } from '../../domain/event-builder';
import { PublishableEventRecord } from '../../domain/input-schemas';
import { shouldPublish } from '../../domain/should-publish';

Expand Down Expand Up @@ -201,7 +202,7 @@ const expectedEvent = (status: string, type: string, dataschema: string) => ({
type,
specversion: '1.0',
dataschema,
dataschemaversion: '1.1.1',
dataschemaversion: VERSION,
plane: 'control',
subject: '92b676e9-470f-4d04-ab14-965ef145e15d',
data: {
Expand Down
Loading
Loading