From 0700bdf19c9373543c60d3bc0d48130b55067317 Mon Sep 17 00:00:00 2001 From: aidenvaines-bjss <54067008+aidenvaines-bjss@users.noreply.github.com> Date: Sun, 1 Mar 2026 00:19:27 +0000 Subject: [PATCH] Drift from template --- .../dispatch_internal_repo_workflow.sh | 33 ++++- scripts/config/pre-commit.yaml | 17 +-- scripts/config/trivy.yaml | 1 + scripts/githooks/check-file-format.sh | 4 +- scripts/githooks/check-todos.sh | 4 +- scripts/init.mk | 2 +- scripts/lambda-container-build/docker.sh | 129 ++++++++++++++++++ 7 files changed, 163 insertions(+), 27 deletions(-) create mode 100755 scripts/lambda-container-build/docker.sh diff --git a/.github/scripts/dispatch_internal_repo_workflow.sh b/.github/scripts/dispatch_internal_repo_workflow.sh index 042d440b..a52c1bbe 100755 --- a/.github/scripts/dispatch_internal_repo_workflow.sh +++ b/.github/scripts/dispatch_internal_repo_workflow.sh @@ -11,19 +11,26 @@ # --targetComponent \ # --targetAccountGroup \ # --terraformAction \ -# --internalRef +# --internalRef \ +# --overrides \ +# --overrideProjectName \ +# --overrideRoleName + # # All arguments are required except terraformAction, and internalRef. # Example: # ./dispatch_internal_repo_workflow.sh \ -# --infraRepoName "nhs-notify-iam-webauth" \ +# --infraRepoName "nhs-notify-dns" \ # --releaseVersion "v1.2.3" \ # --targetWorkflow "deploy.yaml" \ # --targetEnvironment "prod" \ # --targetComponent "web" \ # --targetAccountGroup "core" \ # --terraformAction "apply" \ -# --internalRef "main" +# --internalRef "main" \ +# --overrides "tf_var=someString" \ +# --overrideProjectName nhs \ +# --overrideRoleName nhs-service-iam-role set -e @@ -65,6 +72,14 @@ while [[ $# -gt 0 ]]; do overrides="$2" shift 2 ;; + --overrideProjectName) # Override the project name (optional) + overrideProjectName="$2" + shift 2 + ;; + --overrideRoleName) # Override the role name (optional) + overrideRoleName="$2" + shift 2 + ;; *) echo "[ERROR] Unknown argument: $1" exit 1 @@ -149,6 +164,9 @@ echo " targetAccountGroup: $targetAccountGroup" echo " terraformAction: $terraformAction" echo " internalRef: $internalRef" echo " overrides: $overrides" +echo " overrideProjectName: $overrideProjectName" +echo " overrideRoleName: $overrideRoleName" +echo " targetProject: $targetProject" DISPATCH_EVENT=$(jq -ncM \ --arg infraRepoName "$infraRepoName" \ @@ -159,11 +177,17 @@ DISPATCH_EVENT=$(jq -ncM \ --arg terraformAction "$terraformAction" \ --arg targetWorkflow "$targetWorkflow" \ --arg overrides "$overrides" \ + --arg overrideProjectName "$overrideProjectName" \ + --arg overrideRoleName "$overrideRoleName" \ + --arg targetProject "$targetProject" \ '{ "ref": "'"$internalRef"'", "inputs": ( (if $infraRepoName != "" then { "infraRepoName": $infraRepoName } else {} end) + (if $terraformAction != "" then { "terraformAction": $terraformAction } else {} end) + + (if $overrideProjectName != "" then { "overrideProjectName": $overrideProjectName } else {} end) + + (if $overrideRoleName != "" then { "overrideRoleName": $overrideRoleName } else {} end) + + (if $targetProject != "" then { "targetProject": $targetProject } else {} end) + { "releaseVersion": $releaseVersion, "targetEnvironment": $targetEnvironment, @@ -176,7 +200,6 @@ DISPATCH_EVENT=$(jq -ncM \ echo "[INFO] Triggering workflow '$targetWorkflow' in nhs-notify-internal..." -set -x trigger_response=$(curl -s -L \ --fail \ -X POST \ @@ -185,7 +208,6 @@ trigger_response=$(curl -s -L \ -H "X-GitHub-Api-Version: 2022-11-28" \ "https://api.github.com/repos/NHSDigital/nhs-notify-internal/actions/workflows/$targetWorkflow/dispatches" \ -d "$DISPATCH_EVENT" 2>&1) -set +x if [[ $? -ne 0 ]]; then echo "[ERROR] Failed to trigger workflow. Response: $trigger_response" @@ -200,6 +222,7 @@ sleep 10 # Wait a few seconds before checking for the presence of the api to acc workflow_run_url="" for _ in {1..18}; do + response=$(curl -s -L \ -H "Accept: application/vnd.github+json" \ -H "Authorization: Bearer ${PR_TRIGGER_PAT}" \ diff --git a/scripts/config/pre-commit.yaml b/scripts/config/pre-commit.yaml index 9d30700a..9c5e690a 100644 --- a/scripts/config/pre-commit.yaml +++ b/scripts/config/pre-commit.yaml @@ -3,32 +3,17 @@ repos: rev: v5.0.0 # Use the ref you want to point at hooks: - id: trailing-whitespace - exclude: | - (?x)^( - frontend/src/__tests__/.*\.tsx\.snap | - frontend/.*\.min\..* - )$ - id: detect-aws-credentials args: [--allow-missing-credentials] - id: check-added-large-files - id: check-symlinks - id: detect-private-key - id: end-of-file-fixer - exclude: | - (?x)^( - frontend/src/__tests__/.*\.tsx\.snap | - frontend/.*\.min\..* | - .*\.bin - )$ - id: forbid-new-submodules - id: mixed-line-ending - id: pretty-format-json args: ['--autofix'] - exclude: | - (?x)^( - .*/?package-lock.json | - lambdas/jwks-key-rotation/src/__tests__/utils/test-public-key.jwks.json - )$ + exclude: '(^|/)package(-lock)?\.json$' # - id: ... - repo: local hooks: diff --git a/scripts/config/trivy.yaml b/scripts/config/trivy.yaml index a4eff466..29707dbb 100644 --- a/scripts/config/trivy.yaml +++ b/scripts/config/trivy.yaml @@ -4,3 +4,4 @@ exit-code: 1 # When issues are found scan: skip-files: - "**/.terraform/**/*" + - "**/node_modules/**/*" diff --git a/scripts/githooks/check-file-format.sh b/scripts/githooks/check-file-format.sh index 632e536b..b1e02efb 100755 --- a/scripts/githooks/check-file-format.sh +++ b/scripts/githooks/check-file-format.sh @@ -67,10 +67,8 @@ function main() { esac if command -v editorconfig-checker > /dev/null 2>&1 && ! is-arg-true "${FORCE_USE_DOCKER:-false}"; then - echo "Running editorconfig-checker natively" filter="$filter" dry_run_opt="${dry_run_opt:-}" run-editorconfig-natively else - echo "Running editorconfig-checker in Docker" filter="$filter" dry_run_opt="${dry_run_opt:-}" run-editorconfig-in-docker fi } @@ -103,7 +101,7 @@ function run-editorconfig-in-docker() { docker run --rm --platform linux/amd64 \ --volume "$PWD":/check \ "$image" \ - sh -c "set -x; ec --exclude '.git/' $dry_run_opt \$($filter) /dev/null" + sh -c "ec --exclude '.git/' $dry_run_opt \$($filter) /dev/null" } # ============================================================================== diff --git a/scripts/githooks/check-todos.sh b/scripts/githooks/check-todos.sh index 4135cb2a..83b7a80e 100755 --- a/scripts/githooks/check-todos.sh +++ b/scripts/githooks/check-todos.sh @@ -120,7 +120,7 @@ function search_todos() { # If the file is excluded, skip it if [ "$skip" = false ] && [ -f "$file" ]; then - file_todos=$(grep -nHiE '\bTODO(:| )' "$file" || true) + file_todos=$(grep -nHiE '\bTODO\b' "$file" || true) [ -n "$file_todos" ] && todos+="$file_todos\n" fi done @@ -136,7 +136,7 @@ function filter_todos_with_valid_jira_ticket() { while IFS= read -r line; do # Only lines with TODO but without a valid JIRA ticket - if grep -qnHiE '\bTODO(:| )' <<< "$line"; then + if grep -qnHiE '\bTODO\b' <<< "$line"; then if ! [[ "$line" =~ $jira_regex ]]; then todos_without_ticket+="$line\n" fi diff --git a/scripts/init.mk b/scripts/init.mk index 416ff5e0..885d2d33 100644 --- a/scripts/init.mk +++ b/scripts/init.mk @@ -46,7 +46,7 @@ _install-dependency: # Install asdf dependency - mandatory: name=[listed in the asdf install ${name} $(or ${version},) _install-dependencies: # Install all the dependencies listed in .tool-versions - for plugin in $$(grep '^[a-z]' .tool-versions | cut -f1 -d' '); do \ + for plugin in $$(grep ^[a-z] .tool-versions | sed 's/[[:space:]].*//'); do $(MAKE) _install-dependency name=$${plugin}; \ done diff --git a/scripts/lambda-container-build/docker.sh b/scripts/lambda-container-build/docker.sh new file mode 100755 index 00000000..b86a8749 --- /dev/null +++ b/scripts/lambda-container-build/docker.sh @@ -0,0 +1,129 @@ +#!/bin/bash + +# Fail fast on errors, unset variables, and pipeline failures. +set -euo pipefail + +# Ensure build.sh is executable and build the lambda artifacts before producing the Docker image. +chmod +x ./build.sh +./build.sh + + +# Parse arguments +BASE_IMAGE="" +while [[ $# -gt 0 ]]; do + case $1 in + --base-image) + BASE_IMAGE="$2" + shift 2 + ;; + *) + echo "Unknown argument: $1" >&2 + exit 1 + ;; + esac +done + +if [[ -z "$BASE_IMAGE" ]]; then + echo "Error: --base-image parameter is required." >&2 + exit 1 +fi + +CSI="${PROJECT}-${ENVIRONMENT}-${COMPONENT}" +ECR_REPO="${ECR_REPO:-nhs-notify-main-acct}" +GHCR_LOGIN_TOKEN="${GITHUB_TOKEN}" +GHCR_LOGIN_USER="${GITHUB_ACTOR}" +LAMBDA_NAME="${LAMBDA_NAME:-$(basename "$PWD")}" + +## Set IMAGE_TAG_SUFFIX based on git tag or short SHA for unique lambda image tagging in ECR. +#This ensures that each build produces a uniquely identifiable image, and tagged releases are easily traceable. +echo "Checking if current commit is a tag..." +GIT_TAG="$(git describe --tags --exact-match 2>/dev/null || true)" +if [ -n "$GIT_TAG" ]; then + TAGGED="tag-$GIT_TAG" + echo "On tag: $GIT_TAG, exporting IMAGE_TAG_SUFFIX as tag: $TAGGED" + export IMAGE_TAG_SUFFIX="$TAGGED" + +else + SHORT_SHA="sha-$(git rev-parse --short HEAD)" + echo "Not on a tag, exporting IMAGE_TAG_SUFFIX as short SHA: $SHORT_SHA" + export IMAGE_TAG_SUFFIX="$SHORT_SHA" +fi + +## Check if we are running in the context of a Terraform apply or plan, and set PUBLISH_LAMBDA_IMAGE accordingly. We only want to push images to ECR on apply, not on plan. +echo "Checking if ACTION is 'apply' to set PUBLISH_LAMBDA_IMAGE..." +if [ "$ACTION" = "apply" ]; then + echo "Setting PUBLISH_LAMBDA_IMAGE to true for apply action" + export PUBLISH_LAMBDA_IMAGE="true" +else + echo "Not setting PUBLISH_LAMBDA_IMAGE for action ($ACTION)" +fi + +# Ensure required AWS/ECR configuration is present. +echo "BASE_IMAGE: ${BASE_IMAGE:-}" +echo "AWS_ACCOUNT_ID: ${AWS_ACCOUNT_ID:-}" +echo "AWS_REGION: ${AWS_REGION:-}" +echo "COMPONENT: ${COMPONENT:-}" +echo "CSI: ${CSI:-}" +echo "ECR_REPO: ${ECR_REPO:-}" +echo "ENVIRONMENT: ${ENVIRONMENT:-}" +echo "GHCR_LOGIN_TOKEN: ${GHCR_LOGIN_TOKEN:-}" +echo "GHCR_LOGIN_USER: ${GHCR_LOGIN_USER:-}" +echo "IMAGE_TAG_SUFFIX: ${IMAGE_TAG_SUFFIX:-}" +echo "LAMBDA_NAME: ${LAMBDA_NAME:-}" + +# Authenticate Docker with AWS ECR using an ephemeral login token. +aws ecr get-login-password --region "${AWS_REGION}" | docker login --username AWS --password-stdin "${AWS_ACCOUNT_ID}".dkr.ecr."${AWS_REGION}".amazonaws.com + +# Authenticate to GitHub Container Registry for base images. +if [ -n "${GHCR_LOGIN_USER:-}" ] && [ -n "${GHCR_LOGIN_TOKEN:-}" ]; then + echo "Attempting GHCR login as ${GHCR_LOGIN_USER}..." + if echo "${GHCR_LOGIN_TOKEN}" | docker login ghcr.io --username "${GHCR_LOGIN_USER}" --password-stdin; then + echo "GHCR login successful." + else + echo "GHCR login failed!" >&2 + fi +fi + +# Namespace tag by CSI and lambda name to avoid cross-environment collisions. +IMAGE_TAG="${CSI}-${LAMBDA_NAME}" + +# Compose the full ECR image references. +ECR_REPO_URI="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPO}" + +# Final tag names we will produce + +IMAGE_TAG_LATEST="${ECR_REPO_URI}:${IMAGE_TAG}-latest" +IMAGE_TAG_SUFFIXED="${ECR_REPO_URI}:${IMAGE_TAG}-${IMAGE_TAG_SUFFIX}" + +echo "Will build and tag images:" +echo " LATEST -> ${IMAGE_TAG_LATEST}" +echo " SUFFIXED -> ${IMAGE_TAG_SUFFIXED}" + +# Build and tag the Docker image for the lambda. +# --load makes the built image available to the local docker daemon (single-platform). +docker buildx build \ + -f docker/lambda/Dockerfile \ + --platform=linux/amd64 \ + --provenance=false \ + --sbom=false \ + --build-arg BASE_IMAGE="${BASE_IMAGE}" \ + -t "${IMAGE_TAG_LATEST}" \ + -t "${IMAGE_TAG_SUFFIXED}" \ + --load \ + . + +# Push the image tag(s) to ECR on apply only. The Terraform configuration will reference image digest. +if [ "${PUBLISH_LAMBDA_IMAGE:-false}" = "true" ]; then + echo "PUBLISH_LAMBDA_IMAGE is set to true. Pushing Docker images to ECR..." + + + for TAG in "${IMAGE_TAG_LATEST}" "${IMAGE_TAG_SUFFIXED}"; do + echo "Pushing ${TAG}..." + docker push "${TAG}" + done + + echo "Push complete." +else + echo "PUBLISH_LAMBDA_IMAGE is not set to true (likely TF Plan). Skipping Docker push." + exit 0 +fi