Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
55a4805
CCM-15372: Refactor Docker Build Mechanism
jamesthompson26-nhs Mar 18, 2026
611da64
CCM-15372: Refactor Docker Build Mechanism
jamesthompson26-nhs Mar 18, 2026
fc5e40d
CCM-15372: Refactor Docker Build Mechanism
jamesthompson26-nhs Mar 18, 2026
868e3d5
CCM-15372: Refactor Docker Build Mechanism
jamesthompson26-nhs Mar 18, 2026
1bdc659
CCM-15372: Refactor Docker Build Mechanism
jamesthompson26-nhs Mar 18, 2026
72142ce
CCM-15372: Refactor Docker Build Mechanism
jamesthompson26-nhs Mar 18, 2026
98edd62
CCM-15372: Refactor Docker Build Mechanism
jamesthompson26-nhs Mar 18, 2026
883cc49
CCM-15372: Refactor Docker Build Mechanism
jamesthompson26-nhs Mar 18, 2026
239f788
CCM-15372: Refactor Docker Build Mechanism
jamesthompson26-nhs Mar 18, 2026
6bc65c6
CCM-15372: Refactor Docker Build Mechanism
jamesthompson26-nhs Mar 18, 2026
f38c890
CCM-15372: Refactor Docker Build Mechanism
jamesthompson26-nhs Mar 18, 2026
f500e30
CCM-15372: Refactor Docker Build Mechanism
jamesthompson26-nhs Mar 18, 2026
6f2a17a
CCM-15372: Refactor Docker Build Mechanism
jamesthompson26-nhs Mar 19, 2026
a3da332
CCM-15372: Refactor Docker Build Mechanism
jamesthompson26-nhs Mar 19, 2026
abe0bb7
CCM-15372: Refactor Docker Build Mechanism
jamesthompson26-nhs Mar 19, 2026
79978b0
CCM-15372: Refactor Docker Build Mechanism
jamesthompson26-nhs Mar 19, 2026
ec27bb6
CCM-15372: Refactor Docker Build Mechanism
jamesthompson26-nhs Mar 19, 2026
21d8511
CCM-15372: Refactor Docker Build Mechanism
jamesthompson26-nhs Mar 20, 2026
b085153
CCM-15372: Refactor Docker Build Mechanism
jamesthompson26-nhs Mar 20, 2026
9388e0e
CCM-15372: Refactor Docker Build Mechanism
jamesthompson26-nhs Mar 20, 2026
81cf935
CCM-15372: Refactor Docker Build Mechanism
jamesthompson26-nhs Mar 20, 2026
b923eaf
CCM-15372_Refactoring Container Build Flow
aidenvaines-cgi Mar 20, 2026
573d237
CCM-15372 updating packagelock
aidenvaines-cgi Mar 20, 2026
fb5b1be
CCM-15372 updating packagelock
aidenvaines-cgi Mar 20, 2026
b494bae
Merge branch 'main' into feature/CCM-15372_Refactor_Docker_Build_Mech…
aidenvaines-cgi Mar 20, 2026
8a0a095
CCM-15372: replacing lambda-build build:archive
aidenvaines-cgi Mar 20, 2026
0c59f7b
CCM-14307 Bumping Trivy
aidenvaines-cgi Mar 23, 2026
9164caa
CCM-15372: Update package lock with npm install
jamesthompson26-nhs Mar 23, 2026
c0ac6f0
CCM-15372: Update package lock with npm install
jamesthompson26-nhs Mar 23, 2026
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
1 change: 0 additions & 1 deletion .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@
# Deployment related

GITHUB_TOKEN=Github Personal Access Token with packages:read permissions
GITHUB_ACTOR=Github username associated with the token
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ nodejs 22.22.0
pre-commit 3.6.0
terraform 1.10.1
terraform-docs 0.19.0
trivy 0.69.2
trivy 0.69.3
vale 3.6.0
python 3.13.2

Expand Down
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,22 @@ Agents should look for a nested `AGENTS.md` in or near these areas before making
The root `package.json` is the orchestration manifestgit co for this repo. It does not ship application code; it wires up shared dev tooling and delegates to workspace-level projects.

- Workspaces: Declares the set of npm workspaces (e.g. under `lambdas/`, `utils/`, `tests/`, `scripts/`). Agents should add a new workspace path here when introducing a new npm project.
- Scripts: Provides top-level commands that fan out across workspaces using `--workspaces` (lint, typecheck, unit tests) and project-specific runners (e.g. `lambda-build`).
- Scripts: Provides top-level commands that fan out across workspaces using `--workspaces` (lint, typecheck, unit tests) and project-specific runners (e.g. `build:archive`).
- Dev tool dependencies: Centralises Jest, TypeScript, ESLint configurations and plugins to keep versions consistent across workspaces. Workspace projects should rely on these unless a local override is strictly needed.
- Overrides/resolutions: Pins transitive dependencies (e.g. Jest/react-is) to avoid ecosystem conflicts. Agents must not remove overrides without verifying tests across all workspaces.

Agent guidance:

- Before adding or removing a workspace, update the root `workspaces` array and ensure CI scripts still succeed with `npm run lint`, `npm run typecheck`, and `npm run test:unit` at the repo root.
- When adding repo-wide scripts, keep names consistent with existing patterns (e.g. `lint`, `lint:fix`, `typecheck`, `test:unit`, `lambda-build`) and prefer `--workspaces` fan-out.
- When adding repo-wide scripts, keep names consistent with existing patterns (e.g. `lint`, `lint:fix`, `typecheck`, `test:unit`, `build:archive`) and prefer `--workspaces` fan-out.
- Do not publish from the root. If adding a new workspace intended for publication, mark that workspace package as `private: false` and keep the root as private.
- Validate changes by running the repo pre-commit hooks: `make githooks-run`.

Success criteria for changes affecting the root `package.json`:

- `npm run lint`, `npm run typecheck`, and `npm run test:unit` pass at the repo root.
- Workspace discovery is correct (new projects appear under `npm run typecheck --workspaces`).
- No regression in lambda build tooling (`npm run lambda-build`).
- No regression in lambda build tooling (`npm run build:archive`).

## What Agents Can / Can’t Do

Expand Down
8 changes: 4 additions & 4 deletions infrastructure/terraform/bin/terraform.sh
Original file line number Diff line number Diff line change
Expand Up @@ -391,8 +391,8 @@ rm -rf ${component_path}/.terraform;

# Run global pre.sh
if [ -f "pre.sh" ]; then
source pre.sh "${region}" "${environment}" "${action}" \
|| error_and_die "Global pre script execution failed with exit code ${?}";
PROJECT="${project}" REGION="${region}" COMPONENT="${component}" AWS_ACCOUNT_ID="${aws_account_id}" ENVIRONMENT="${environment}" ACTION="${action}" \
source pre.sh || error_and_die "Global pre script execution failed with exit code ${?}";
fi;

# Make sure we're running in the component directory
Expand Down Expand Up @@ -427,8 +427,8 @@ fi;

# Run pre.sh
if [ -f "pre.sh" ]; then
source pre.sh "${region}" "${environment}" "${action}" \
|| error_and_die "Component pre script execution failed with exit code ${?}";
PROJECT="${project}" REGION="${region}" COMPONENT="${component}" AWS_ACCOUNT_ID="${aws_account_id}" ENVIRONMENT="${environment}" ACTION="${action}" \
source pre.sh || error_and_die "Component pre script execution failed with exit code ${?}";
fi;

# Pull down secret TFVAR file from S3
Expand Down
77 changes: 60 additions & 17 deletions infrastructure/terraform/components/app/pre.sh
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,8 +1,44 @@
#!/bin/bash

# This script is run before Terraform executable commands.
# It ensures all Node.js dependencies are installed, generates any required dependencies,
# and builds all Lambda functions in the workspace before Terraform provisions infrastructure.
# 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
REGION=$1
ENVIRONMENT=$2
ACTION=$3

: "${PROJECT:?PROJECT is required}"
: "${AWS_REGION:?AWS_REGION is required}"
: "${COMPONENT:?COMPONENT is required}"
: "${ENVIRONMENT:?ENVIRONMENT is required}"
: "${AWS_ACCOUNT_ID:?AWS_ACCOUNT_ID is required}"
: "${ACTION:?ACTION is required}"
REPO_ROOT="$(git rev-parse --show-toplevel)"

echo "Running app pre.sh"
echo "ENVIRONMENT=$ENVIRONMENT"
echo "ACTION=$ACTION"
echo "PROJECT=$PROJECT"
echo "COMPONENT=$COMPONENT"
echo "AWS_REGION=$REGION"
echo "AWS_ACCOUNT_ID=$AWS_ACCOUNT_ID"
echo "REPO_ROOT=$REPO_ROOT"

# Calculate container image prefix from PROJECT, ENVIRONMENT, COMPONENT
CONTAINER_IMAGE_PREFIX="${PROJECT}-${ENVIRONMENT}-${COMPONENT}"
echo "CONTAINER_IMAGE_PREFIX: ${CONTAINER_IMAGE_PREFIX}"

# Translate ACTION to PUBLISH_CONTAINER_IMAGE (build)
if [ "${ACTION}" = "plan" ]; then
PUBLISH_CONTAINER_IMAGE="false"
else
PUBLISH_CONTAINER_IMAGE="true"
fi

if [ -f "${REPO_ROOT}/.env" ]; then
set -a
# shellcheck disable=SC1090
. "${REPO_ROOT}/.env"
set +a
fi

# Helper function for error handling
run_or_fail() {
Expand All @@ -13,28 +49,35 @@ run_or_fail() {
fi
}

echo "Running app pre.sh"
echo "REGION=$REGION"
echo "ENVIRONMENT=$ENVIRONMENT"
echo "ACTION=$ACTION"
# Switch to repo root
pushd "${REPO_ROOT}" || exit 1

# Calculate git-based version suffix
SHORT_SHA="$(git rev-parse --short HEAD)"
GIT_TAG="$(git describe --tags --exact-match 2>/dev/null || true)"

if [ -n "${GIT_TAG}" ]; then
RELEASE_VERSION="${GIT_TAG#v}"
export TF_VAR_container_image_tag_suffix="release-${RELEASE_VERSION}-$(git rev-parse --short HEAD)"
echo "On tag: $GIT_TAG, image tag suffixes will be: release-${RELEASE_VERSION}-$(git rev-parse --short HEAD)"
CONTAINER_IMAGE_SUFFIX="release-${RELEASE_VERSION}-${SHORT_SHA}"
echo "On tag: $GIT_TAG, image suffix: ${CONTAINER_IMAGE_SUFFIX}"
else
export TF_VAR_container_image_tag_suffix="sha-$(git rev-parse --short HEAD)"
echo "Not on a tag, image tag suffix will be: sha-$(git rev-parse --short HEAD)"
CONTAINER_IMAGE_SUFFIX="sha-${SHORT_SHA}"
echo "Not on a tag, image suffix: ${CONTAINER_IMAGE_SUFFIX}"
fi

# change to monorepo root
cd $(git rev-parse --show-toplevel)
# Export for Terraform
export TF_VAR_container_image_tag_suffix="${CONTAINER_IMAGE_SUFFIX}"

run_or_fail npm ci
run_or_fail npm run generate-dependencies --workspaces --if-present
run_or_fail npm run lambda-build --workspaces --if-present
run_or_fail npm run build:archive --workspaces --if-present
run_or_fail env \
CONTAINER_IMAGE_PREFIX="${CONTAINER_IMAGE_PREFIX}" \
CONTAINER_IMAGE_SUFFIX="${CONTAINER_IMAGE_SUFFIX}" \
AWS_ACCOUNT_ID="${AWS_ACCOUNT_ID}" \
AWS_REGION="${REGION}" \
PUBLISH_CONTAINER_IMAGE="${PUBLISH_CONTAINER_IMAGE}" \
npm run build:container --workspaces --if-present
run_or_fail lambdas/layers/pdfjs/build.sh

# revert back to original directory
cd -
popd || exit 1 # Return to working directory
77 changes: 60 additions & 17 deletions infrastructure/terraform/components/sbx/pre.sh
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,8 +1,44 @@
#!/bin/bash

# This script is run before Terraform executable commands.
# It ensures all Node.js dependencies are installed, generates any required dependencies,
# and builds all Lambda functions in the workspace before Terraform provisions infrastructure.
# 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
REGION=$1
ENVIRONMENT=$2
ACTION=$3

: "${PROJECT:?PROJECT is required}"
: "${AWS_REGION:?AWS_REGION is required}"
: "${COMPONENT:?COMPONENT is required}"
: "${ENVIRONMENT:?ENVIRONMENT is required}"
: "${AWS_ACCOUNT_ID:?AWS_ACCOUNT_ID is required}"
: "${ACTION:?ACTION is required}"
REPO_ROOT="$(git rev-parse --show-toplevel)"

echo "Running sbx pre.sh"
echo "ENVIRONMENT=$ENVIRONMENT"
echo "ACTION=$ACTION"
echo "PROJECT=$PROJECT"
echo "COMPONENT=$COMPONENT"
echo "AWS_REGION=$REGION"
echo "AWS_ACCOUNT_ID=$AWS_ACCOUNT_ID"
echo "REPO_ROOT=$REPO_ROOT"

# Calculate container image prefix from PROJECT, ENVIRONMENT, COMPONENT
CONTAINER_IMAGE_PREFIX="${PROJECT}-${ENVIRONMENT}-${COMPONENT}"
echo "CONTAINER_IMAGE_PREFIX: ${CONTAINER_IMAGE_PREFIX}"

# Translate ACTION to PUBLISH_CONTAINER_IMAGE (build)
if [ "${ACTION}" = "plan" ]; then
PUBLISH_CONTAINER_IMAGE="false"
else
PUBLISH_CONTAINER_IMAGE="true"
fi

if [ -f "${REPO_ROOT}/.env" ]; then
set -a
# shellcheck disable=SC1090
. "${REPO_ROOT}/.env"
set +a
fi

# Helper function for error handling
run_or_fail() {
Expand All @@ -13,23 +49,24 @@ run_or_fail() {
fi
}

echo "Running sandbox pre.sh"
echo "REGION=$REGION"
echo "ENVIRONMENT=$ENVIRONMENT"
echo "ACTION=$ACTION"
# Switch to repo root
pushd "${REPO_ROOT}" || exit 1

# Calculate git-based version suffix
SHORT_SHA="$(git rev-parse --short HEAD)"
GIT_TAG="$(git describe --tags --exact-match 2>/dev/null || true)"

if [ -n "${GIT_TAG}" ]; then
RELEASE_VERSION="${GIT_TAG#v}"
export TF_VAR_container_image_tag_suffix="release-${RELEASE_VERSION}-$(git rev-parse --short HEAD)"
echo "On tag: $GIT_TAG, image tag suffixes will be: release-${RELEASE_VERSION}-$(git rev-parse --short HEAD)"
CONTAINER_IMAGE_SUFFIX="release-${RELEASE_VERSION}-${SHORT_SHA}"
echo "On tag: $GIT_TAG, image suffix: ${CONTAINER_IMAGE_SUFFIX}"
else
export TF_VAR_container_image_tag_suffix="sha-$(git rev-parse --short HEAD)"
echo "Not on a tag, image tag suffix will be: sha-$(git rev-parse --short HEAD)"
CONTAINER_IMAGE_SUFFIX="sha-${SHORT_SHA}"
echo "Not on a tag, image suffix: ${CONTAINER_IMAGE_SUFFIX}"
fi

# change to monorepo root
cd $(git rev-parse --show-toplevel)
# Export for Terraform
export TF_VAR_container_image_tag_suffix="${CONTAINER_IMAGE_SUFFIX}"

case "${ACTION}" in
apply)
Expand All @@ -43,7 +80,14 @@ case "${ACTION}" in
fi

run_or_fail npm run generate-dependencies --workspaces --if-present
run_or_fail npm run lambda-build --workspaces --if-present
run_or_fail npm run build:archive --workspaces --if-present
run_or_fail env \
CONTAINER_IMAGE_PREFIX="${CONTAINER_IMAGE_PREFIX}" \
CONTAINER_IMAGE_SUFFIX="${CONTAINER_IMAGE_SUFFIX}" \
AWS_ACCOUNT_ID="${AWS_ACCOUNT_ID}" \
AWS_REGION="${AWS_REGION}" \
PUBLISH_CONTAINER_IMAGE="${PUBLISH_CONTAINER_IMAGE}" \
npm run build:container --workspaces --if-present
run_or_fail lambdas/layers/pdfjs/build.sh
;;
plan)
Expand All @@ -54,5 +98,4 @@ case "${ACTION}" in
;;
esac

# revert back to original directory
cd -
popd || exit 1 # Return to working directory
2 changes: 1 addition & 1 deletion lambdas/authorizer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"name": "nhs-notify-templates-api-authorizer",
"private": true,
"scripts": {
"lambda-build": "rm -rf dist && npx esbuild --bundle --minify --sourcemap --target=es2020 --platform=node --loader:.node=file --entry-names=[name] --outdir=dist src/index.ts",
"build:archive": "rm -rf dist && npx esbuild --bundle --minify --sourcemap --target=es2020 --platform=node --loader:.node=file --entry-names=[name] --outdir=dist src/index.ts",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"test:unit": "jest",
Expand Down
2 changes: 1 addition & 1 deletion lambdas/backend-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"name": "nhs-notify-backend-api",
"private": true,
"scripts": {
"lambda-build": "./build.sh",
"build:archive": "./build.sh",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"test:unit": "NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules\" npx jest",
Expand Down
2 changes: 1 addition & 1 deletion lambdas/cognito-triggers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"name": "cognito-triggers",
"private": true,
"scripts": {
"lambda-build": "./build.sh",
"build:archive": "./build.sh",
"lint": "eslint ./src",
"lint:fix": "eslint ./src --fix",
"test:unit": "jest",
Expand Down
2 changes: 1 addition & 1 deletion lambdas/download-authorizer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"name": "nhs-notify-download-authorizer",
"private": true,
"scripts": {
"lambda-build": "rm -rf dist && npx esbuild --bundle --minify --sourcemap --target=es2020 --platform=node --loader:.node=file --entry-names=[name] --outdir=dist src/index.ts",
"build:archive": "rm -rf dist && npx esbuild --bundle --minify --sourcemap --target=es2020 --platform=node --loader:.node=file --entry-names=[name] --outdir=dist src/index.ts",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"test:unit": "jest",
Expand Down
2 changes: 1 addition & 1 deletion lambdas/event-publisher/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"name": "nhs-notify-templates-event-publisher",
"private": true,
"scripts": {
"lambda-build": "./build.sh",
"build:archive": "./build.sh",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"test:unit": "jest",
Expand Down
2 changes: 1 addition & 1 deletion lambdas/letter-preview-renderer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"name": "nhs-notify-templates-letter-preview-renderer",
"private": true,
"scripts": {
"lambda-build": "../../scripts/lambda-container-build/docker.sh --base-image ghcr.io/nhsdigital/nhs-notify/libreoffice-amet-node-22:latest",
"build:container": "cd ../.. && make docker-build-and-push base_image=ghcr.io/nhsdigital/nhs-notify/libreoffice-amet-node-22:latest dir=lambdas/letter-preview-renderer",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"test:unit": "jest",
Expand Down
2 changes: 1 addition & 1 deletion lambdas/sftp-letters/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"name": "nhs-notify-sftp-letters-lambdas",
"private": true,
"scripts": {
"lambda-build": "./build.sh",
"build:archive": "./build.sh",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"test:unit": "jest",
Expand Down
Loading
Loading