From f19fc9c68bbeba2e12c71f6d133ccff3cdaef035 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 09:36:46 +0000 Subject: [PATCH 01/62] build dev container --- .github/workflows/quality-checks.yml | 31 +++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index d4d958d..f157940 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -20,7 +20,10 @@ on: type: boolean description: Toggle to reinstall poetry on top of python version installed by asdf. default: false - + asdfVersion: + type: string + required: false + default: "v0.18.0" jobs: quality_checks: runs-on: ubuntu-22.04 @@ -71,23 +74,23 @@ jobs: # using git commit sha for version of action to ensure we have stable version - name: Install asdf - uses: asdf-vm/actions/setup@05e0d2ed97b598bfce82fd30daf324ae0c4570e6 + uses: asdf-vm/actions/setup@1902764435ca0dd2f3388eea723a4f92a4eb8302 with: - asdf_branch: v0.14.1 + asdf_version: ${{ inputs.asdfVersion }} - name: Cache asdf uses: actions/cache@v4 with: path: | ~/.asdf - key: ${{ runner.os }}-asdf-${{ hashFiles('**/.tool-versions') }} + key: ${{ runner.os }}-asdf-${{ hashFiles('**/.tool-versions') }}-${{ inputs.asdfVersion }} restore-keys: | - ${{ runner.os }}-asdf- + ${{ runner.os }}-asdf-${{ hashFiles('**/.tool-versions') }}-${{ inputs.asdfVersion }} - name: Install asdf dependencies in .tool-versions - uses: asdf-vm/actions/install@05e0d2ed97b598bfce82fd30daf324ae0c4570e6 + uses: asdf-vm/actions/install@1902764435ca0dd2f3388eea723a4f92a4eb8302 with: - asdf_branch: v0.14.1 + asdf_version: ${{ inputs.asdfVersion }} env: PYTHON_CONFIGURE_OPTS: --enable-shared @@ -354,3 +357,17 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + + build_dev_container: + runs-on: ubuntu-22.04 + steps: + - name: Checkout code + uses: actions/checkout@v5 + with: + ref: ${{ env.BRANCH_NAME }} + fetch-depth: 0 + + - name: Build dev container + run: | + docker buildx create --use + docker buildx build --platform linux/amd64,linux/arm64 -f .devcontainer/Dockerfile -t dev-container-image . \ No newline at end of file From 566635362f771c4123d39a4f77b8016084f7fc6a Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 12:31:55 +0000 Subject: [PATCH 02/62] build the dev container --- .github/workflows/quality-checks.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 141adc3..86402a3 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -23,10 +23,6 @@ on: type: boolean description: Toggle to reinstall poetry on top of python version installed by asdf. default: false - asdfVersion: - type: string - required: false - default: "v0.18.0" jobs: quality_checks: runs-on: ubuntu-22.04 @@ -373,4 +369,4 @@ jobs: - name: Build dev container run: | docker buildx create --use - docker buildx build --platform linux/amd64,linux/arm64 -f .devcontainer/Dockerfile -t dev-container-image . \ No newline at end of file + docker buildx build --platform linux/amd64,linux/arm64 -f .devcontainer/Dockerfile -t dev-container-image . From 9dcc3f26ac8a1d3c7c2ea96697bc50346109b8c7 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 12:55:07 +0000 Subject: [PATCH 03/62] build macos on seperate image --- .../scripts/check_ecr_image_scan_results.sh | 138 ++++++++++++++++++ .github/workflows/quality-checks.yml | 89 ++++++++++- 2 files changed, 224 insertions(+), 3 deletions(-) create mode 100755 .github/scripts/check_ecr_image_scan_results.sh diff --git a/.github/scripts/check_ecr_image_scan_results.sh b/.github/scripts/check_ecr_image_scan_results.sh new file mode 100755 index 0000000..4a5222e --- /dev/null +++ b/.github/scripts/check_ecr_image_scan_results.sh @@ -0,0 +1,138 @@ +#!/usr/bin/env bash +set -e + +AWS_MAX_ATTEMPTS=20 +export AWS_MAX_ATTEMPTS + +if [ -z "${REPOSITORY_NAME}" ]; then + echo "REPOSITORY_NAME not set" + exit 1 +fi + +if [ -z "${IMAGE_TAG}" ]; then + echo "IMAGE_TAG not set" + exit 1 +fi + +if [ -z "${AWS_REGION}" ]; then + echo "AWS_REGION not set" + exit 1 +fi + +if [ -z "${ACCOUNT_ID}" ]; then + echo "AWS_REGION not set" + exit 1 +fi + +IMAGE_DIGEST=$(aws ecr describe-images \ + --repository-name "$REPOSITORY_NAME" \ + --image-ids imageTag="$IMAGE_TAG" \ + --query 'imageDetails[0].imageDigest' \ + --output text) + +RESOURCE_ARN="arn:aws:ecr:${AWS_REGION}:${ACCOUNT_ID}:repository/${REPOSITORY_NAME}/${IMAGE_DIGEST}" + +echo "Monitoring scan for ${REPOSITORY_NAME}:${IMAGE_TAG}" +echo "Resource ARN: ${RESOURCE_ARN}" +echo + +# Wait for ECR scan to reach COMPLETE +STATUS="" +echo "Waiting for ECR scan to complete..." +for i in {1..30}; do + echo "Checking scan status. Attempt ${i}" + STATUS=$(aws ecr describe-image-scan-findings \ + --repository-name "$REPOSITORY_NAME" \ + --image-id imageDigest="$IMAGE_DIGEST" \ + --query 'imageScanStatus.status' \ + --output text 2>/dev/null || echo "NONE") + + if [[ "$STATUS" == "COMPLETE" ]]; then + echo "ECR scan completed." + break + fi + + if [[ "$STATUS" == "FAILED" ]]; then + echo "Scan failed." + exit 1 + fi + + echo "SCAN IS NOT YET COMPLETE. Waiting 10 seconds before checking again..." + sleep 10 +done + +if [[ "$STATUS" != "COMPLETE" ]]; then + echo "Timeout waiting for ECR scan to complete." + exit 1 +fi + +# Wait for Inspector2 findings to appear & stabilize +# this is in place as scan may show as complete but findings have not yet stabilize +echo +echo "Waiting for Inspector2 findings to stabilize..." + +PREV_HASH="" +for i in {1..12}; do # ~2 minutes max + FINDINGS=$(aws inspector2 list-findings \ + --filter-criteria "{ + \"resourceId\": [{\"comparison\": \"EQUALS\", \"value\": \"${RESOURCE_ARN}\"}], + \"findingStatus\": [{\"comparison\": \"EQUALS\", \"value\": \"ACTIVE\"}] + }" \ + --output json 2>/dev/null || echo "{}") + + CURR_HASH=$(echo "$FINDINGS" | sha256sum) + COUNT=$(echo "$FINDINGS" | jq '.findings | length') + + if [[ "$COUNT" -gt 0 && "$CURR_HASH" == "$PREV_HASH" ]]; then + echo "Findings stabilized ($COUNT findings)." + break + fi + + PREV_HASH="$CURR_HASH" + echo "Attempt: ${i}. Still waiting... (${COUNT} findings so far)" + sleep 10 +done + +# Extract counts and display findings +echo +echo "Final Inspector2 findings with suppressions removed:" +echo + +echo "$FINDINGS" | jq '{ + findings: [ + .findings[]? | { + severity: .severity, + title: .title, + package: .packageVulnerabilityDetails.vulnerablePackages[0].name, + sourceUrl: .packageVulnerabilityDetails.sourceUrl, + recommendation: (.remediation.recommendation.text // "N/A") + } + ] +}' + +echo + +# Check for critical/high severity +CRITICAL_COUNT=$(echo "$FINDINGS" | jq '[.findings[]? | select(.severity=="CRITICAL")] | length') +HIGH_COUNT=$(echo "$FINDINGS" | jq '[.findings[]? | select(.severity=="HIGH")] | length') + +if (( CRITICAL_COUNT > 0 || HIGH_COUNT > 0 )); then + echo "${CRITICAL_COUNT} CRITICAL and ${HIGH_COUNT} HIGH vulnerabilities detected!" + echo + echo "Critical/High vulnerabilities:" + echo "$FINDINGS" | jq -r ' + .findings[]? | + select(.severity=="CRITICAL" or .severity=="HIGH") |{ + severity: .severity, + title: .title, + package: .packageVulnerabilityDetails.vulnerablePackages[0].name, + sourceUrl: .packageVulnerabilityDetails.sourceUrl, + recommendation: (.remediation.recommendation.text // "N/A") + }' + echo + echo "Failing pipeline due to Critical/High vulnerabilities." + exit 2 +else + echo "No Critical or High vulnerabilities found." + exit 0 +fi diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 86402a3..d165954 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -5,6 +5,8 @@ on: secrets: SONAR_TOKEN: required: false + CLOUD_FORMATION_DEPLOY_ROLE: + required: false inputs: install_java: type: boolean @@ -23,6 +25,14 @@ on: type: boolean description: Toggle to reinstall poetry on top of python version installed by asdf. default: false + dev_container_ecr: + type: string + description: "The name of the ECR repository to push the dev container image to." + required: false + dev_container_image_tag: + type: string + description: "The tag to use for the dev container image." + required: false jobs: quality_checks: runs-on: ubuntu-22.04 @@ -357,7 +367,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - build_dev_container: + build_dev_container_x64: runs-on: ubuntu-22.04 steps: - name: Checkout code @@ -368,5 +378,78 @@ jobs: - name: Build dev container run: | - docker buildx create --use - docker buildx build --platform linux/amd64,linux/arm64 -f .devcontainer/Dockerfile -t dev-container-image . + docker build -f .devcontainer/Dockerfile -t dev-container-image . + # - name: Configure AWS Credentials + # uses: aws-actions/configure-aws-credentials@v5 + # id: connect-aws-deploy + # with: + # aws-region: eu-west-2 + # role-to-assume: ${{ secrets.CLOUD_FORMATION_DEPLOY_ROLE }} + # role-session-name: dev-container-build + # output-credentials: true + + # - name: Retrieve AWS Account ID + # id: retrieve-deploy-account-id + # run: echo "ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)" >> "$GITHUB_ENV" + + # - name: Login to Amazon ECR + # id: login-ecr-push-image + # run: | + # aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ env.ACCOUNT_ID }}.dkr.ecr.eu-west-2.amazonaws.com + + # - name: Push FHIR Facade image to Amazon ECR + # run: | + # docker tag "dev-container-image" "${{ env.ACCOUNT_ID }}.dkr.ecr.eu-west-2.amazonaws.com/${{inputs.DEV_CONTAINER_ECR}}:${{ inputs.DEV_CONTAINER_IMAGE_TAG }}" + # docker push "${{ env.ACCOUNT_ID }}.dkr.ecr.eu-west-2.amazonaws.com/${{inputs.DEV_CONTAINER_ECR}}:${{ inputs.DEV_CONTAINER_IMAGE_TAG }}" + + # - name: Check dev container scan results + # env: + # REPOSITORY_NAME: ${{inputs.DEV_CONTAINER_ECR}} + # IMAGE_TAG: ${{ inputs.DEV_CONTAINER_IMAGE_TAG }} + # working-directory: .github/scripts + # run: | + # ./check_ecr_image_scan_results.sh + + build_dev_container_arm64: + runs-on: macos-latest + steps: + - name: Checkout code + uses: actions/checkout@v5 + with: + ref: ${{ env.BRANCH_NAME }} + fetch-depth: 0 + + - name: Build dev container + run: | + docker build -f .devcontainer/Dockerfile -t dev-container-image . + + # - name: Configure AWS Credentials + # uses: aws-actions/configure-aws-credentials@v5 + # id: connect-aws-deploy + # with: + # aws-region: eu-west-2 + # role-to-assume: ${{ secrets.CLOUD_FORMATION_DEPLOY_ROLE }} + # role-session-name: dev-container-build + # output-credentials: true + + # - name: Retrieve AWS Account ID + # id: retrieve-deploy-account-id + # run: echo "ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)" >> "$GITHUB_ENV" + + # - name: Login to Amazon ECR + # id: login-ecr-push-image + # run: | + # aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ env.ACCOUNT_ID }}.dkr.ecr.eu-west-2.amazonaws.com + + # - name: Push FHIR Facade image to Amazon ECR + # run: | + # docker tag "dev-container-image" "${{ env.ACCOUNT_ID }}.dkr.ecr.eu-west-2.amazonaws.com/${{inputs.DEV_CONTAINER_ECR}}:${{ inputs.DEV_CONTAINER_IMAGE_TAG }}" + # docker push "${{ env.ACCOUNT_ID }}.dkr.ecr.eu-west-2.amazonaws.com/${{inputs.DEV_CONTAINER_ECR}}:${{ inputs.DEV_CONTAINER_IMAGE_TAG }}" + + # - name: Check dev container scan results + # env: + # REPOSITORY_NAME: ${{inputs.DEV_CONTAINER_ECR}} + # IMAGE_TAG: ${{ inputs.DEV_CONTAINER_IMAGE_TAG }} + # working-directory: .github/scripts + # run: | + # ./check_ecr_image_scan_results.sh From 3872a506414a1146d61d56531ea313e2e1b834f9 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 12:58:24 +0000 Subject: [PATCH 04/62] install docker on macos --- .github/workflows/quality-checks.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index d165954..da56f0c 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -419,6 +419,18 @@ jobs: ref: ${{ env.BRANCH_NAME }} fetch-depth: 0 + - name: Install Docker Desktop + run: | + brew install --cask docker + sudo /Applications/Docker.app/Contents/MacOS/Docker --unattended --install-privileged-components + open -a Docker + # Wait for Docker to start + while ! docker system info > /dev/null 2>&1; do + echo "Waiting for Docker to start..." + sleep 5 + done + echo "Docker is ready!" + - name: Build dev container run: | docker build -f .devcontainer/Dockerfile -t dev-container-image . From 34a511a9d888ceca7e7f861e922d16548a33ea15 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 13:03:15 +0000 Subject: [PATCH 05/62] try colima --- .github/workflows/quality-checks.yml | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index da56f0c..4365da1 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -419,17 +419,10 @@ jobs: ref: ${{ env.BRANCH_NAME }} fetch-depth: 0 - - name: Install Docker Desktop + - name: Install Docker with Colima run: | - brew install --cask docker - sudo /Applications/Docker.app/Contents/MacOS/Docker --unattended --install-privileged-components - open -a Docker - # Wait for Docker to start - while ! docker system info > /dev/null 2>&1; do - echo "Waiting for Docker to start..." - sleep 5 - done - echo "Docker is ready!" + brew install docker colima + colima start - name: Build dev container run: | From 1b19e0054067f06cbec2d0cecdda25cd3c0f6d33 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 13:06:07 +0000 Subject: [PATCH 06/62] try lima --- .github/workflows/quality-checks.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 4365da1..71a22ae 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -419,10 +419,12 @@ jobs: ref: ${{ env.BRANCH_NAME }} fetch-depth: 0 - - name: Install Docker with Colima + - name: Install Docker with Lima run: | - brew install docker colima - colima start + brew install docker lima + limactl start template://docker + DOCKER_HOST=$(limactl list docker --format 'unix://{{.Dir}}/sock/docker.sock') + export DOCKER_HOST - name: Build dev container run: | From cbea80e420664b36d7d235e731161a9ed66540c1 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 13:17:44 +0000 Subject: [PATCH 07/62] build on ubuntu --- .github/workflows/quality-checks.yml | 9 +-------- .tool-versions | 2 +- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 71a22ae..5071387 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -411,7 +411,7 @@ jobs: # ./check_ecr_image_scan_results.sh build_dev_container_arm64: - runs-on: macos-latest + runs-on: ubuntu-22.04-arm steps: - name: Checkout code uses: actions/checkout@v5 @@ -419,13 +419,6 @@ jobs: ref: ${{ env.BRANCH_NAME }} fetch-depth: 0 - - name: Install Docker with Lima - run: | - brew install docker lima - limactl start template://docker - DOCKER_HOST=$(limactl list docker --format 'unix://{{.Dir}}/sock/docker.sock') - export DOCKER_HOST - - name: Build dev container run: | docker build -f .devcontainer/Dockerfile -t dev-container-image . diff --git a/.tool-versions b/.tool-versions index b7e181d..df26591 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,5 +1,5 @@ nodejs 20.18.0 -actionlint 1.6.26 +actionlint 1.7.8 shellcheck 0.11.0 python 3.14.0 poetry 2.2.1 From be5997341907f9d5798a02626a5e6a17adefcca5 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 13:22:42 +0000 Subject: [PATCH 08/62] upload image --- .github/workflows/quality-checks.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 5071387..6a056eb 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -421,8 +421,13 @@ jobs: - name: Build dev container run: | - docker build -f .devcontainer/Dockerfile -t dev-container-image . - + docker build -f .devcontainer/Dockerfile -t dev-container-image-arm . + docker save "dev-container-image-arm" -o dev-container-image-arm.img + - uses: actions/upload-artifact@v4 + name: upload build artifact + with: + name: dev-container-image-arm + path: dev-container-image-arm.img # - name: Configure AWS Credentials # uses: aws-actions/configure-aws-credentials@v5 # id: connect-aws-deploy From accee98a527c995d43fd1c8610afef98eec1c160 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 13:26:09 +0000 Subject: [PATCH 09/62] correct dev container --- .devcontainer/Dockerfile | 45 +++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 83858e4..da01e8d 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,5 +1,12 @@ FROM mcr.microsoft.com/devcontainers/base:ubuntu + +ARG TARGETARCH +ENV TARGETARCH=${TARGETARCH} + +ARG ASDF_VERSION +COPY .tool-versions.asdf /tmp/.tool-versions.asdf + RUN apt-get update \ && export DEBIAN_FRONTEND=noninteractive \ && apt-get -y dist-upgrade \ @@ -11,14 +18,39 @@ RUN apt-get update \ libreadline-dev libsqlite3-dev wget llvm libncurses5-dev libncursesw5-dev \ xz-utils tk-dev liblzma-dev netcat-traditional libyaml-dev -USER vscode +# Download correct AWS CLI for arch +RUN if [ "$TARGETARCH" = "arm64" ] || [ "$TARGETARCH" == "aarch64" ]; then \ + wget -O /tmp/awscliv2.zip "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip"; \ + else \ + wget -O /tmp/awscliv2.zip "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip"; \ + fi && \ + unzip /tmp/awscliv2.zip -d /tmp/aws-cli && \ + /tmp/aws-cli/aws/install && \ + rm /tmp/awscliv2.zip && rm -rf /tmp/aws-cli + +# Download correct SAM CLI for arch +RUN if [ "$TARGETARCH" = "arm64" ] || [ "$TARGETARCH" == "aarch64" ]; then \ + wget -O /tmp/aws-sam-cli.zip "https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-arm64.zip"; \ + else \ + wget -O /tmp/aws-sam-cli.zip "https://github.com/aws/aws-sam-cli/releases/latest/download/aws-sam-cli-linux-x86_64.zip"; \ + fi && \ + unzip /tmp/aws-sam-cli.zip -d /tmp/aws-sam-cli && \ + /tmp/aws-sam-cli/install && \ + rm /tmp/aws-sam-cli.zip && rm -rf /tmp/aws-sam-cli # Install ASDF -RUN git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.11.3; \ - echo '. $HOME/.asdf/asdf.sh' >> ~/.bashrc; \ - echo '. $HOME/.asdf/completions/asdf.bash' >> ~/.bashrc; +RUN ASDF_VERSION=$(awk '!/^#/ && NF {print $1; exit}' /tmp/.tool-versions.asdf) && \ + if [ "$TARGETARCH" = "arm64" ] || [ "$TARGETARCH" = "aarch64" ]; then \ + wget -O /tmp/asdf.tar.gz https://github.com/asdf-vm/asdf/releases/download/v${ASDF_VERSION}/asdf-v${ASDF_VERSION}-linux-arm64.tar.gz; \ + else \ + wget -O /tmp/asdf.tar.gz https://github.com/asdf-vm/asdf/releases/download/v${ASDF_VERSION}/asdf-v${ASDF_VERSION}-linux-amd64.tar.gz; \ + fi && \ + tar -xvzf /tmp/asdf.tar.gz && \ + mv asdf /usr/bin + +USER vscode -ENV PATH="$PATH:/home/vscode/.asdf/bin/:/workspaces/eps-prescription-tracker-ui/node_modules/.bin:/workspaces/eps-workflow-quality-checks/.venv/bin" +ENV PATH="$PATH:/home/vscode/.asdf/shims/:/workspaces/eps-prescription-tracker-ui/node_modules/.bin:/workspaces/eps-workflow-quality-checks/.venv/bin" # Install ASDF plugins# RUN asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs.git; \ @@ -33,5 +65,4 @@ ADD .tool-versions /workspaces/eps-workflow-quality-checks/.tool-versions ADD .tool-versions /home/vscode/.tool-versions RUN asdf install python; \ - asdf install; \ - asdf reshim nodejs; + asdf install; From 61fa254c01ca7f050da195d79438ad68d56edcd8 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 13:47:07 +0000 Subject: [PATCH 10/62] try cross compile again --- .github/workflows/quality-checks.yml | 43 ++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 6a056eb..2e57462 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -367,6 +367,49 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + build_dev_container_cross_compile: + runs-on: ubuntu-22.04 + steps: + - name: Checkout code + uses: actions/checkout@v5 + with: + ref: ${{ env.BRANCH_NAME }} + fetch-depth: 0 + + - name: Build dev container + run: | + docker buildx create --use + docker buildx build --platform linux/amd64,linux/arm64 -f .devcontainer/Dockerfile -t dev-container-image . + # - name: Configure AWS Credentials + # uses: aws-actions/configure-aws-credentials@v5 + # id: connect-aws-deploy + # with: + # aws-region: eu-west-2 + # role-to-assume: ${{ secrets.CLOUD_FORMATION_DEPLOY_ROLE }} + # role-session-name: dev-container-build + # output-credentials: true + + # - name: Retrieve AWS Account ID + # id: retrieve-deploy-account-id + # run: echo "ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)" >> "$GITHUB_ENV" + + # - name: Login to Amazon ECR + # id: login-ecr-push-image + # run: | + # aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ env.ACCOUNT_ID }}.dkr.ecr.eu-west-2.amazonaws.com + + # - name: Push FHIR Facade image to Amazon ECR + # run: | + # docker tag "dev-container-image" "${{ env.ACCOUNT_ID }}.dkr.ecr.eu-west-2.amazonaws.com/${{inputs.DEV_CONTAINER_ECR}}:${{ inputs.DEV_CONTAINER_IMAGE_TAG }}" + # docker push "${{ env.ACCOUNT_ID }}.dkr.ecr.eu-west-2.amazonaws.com/${{inputs.DEV_CONTAINER_ECR}}:${{ inputs.DEV_CONTAINER_IMAGE_TAG }}" + + # - name: Check dev container scan results + # env: + # REPOSITORY_NAME: ${{inputs.DEV_CONTAINER_ECR}} + # IMAGE_TAG: ${{ inputs.DEV_CONTAINER_IMAGE_TAG }} + # working-directory: .github/scripts + # run: | + # ./check_ecr_image_scan_results.sh build_dev_container_x64: runs-on: ubuntu-22.04 steps: From 8d18a9d4170747ac5cb0663ac8e460a6f6ddcd69 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 14:05:44 +0000 Subject: [PATCH 11/62] try pushing image --- .github/workflows/pull_request.yml | 3 + .github/workflows/quality-checks.yml | 211 +++++++++++++-------------- MULTI_ARCH_DOCKER.md | 123 ++++++++++++++++ 3 files changed, 227 insertions(+), 110 deletions(-) create mode 100644 MULTI_ARCH_DOCKER.md diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 8d84b6a..f29800b 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -32,8 +32,11 @@ jobs: needs: [get_asdf_version] with: asdfVersion: ${{ needs.get_asdf_version.outputs.asdf_version }} + dev_container_ecr: dev-container-quality-checks + dev_container_image_tag: latest secrets: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + CLOUD_FORMATION_DEPLOY_ROLE: ${{ secrets.CLOUD_FORMATION_DEPLOY_ROLE }} tag_release: needs: [quality_checks, get_asdf_version] uses: NHSDigital/eps-workflow-semantic-release/.github/workflows/tag-release.yml@f80157cecce288dd175e61b477a1d2dbe9c88b99 diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 2e57462..cea378f 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -46,7 +46,6 @@ jobs: - name: Checkout code uses: actions/checkout@v5 with: - ref: ${{ env.BRANCH_NAME }} fetch-depth: 0 # Must be done before anything installs, or it will check dependencies for secrets too. @@ -367,137 +366,129 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - build_dev_container_cross_compile: + build_dev_container_x64: runs-on: ubuntu-22.04 + if: ${{ inputs.dev_container_ecr != '' && inputs.dev_container_image_tag != '' }} steps: - name: Checkout code uses: actions/checkout@v5 with: - ref: ${{ env.BRANCH_NAME }} fetch-depth: 0 - name: Build dev container run: | - docker buildx create --use - docker buildx build --platform linux/amd64,linux/arm64 -f .devcontainer/Dockerfile -t dev-container-image . - # - name: Configure AWS Credentials - # uses: aws-actions/configure-aws-credentials@v5 - # id: connect-aws-deploy - # with: - # aws-region: eu-west-2 - # role-to-assume: ${{ secrets.CLOUD_FORMATION_DEPLOY_ROLE }} - # role-session-name: dev-container-build - # output-credentials: true - - # - name: Retrieve AWS Account ID - # id: retrieve-deploy-account-id - # run: echo "ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)" >> "$GITHUB_ENV" - - # - name: Login to Amazon ECR - # id: login-ecr-push-image - # run: | - # aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ env.ACCOUNT_ID }}.dkr.ecr.eu-west-2.amazonaws.com - - # - name: Push FHIR Facade image to Amazon ECR - # run: | - # docker tag "dev-container-image" "${{ env.ACCOUNT_ID }}.dkr.ecr.eu-west-2.amazonaws.com/${{inputs.DEV_CONTAINER_ECR}}:${{ inputs.DEV_CONTAINER_IMAGE_TAG }}" - # docker push "${{ env.ACCOUNT_ID }}.dkr.ecr.eu-west-2.amazonaws.com/${{inputs.DEV_CONTAINER_ECR}}:${{ inputs.DEV_CONTAINER_IMAGE_TAG }}" - - # - name: Check dev container scan results - # env: - # REPOSITORY_NAME: ${{inputs.DEV_CONTAINER_ECR}} - # IMAGE_TAG: ${{ inputs.DEV_CONTAINER_IMAGE_TAG }} - # working-directory: .github/scripts - # run: | - # ./check_ecr_image_scan_results.sh - build_dev_container_x64: - runs-on: ubuntu-22.04 - steps: - - name: Checkout code - uses: actions/checkout@v5 + docker build -f .devcontainer/Dockerfile -t dev-container-image . + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v5 + id: connect-aws-deploy with: - ref: ${{ env.BRANCH_NAME }} - fetch-depth: 0 + aws-region: eu-west-2 + role-to-assume: ${{ secrets.CLOUD_FORMATION_DEPLOY_ROLE }} + role-session-name: dev-container-build-x64 + output-credentials: true - - name: Build dev container + - name: Retrieve AWS Account ID + id: retrieve-deploy-account-id run: | - docker build -f .devcontainer/Dockerfile -t dev-container-image . - # - name: Configure AWS Credentials - # uses: aws-actions/configure-aws-credentials@v5 - # id: connect-aws-deploy - # with: - # aws-region: eu-west-2 - # role-to-assume: ${{ secrets.CLOUD_FORMATION_DEPLOY_ROLE }} - # role-session-name: dev-container-build - # output-credentials: true - - # - name: Retrieve AWS Account ID - # id: retrieve-deploy-account-id - # run: echo "ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)" >> "$GITHUB_ENV" - - # - name: Login to Amazon ECR - # id: login-ecr-push-image - # run: | - # aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ env.ACCOUNT_ID }}.dkr.ecr.eu-west-2.amazonaws.com - - # - name: Push FHIR Facade image to Amazon ECR - # run: | - # docker tag "dev-container-image" "${{ env.ACCOUNT_ID }}.dkr.ecr.eu-west-2.amazonaws.com/${{inputs.DEV_CONTAINER_ECR}}:${{ inputs.DEV_CONTAINER_IMAGE_TAG }}" - # docker push "${{ env.ACCOUNT_ID }}.dkr.ecr.eu-west-2.amazonaws.com/${{inputs.DEV_CONTAINER_ECR}}:${{ inputs.DEV_CONTAINER_IMAGE_TAG }}" - - # - name: Check dev container scan results - # env: - # REPOSITORY_NAME: ${{inputs.DEV_CONTAINER_ECR}} - # IMAGE_TAG: ${{ inputs.DEV_CONTAINER_IMAGE_TAG }} - # working-directory: .github/scripts - # run: | - # ./check_ecr_image_scan_results.sh + ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) + echo "account_id=$ACCOUNT_ID" >> "$GITHUB_OUTPUT" + + - name: Login to Amazon ECR + run: | + aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com + + - name: Push x64 image to Amazon ECR + run: | + docker tag "dev-container-image" "${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-amd64" + docker push "${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-amd64" build_dev_container_arm64: runs-on: ubuntu-22.04-arm + if: ${{ inputs.dev_container_ecr != '' && inputs.dev_container_image_tag != '' }} steps: - name: Checkout code uses: actions/checkout@v5 with: - ref: ${{ env.BRANCH_NAME }} fetch-depth: 0 - name: Build dev container run: | docker build -f .devcontainer/Dockerfile -t dev-container-image-arm . - docker save "dev-container-image-arm" -o dev-container-image-arm.img - - uses: actions/upload-artifact@v4 - name: upload build artifact + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v5 + id: connect-aws-deploy with: - name: dev-container-image-arm - path: dev-container-image-arm.img - # - name: Configure AWS Credentials - # uses: aws-actions/configure-aws-credentials@v5 - # id: connect-aws-deploy - # with: - # aws-region: eu-west-2 - # role-to-assume: ${{ secrets.CLOUD_FORMATION_DEPLOY_ROLE }} - # role-session-name: dev-container-build - # output-credentials: true - - # - name: Retrieve AWS Account ID - # id: retrieve-deploy-account-id - # run: echo "ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)" >> "$GITHUB_ENV" - - # - name: Login to Amazon ECR - # id: login-ecr-push-image - # run: | - # aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ env.ACCOUNT_ID }}.dkr.ecr.eu-west-2.amazonaws.com - - # - name: Push FHIR Facade image to Amazon ECR - # run: | - # docker tag "dev-container-image" "${{ env.ACCOUNT_ID }}.dkr.ecr.eu-west-2.amazonaws.com/${{inputs.DEV_CONTAINER_ECR}}:${{ inputs.DEV_CONTAINER_IMAGE_TAG }}" - # docker push "${{ env.ACCOUNT_ID }}.dkr.ecr.eu-west-2.amazonaws.com/${{inputs.DEV_CONTAINER_ECR}}:${{ inputs.DEV_CONTAINER_IMAGE_TAG }}" - - # - name: Check dev container scan results - # env: - # REPOSITORY_NAME: ${{inputs.DEV_CONTAINER_ECR}} - # IMAGE_TAG: ${{ inputs.DEV_CONTAINER_IMAGE_TAG }} - # working-directory: .github/scripts - # run: | - # ./check_ecr_image_scan_results.sh + aws-region: eu-west-2 + role-to-assume: ${{ secrets.CLOUD_FORMATION_DEPLOY_ROLE }} + role-session-name: dev-container-build-arm64 + output-credentials: true + + - name: Retrieve AWS Account ID + id: retrieve-deploy-account-id + run: | + ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) + echo "account_id=$ACCOUNT_ID" >> "$GITHUB_OUTPUT" + + - name: Login to Amazon ECR + run: | + aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com + + - name: Push ARM64 image to Amazon ECR + run: | + docker tag "dev-container-image-arm" "${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-arm64" + docker push "${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-arm64" + + create_multi_arch_manifest: + runs-on: ubuntu-22.04 + needs: [build_dev_container_x64, build_dev_container_arm64] + if: ${{ inputs.dev_container_ecr != '' && inputs.dev_container_image_tag != '' }} + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v5 + with: + aws-region: eu-west-2 + role-to-assume: ${{ secrets.CLOUD_FORMATION_DEPLOY_ROLE }} + role-session-name: multi-arch-manifest + output-credentials: true + + - name: Retrieve AWS Account ID + id: retrieve-deploy-account-id + run: | + ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) + echo "account_id=$ACCOUNT_ID" >> "$GITHUB_OUTPUT" + + - name: Login to Amazon ECR + run: | + aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com + + - name: Create and push multi-architecture manifest + run: | + # Create manifest list combining both architectures + docker buildx imagetools create -t ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }} \ + ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-amd64 \ + ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-arm64 + + # Also create latest tag + docker buildx imagetools create -t ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:latest \ + ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-amd64 \ + ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-arm64 + + - name: Verify multi-architecture manifest + run: | + echo "=== Verifying multi-architecture manifest ===" + docker buildx imagetools inspect ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }} + + - name: Check dev container scan results + env: + REPOSITORY_NAME: ${{ inputs.dev_container_ecr }} + IMAGE_TAG: ${{ inputs.dev_container_image_tag }} + working-directory: .github/scripts + run: | + # Wait a moment for ECR to process the new manifest + sleep 30 + ./check_ecr_image_scan_results.sh diff --git a/MULTI_ARCH_DOCKER.md b/MULTI_ARCH_DOCKER.md new file mode 100644 index 0000000..57303c9 --- /dev/null +++ b/MULTI_ARCH_DOCKER.md @@ -0,0 +1,123 @@ +# Multi-Architecture Docker Images (Separate Build Approach) + +This workflow builds multi-architecture Docker images by combining separate architecture-specific builds. This approach is more efficient than cross-compilation when you have native runners for each architecture. + +## How It Works + +### 1. Separate Architecture Builds +- **`build_dev_container_x64`**: Builds on `ubuntu-22.04` (native x64) +- **`build_dev_container_arm64`**: Builds on `ubuntu-22.04-arm` (native ARM64) + +Each job: +1. Builds the Docker image natively for its architecture +2. Pushes it to ECR with an architecture-specific tag (e.g., `:v1.0.0-amd64`, `:v1.0.0-arm64`) + +### 2. Multi-Architecture Manifest Creation +- **`create_multi_arch_manifest`**: Combines both images into a multi-arch manifest +- Uses `docker buildx imagetools create` to create a manifest list +- Creates both versioned tag (`:v1.0.0`) and `:latest` tag + +## Usage + +### To Build and Push Multi-Architecture Images + +Call the workflow with both required inputs: + +```yaml +uses: ./.github/workflows/quality-checks.yml +with: + dev_container_ecr: "your-repo-name" + dev_container_image_tag: "v1.0.0" + asdfVersion: "v0.10.2" +secrets: + CLOUD_FORMATION_DEPLOY_ROLE: ${{ secrets.CLOUD_FORMATION_DEPLOY_ROLE }} +``` + +This will: +1. Build x64 image → push as `:v1.0.0-amd64` +2. Build ARM64 image → push as `:v1.0.0-arm64` +3. Create manifest combining both → available as `:v1.0.0` and `:latest` + +### To Skip Multi-Architecture Build + +Call without ECR inputs to skip the container builds entirely: + +```yaml +uses: ./.github/workflows/quality-checks.yml +with: + asdfVersion: "v0.10.2" +``` + +## What Users Get + +Users can pull with a single command: +```bash +docker pull 123456789012.dkr.ecr.eu-west-2.amazonaws.com/your-repo:v1.0.0 +``` + +Docker automatically serves: +- `:v1.0.0-amd64` for Intel/AMD x64 systems +- `:v1.0.0-arm64` for ARM64 systems (Apple Silicon, ARM servers) + +## Benefits of This Approach + +✅ **Faster builds**: Native compilation is much faster than cross-compilation +✅ **Parallel execution**: Both architectures build simultaneously +✅ **Automatic platform detection**: Users get the right architecture transparently +✅ **Conditional execution**: Only runs when ECR inputs are provided +✅ **Security scanning**: Includes ECR vulnerability scanning +✅ **Verification**: Confirms multi-arch manifest was created correctly + +## Architecture Flow + +``` +┌─────────────────┐ ┌─────────────────┐ +│ build_x64 │ │ build_arm64 │ +│ (ubuntu-22.04) │ │ (ubuntu-22.04- │ +│ │ │ arm) │ +│ Build & Push │ │ Build & Push │ +│ :tag-amd64 │ │ :tag-arm64 │ +└─────────┬───────┘ └─────────┬───────┘ + │ │ + └──────────┬───────────┘ + │ + ┌────────────▼────────────┐ + │ create_multi_arch_ │ + │ manifest │ + │ (ubuntu-22.04) │ + │ │ + │ Combine into: │ + │ :tag (multi-arch) │ + │ :latest (multi-arch) │ + └─────────────────────────┘ +``` + +## Verification + +After the workflow completes, you can verify the multi-architecture manifest: + +```bash +# Check the manifest +docker buildx imagetools inspect 123456789012.dkr.ecr.eu-west-2.amazonaws.com/your-repo:v1.0.0 + +# Should show both architectures: +Name: 123456789012.dkr.ecr.eu-west-2.amazonaws.com/your-repo:v1.0.0 +MediaType: application/vnd.docker.distribution.manifest.list.v2+json + +Manifests: + Name: ...your-repo:v1.0.0@sha256:... + MediaType: application/vnd.docker.distribution.manifest.v2+json + Platform: linux/amd64 + + Name: ...your-repo:v1.0.0@sha256:... + MediaType: application/vnd.docker.distribution.manifest.v2+json + Platform: linux/arm64 +``` + +## Technical Details + +- **Job Dependencies**: `create_multi_arch_manifest` waits for both build jobs via `needs:` +- **Conditional Execution**: All container jobs only run when ECR inputs are provided +- **AWS Authentication**: Each job authenticates separately to AWS +- **Build Tools**: Uses Docker Buildx imagetools for manifest creation +- **Security**: 30-second delay before scanning allows ECR to process new images From 2ced8e0668df42e6f6a4cbd16b2931b66c7424e5 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 14:11:09 +0000 Subject: [PATCH 12/62] add id_token permissions --- .gitallowed | 1 + .github/workflows/quality-checks.yml | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/.gitallowed b/.gitallowed index 2a7c5ef..e7593cf 100644 --- a/.gitallowed +++ b/.gitallowed @@ -1,2 +1,3 @@ token: ?"?\$\{\{\s*secrets\.GITHUB_TOKEN\s*\}\}"? .*\.gitallowed.* +id-token: write diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index cea378f..8bb4ddf 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -367,6 +367,8 @@ jobs: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} build_dev_container_x64: + permissions: + id-token: write runs-on: ubuntu-22.04 if: ${{ inputs.dev_container_ecr != '' && inputs.dev_container_image_tag != '' }} steps: @@ -404,6 +406,8 @@ jobs: docker push "${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-amd64" build_dev_container_arm64: + permissions: + id-token: write runs-on: ubuntu-22.04-arm if: ${{ inputs.dev_container_ecr != '' && inputs.dev_container_image_tag != '' }} steps: @@ -441,6 +445,8 @@ jobs: docker push "${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-arm64" create_multi_arch_manifest: + permissions: + id-token: write runs-on: ubuntu-22.04 needs: [build_dev_container_x64, build_dev_container_arm64] if: ${{ inputs.dev_container_ecr != '' && inputs.dev_container_image_tag != '' }} From d01fe8af558f4946984663a7ea2794247994e88a Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 14:23:49 +0000 Subject: [PATCH 13/62] use a different role --- .github/workflows/pull_request.yml | 2 +- .github/workflows/quality-checks.yml | 10 +++++----- .github/workflows/release.yml | 1 + 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index f29800b..13ecdc0 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -36,7 +36,7 @@ jobs: dev_container_image_tag: latest secrets: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - CLOUD_FORMATION_DEPLOY_ROLE: ${{ secrets.CLOUD_FORMATION_DEPLOY_ROLE }} + PUSH_IMAGE_ROLE: ${{ secrets.PUSH_IMAGE_ROLE }} tag_release: needs: [quality_checks, get_asdf_version] uses: NHSDigital/eps-workflow-semantic-release/.github/workflows/tag-release.yml@f80157cecce288dd175e61b477a1d2dbe9c88b99 diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 8bb4ddf..40898d3 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -5,8 +5,8 @@ on: secrets: SONAR_TOKEN: required: false - CLOUD_FORMATION_DEPLOY_ROLE: - required: false + PUSH_IMAGE_ROLE: + required: true inputs: install_java: type: boolean @@ -386,7 +386,7 @@ jobs: id: connect-aws-deploy with: aws-region: eu-west-2 - role-to-assume: ${{ secrets.CLOUD_FORMATION_DEPLOY_ROLE }} + role-to-assume: ${{ secrets.PUSH_IMAGE_ROLE }} role-session-name: dev-container-build-x64 output-credentials: true @@ -425,7 +425,7 @@ jobs: id: connect-aws-deploy with: aws-region: eu-west-2 - role-to-assume: ${{ secrets.CLOUD_FORMATION_DEPLOY_ROLE }} + role-to-assume: ${{ secrets.PUSH_IMAGE_ROLE }} role-session-name: dev-container-build-arm64 output-credentials: true @@ -458,7 +458,7 @@ jobs: uses: aws-actions/configure-aws-credentials@v5 with: aws-region: eu-west-2 - role-to-assume: ${{ secrets.CLOUD_FORMATION_DEPLOY_ROLE }} + role-to-assume: ${{ secrets.PUSH_IMAGE_ROLE }} role-session-name: multi-arch-manifest output-credentials: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6047db5..b849f94 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,6 +32,7 @@ jobs: asdfVersion: ${{ needs.get_asdf_version.outputs.asdf_version }} secrets: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + PUSH_IMAGE_ROLE: ${{ secrets.PUSH_IMAGE_ROLE }} tag_release: needs: [quality_checks, get_asdf_version] uses: NHSDigital/eps-workflow-semantic-release/.github/workflows/tag-release.yml@f80157cecce288dd175e61b477a1d2dbe9c88b99 From 3cf00874647d76063be657d4e55f317fecb5cdc8 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 14:46:52 +0000 Subject: [PATCH 14/62] checkout scanning --- .github/workflows/quality-checks.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 40898d3..1422396 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -451,6 +451,12 @@ jobs: needs: [build_dev_container_x64, build_dev_container_arm64] if: ${{ inputs.dev_container_ecr != '' && inputs.dev_container_image_tag != '' }} steps: + - name: Checkout local github actions + uses: actions/checkout@v5 + with: + fetch-depth: 0 + sparse-checkout: | + .github - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 From bfcc9868493bc1432c28bae93a3bde71c34e747b Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 14:59:59 +0000 Subject: [PATCH 15/62] move scan earlier --- .github/workflows/quality-checks.yml | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 1422396..ade4dee 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -404,6 +404,15 @@ jobs: run: | docker tag "dev-container-image" "${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-amd64" docker push "${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-amd64" + - name: Check dev container scan results + env: + REPOSITORY_NAME: ${{ inputs.dev_container_ecr }} + IMAGE_TAG: ${{ inputs.dev_container_image_tag }}-amd64 + working-directory: .github/scripts + run: | + # Wait a moment for ECR to process the new manifest + sleep 30 + ./check_ecr_image_scan_results.sh build_dev_container_arm64: permissions: @@ -443,6 +452,15 @@ jobs: run: | docker tag "dev-container-image-arm" "${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-arm64" docker push "${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-arm64" + - name: Check dev container scan results + env: + REPOSITORY_NAME: ${{ inputs.dev_container_ecr }} + IMAGE_TAG: ${{ inputs.dev_container_image_tag }}-arm64 + working-directory: .github/scripts + run: | + # Wait a moment for ECR to process the new manifest + sleep 30 + ./check_ecr_image_scan_results.sh create_multi_arch_manifest: permissions: @@ -494,13 +512,3 @@ jobs: run: | echo "=== Verifying multi-architecture manifest ===" docker buildx imagetools inspect ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }} - - - name: Check dev container scan results - env: - REPOSITORY_NAME: ${{ inputs.dev_container_ecr }} - IMAGE_TAG: ${{ inputs.dev_container_image_tag }} - working-directory: .github/scripts - run: | - # Wait a moment for ECR to process the new manifest - sleep 30 - ./check_ecr_image_scan_results.sh From c02c04e0f215b463a4b458c95ae15456154d663e Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 15:09:29 +0000 Subject: [PATCH 16/62] set account id --- .github/scripts/check_ecr_image_scan_results.sh | 2 +- .github/workflows/quality-checks.yml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/scripts/check_ecr_image_scan_results.sh b/.github/scripts/check_ecr_image_scan_results.sh index 4a5222e..a43e1d5 100755 --- a/.github/scripts/check_ecr_image_scan_results.sh +++ b/.github/scripts/check_ecr_image_scan_results.sh @@ -20,7 +20,7 @@ if [ -z "${AWS_REGION}" ]; then fi if [ -z "${ACCOUNT_ID}" ]; then - echo "AWS_REGION not set" + echo "ACCOUNT_ID not set" exit 1 fi diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index ade4dee..31378f3 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -408,6 +408,7 @@ jobs: env: REPOSITORY_NAME: ${{ inputs.dev_container_ecr }} IMAGE_TAG: ${{ inputs.dev_container_image_tag }}-amd64 + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} working-directory: .github/scripts run: | # Wait a moment for ECR to process the new manifest @@ -456,6 +457,7 @@ jobs: env: REPOSITORY_NAME: ${{ inputs.dev_container_ecr }} IMAGE_TAG: ${{ inputs.dev_container_image_tag }}-arm64 + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} working-directory: .github/scripts run: | # Wait a moment for ECR to process the new manifest From 186b451f6b47e3e497e0325f24ae003f558d17ca Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 15:18:34 +0000 Subject: [PATCH 17/62] upgrade node --- .tool-versions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.tool-versions b/.tool-versions index df26591..daea27d 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,4 +1,4 @@ -nodejs 20.18.0 +nodejs 20.19.5 actionlint 1.7.8 shellcheck 0.11.0 python 3.14.0 From 82f6f083f820a75e30014cbadf344ad315ea8d08 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 15:34:20 +0000 Subject: [PATCH 18/62] upgrade to node 22 --- .tool-versions | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.tool-versions b/.tool-versions index daea27d..e0fee42 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,4 +1,4 @@ -nodejs 20.19.5 +nodejs 22.20.0 actionlint 1.7.8 shellcheck 0.11.0 python 3.14.0 From f84df0a09f059a5efec4e51ced88402bda4a1862 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 15:54:04 +0000 Subject: [PATCH 19/62] tag latest --- .github/workflows/pull_request.yml | 45 ++++++++++++++++++++++++++-- .github/workflows/quality-checks.yml | 15 ++++++---- .github/workflows/release.yml | 23 +++++++++++++- 3 files changed, 75 insertions(+), 8 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 13ecdc0..9e5aeff 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -8,6 +8,46 @@ env: BRANCH_NAME: ${{ github.event.pull_request.head.ref }} jobs: + get_issue_number_and_commit_id: + runs-on: ubuntu-22.04 + outputs: + issue_number: ${{ steps.get_issue_number.outputs.result }} + version: ${{ steps.get_issue_number.outputs.version_number }} + commit_id: ${{ steps.commit_id.outputs.commit_id }} + sha_short: ${{ steps.commit_id.outputs.sha_short }} + + steps: + - name: Checkout code + uses: actions/checkout@v5 + with: + ref: ${{ env.BRANCH_NAME }} + + - uses: actions/github-script@v8 + name: get issue number + id: get_issue_number + with: + script: | + if (context.issue.number) { + // Return issue number if present + return context.issue.number; + } else { + // Otherwise return issue number from commit + return ( + await github.rest.repos.listPullRequestsAssociatedWithCommit({ + commit_sha: context.sha, + owner: context.repo.owner, + repo: context.repo.repo, + }) + ).data[0].number; + } + result-encoding: string + - name: Get Commit ID + id: commit_id + run: | + # echo "commit_id=${{ github.sha }}" >> "$GITHUB_ENV" + echo "commit_id=${{ github.sha }}" >> "$GITHUB_OUTPUT" + echo "sha_short=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" + pr_title_format_check: uses: NHSDigital/eps-workflow-semantic-release/.github/workflows/pr_title_check.yml@f80157cecce288dd175e61b477a1d2dbe9c88b99 get_asdf_version: @@ -29,11 +69,12 @@ jobs: echo "TAG_FORMAT=$TAG_FORMAT" >> "$GITHUB_OUTPUT" quality_checks: uses: ./.github/workflows/quality-checks.yml - needs: [get_asdf_version] + needs: [get_asdf_version, get_issue_number_and_commit_id] with: asdfVersion: ${{ needs.get_asdf_version.outputs.asdf_version }} dev_container_ecr: dev-container-quality-checks - dev_container_image_tag: latest + dev_container_image_tag: PR-${{ needs.get_issue_number_and_commit_id.outputs.issue_number }}-${{ needs.get_issue_number_and_commit_id.outputs.sha_short }} + tag_latest: false secrets: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} PUSH_IMAGE_ROLE: ${{ secrets.PUSH_IMAGE_ROLE }} diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 31378f3..7fb6c01 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -28,11 +28,15 @@ on: dev_container_ecr: type: string description: "The name of the ECR repository to push the dev container image to." - required: false + required: true dev_container_image_tag: type: string description: "The tag to use for the dev container image." - required: false + required: true + tag_latest: + type: boolean + description: "If true, the action will also tag the dev container image as 'latest' in ECR." + required: true jobs: quality_checks: runs-on: ubuntu-22.04 @@ -370,7 +374,6 @@ jobs: permissions: id-token: write runs-on: ubuntu-22.04 - if: ${{ inputs.dev_container_ecr != '' && inputs.dev_container_image_tag != '' }} steps: - name: Checkout code uses: actions/checkout@v5 @@ -419,7 +422,6 @@ jobs: permissions: id-token: write runs-on: ubuntu-22.04-arm - if: ${{ inputs.dev_container_ecr != '' && inputs.dev_container_image_tag != '' }} steps: - name: Checkout code uses: actions/checkout@v5 @@ -498,13 +500,16 @@ jobs: run: | aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com - - name: Create and push multi-architecture manifest + - name: Create and push multi-architecture manifest for tag run: | # Create manifest list combining both architectures docker buildx imagetools create -t ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }} \ ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-amd64 \ ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-arm64 + - name: Create and push multi-architecture manifest for latest tag + if: ${{ inputs.tag_latest == true }} + run: | # Also create latest tag docker buildx imagetools create -t ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:latest \ ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-amd64 \ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b849f94..4acedfd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,6 +8,24 @@ env: BRANCH_NAME: ${{ github.event.ref.BRANCH_NAME }} jobs: + get_commit_id: + runs-on: ubuntu-22.04 + outputs: + commit_id: ${{ steps.commit_id.outputs.commit_id }} + sha_short: ${{ steps.commit_id.outputs.sha_short }} + + steps: + - name: Checkout code + uses: actions/checkout@v5 + with: + ref: ${{ env.BRANCH_NAME }} + + - name: Get Commit ID + id: commit_id + run: | + # echo "commit_id=${{ github.sha }}" >> "$GITHUB_ENV" + echo "commit_id=${{ github.sha }}" >> "$GITHUB_OUTPUT" + echo "sha_short=$(git rev-parse --short HEAD)" >> "$GITHUB_OUTPUT" get_asdf_version: runs-on: ubuntu-22.04 outputs: @@ -26,10 +44,13 @@ jobs: TAG_FORMAT=$(yq '.TAG_FORMAT' .github/config/settings.yml) echo "TAG_FORMAT=$TAG_FORMAT" >> "$GITHUB_OUTPUT" quality_checks: - needs: [get_asdf_version] + needs: [get_asdf_version, get_commit_id] uses: ./.github/workflows/quality-checks.yml with: asdfVersion: ${{ needs.get_asdf_version.outputs.asdf_version }} + tag_latest: true + dev_container_ecr: dev-container-quality-checks + dev_container_image_tag: release-${{ needs.get_commit_id.outputs.sha_short }} secrets: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} PUSH_IMAGE_ROLE: ${{ secrets.PUSH_IMAGE_ROLE }} From 3c4ada442e316a9b9ba704e77def558f67714d73 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 16:06:22 +0000 Subject: [PATCH 20/62] trigger build From a027a79c60890d3d004a565a9d27decd2fe24bb8 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 16:32:04 +0000 Subject: [PATCH 21/62] fix check python licences --- .github/workflows/quality-checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 7fb6c01..f406c06 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -217,7 +217,7 @@ jobs: fi # known packages with dual licensing - IGNORE_PACKAGES="PyGithub chardet text-unidecode" + IGNORE_PACKAGES='"PyGithub" "chardet" "text-unidecode"' LICENSES=$(poetry run pip-licenses --ignore-packages "${IGNORE_PACKAGES}") INCOMPATIBLE_LIBS=$(echo "$LICENSES" | grep 'GPL' || true) From b74c25e81bec511e804c5c40794b45431d5fa649 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 16:34:36 +0000 Subject: [PATCH 22/62] remove python licence check --- .github/workflows/quality-checks.yml | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index f406c06..9f32a32 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -204,32 +204,6 @@ jobs: run: | make check-licenses - - name: Check licenses (Python) - if: steps.check_poetry.outputs.uses_poetry == 'true' - run: | - #!/bin/bash - set -euo pipefail - - # Install pip-licenses if not already installed - if ! poetry run pip show pip-licenses > /dev/null 2>&1; then - echo "pip-licenses is not detected. Installing..." - poetry run pip install pip-licenses - fi - - # known packages with dual licensing - IGNORE_PACKAGES='"PyGithub" "chardet" "text-unidecode"' - LICENSES=$(poetry run pip-licenses --ignore-packages "${IGNORE_PACKAGES}") - INCOMPATIBLE_LIBS=$(echo "$LICENSES" | grep 'GPL' || true) - - if [[ -z $INCOMPATIBLE_LIBS ]]; then - echo "Checked licenses are OK" - exit 0 - else - echo "The following libraries were found which are not compatible with this project's license:" - echo "$INCOMPATIBLE_LIBS" - exit 1 - fi - - name: Run code lint run: make lint From 67a7108980f39fcbd512cd9b8cfed23c7c4daa84 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 16:46:15 +0000 Subject: [PATCH 23/62] checkout local scripts --- .github/workflows/quality-checks.yml | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 9f32a32..cfe8b93 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -354,6 +354,15 @@ jobs: with: fetch-depth: 0 + - name: Checkout .github folder from workflow repo + uses: actions/checkout@v5 + with: + repository: ${{ github.repository }} + path: .workflow-github + sparse-checkout: | + .github + sparse-checkout-cone-mode: false + - name: Build dev container run: | docker build -f .devcontainer/Dockerfile -t dev-container-image . @@ -386,7 +395,7 @@ jobs: REPOSITORY_NAME: ${{ inputs.dev_container_ecr }} IMAGE_TAG: ${{ inputs.dev_container_image_tag }}-amd64 ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} - working-directory: .github/scripts + working-directory: .workflow-github/.github/scripts run: | # Wait a moment for ECR to process the new manifest sleep 30 @@ -434,7 +443,7 @@ jobs: REPOSITORY_NAME: ${{ inputs.dev_container_ecr }} IMAGE_TAG: ${{ inputs.dev_container_image_tag }}-arm64 ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} - working-directory: .github/scripts + working-directory: .workflow-github/.github/scripts run: | # Wait a moment for ECR to process the new manifest sleep 30 @@ -447,12 +456,6 @@ jobs: needs: [build_dev_container_x64, build_dev_container_arm64] if: ${{ inputs.dev_container_ecr != '' && inputs.dev_container_image_tag != '' }} steps: - - name: Checkout local github actions - uses: actions/checkout@v5 - with: - fetch-depth: 0 - sparse-checkout: | - .github - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 From 630f5f5b278589c3b00a5127befc5d684058506e Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 16:55:17 +0000 Subject: [PATCH 24/62] checkout for arm64 --- .github/workflows/quality-checks.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index cfe8b93..2decf33 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -411,6 +411,15 @@ jobs: with: fetch-depth: 0 + - name: Checkout .github folder from workflow repo + uses: actions/checkout@v5 + with: + repository: ${{ github.repository }} + path: .workflow-github + sparse-checkout: | + .github + sparse-checkout-cone-mode: false + - name: Build dev container run: | docker build -f .devcontainer/Dockerfile -t dev-container-image-arm . From 0fdd658b51683e33d38e42f3415bfd0aa07abf42 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 18:07:06 +0000 Subject: [PATCH 25/62] use action locations --- .github/workflows/quality-checks.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 2decf33..34ec940 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -357,7 +357,8 @@ jobs: - name: Checkout .github folder from workflow repo uses: actions/checkout@v5 with: - repository: ${{ github.repository }} + repository: ${{ github.action_repository }} + ref: ${{ github.action_ref }} path: .workflow-github sparse-checkout: | .github @@ -414,7 +415,8 @@ jobs: - name: Checkout .github folder from workflow repo uses: actions/checkout@v5 with: - repository: ${{ github.repository }} + repository: ${{ github.action_repository }} + ref: ${{ github.action_ref }} path: .workflow-github sparse-checkout: | .github From 491b0ed5094129d1b826a09e8c534891337c01c9 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 18:24:27 +0000 Subject: [PATCH 26/62] debug --- .github/workflows/quality-checks.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 34ec940..7901ab0 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -396,11 +396,12 @@ jobs: REPOSITORY_NAME: ${{ inputs.dev_container_ecr }} IMAGE_TAG: ${{ inputs.dev_container_image_tag }}-amd64 ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} - working-directory: .workflow-github/.github/scripts + working-directory: .workflow-github/ run: | + ls -la . # Wait a moment for ECR to process the new manifest sleep 30 - ./check_ecr_image_scan_results.sh + ./.github/scripts/check_ecr_image_scan_results.sh build_dev_container_arm64: permissions: @@ -454,11 +455,13 @@ jobs: REPOSITORY_NAME: ${{ inputs.dev_container_ecr }} IMAGE_TAG: ${{ inputs.dev_container_image_tag }}-arm64 ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} - working-directory: .workflow-github/.github/scripts + working-directory: .workflow-github/ run: | + # List files recursively first + ls -la . # Wait a moment for ECR to process the new manifest sleep 30 - ./check_ecr_image_scan_results.sh + ./.github/scripts/check_ecr_image_scan_results.sh create_multi_arch_manifest: permissions: From b059f46d13866a4de497a2683b5302434ac78300 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 18:30:51 +0000 Subject: [PATCH 27/62] another try --- .github/workflows/quality-checks.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 7901ab0..2821217 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -361,8 +361,7 @@ jobs: ref: ${{ github.action_ref }} path: .workflow-github sparse-checkout: | - .github - sparse-checkout-cone-mode: false + .github/scripts/check_ecr_image_scan_results.sh - name: Build dev container run: | @@ -420,8 +419,7 @@ jobs: ref: ${{ github.action_ref }} path: .workflow-github sparse-checkout: | - .github - sparse-checkout-cone-mode: false + .github/scripts/check_ecr_image_scan_results.sh - name: Build dev container run: | From bbd7f8e576de24427e4a24c14e6962acd1c4d85c Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 19:05:06 +0000 Subject: [PATCH 28/62] download script --- .github/workflows/quality-checks.yml | 38 ++++++++++------------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 2821217..b9f5684 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -37,6 +37,11 @@ on: type: boolean description: "If true, the action will also tag the dev container image as 'latest' in ECR." required: true + check_ecr_image_scan_results_script_tag: + type: string + description: "The tag to download check_ecr_image_scan_results.sh script." + required: false + default: "dev_container_build" jobs: quality_checks: runs-on: ubuntu-22.04 @@ -354,15 +359,10 @@ jobs: with: fetch-depth: 0 - - name: Checkout .github folder from workflow repo - uses: actions/checkout@v5 - with: - repository: ${{ github.action_repository }} - ref: ${{ github.action_ref }} - path: .workflow-github - sparse-checkout: | - .github/scripts/check_ecr_image_scan_results.sh - + - name: Download check_ecr_image_scan_results.sh script + run: | + curl -L https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/heads/${{inputs.check_ecr_image_scan_results_script_tag}}/.github/scripts/check_ecr_image_scan_results.sh -o check_ecr_image_scan_results.sh + chmod +x check_ecr_image_scan_results.sh - name: Build dev container run: | docker build -f .devcontainer/Dockerfile -t dev-container-image . @@ -395,10 +395,7 @@ jobs: REPOSITORY_NAME: ${{ inputs.dev_container_ecr }} IMAGE_TAG: ${{ inputs.dev_container_image_tag }}-amd64 ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} - working-directory: .workflow-github/ run: | - ls -la . - # Wait a moment for ECR to process the new manifest sleep 30 ./.github/scripts/check_ecr_image_scan_results.sh @@ -412,14 +409,10 @@ jobs: with: fetch-depth: 0 - - name: Checkout .github folder from workflow repo - uses: actions/checkout@v5 - with: - repository: ${{ github.action_repository }} - ref: ${{ github.action_ref }} - path: .workflow-github - sparse-checkout: | - .github/scripts/check_ecr_image_scan_results.sh + - name: Download check_ecr_image_scan_results.sh script + run: | + curl -L https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/heads/${{inputs.check_ecr_image_scan_results_script_tag}}/.github/scripts/check_ecr_image_scan_results.sh -o check_ecr_image_scan_results.sh + chmod +x check_ecr_image_scan_results.sh - name: Build dev container run: | @@ -453,13 +446,10 @@ jobs: REPOSITORY_NAME: ${{ inputs.dev_container_ecr }} IMAGE_TAG: ${{ inputs.dev_container_image_tag }}-arm64 ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} - working-directory: .workflow-github/ run: | - # List files recursively first - ls -la . # Wait a moment for ECR to process the new manifest sleep 30 - ./.github/scripts/check_ecr_image_scan_results.sh + ./check_ecr_image_scan_results.sh create_multi_arch_manifest: permissions: From ccbdfdae58eb1e07b5cf52478815d4e6b6c43d96 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 19:08:23 +0000 Subject: [PATCH 29/62] fix path --- .github/workflows/quality-checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index b9f5684..7aef08c 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -397,7 +397,7 @@ jobs: ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} run: | sleep 30 - ./.github/scripts/check_ecr_image_scan_results.sh + ./check_ecr_image_scan_results.sh build_dev_container_arm64: permissions: From dc4ff9229e9b66affa3cd09189a45e652e6d5f9f Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 19:29:49 +0000 Subject: [PATCH 30/62] fix problems --- .github/workflows/pull_request.yml | 1 - .github/workflows/quality-checks.yml | 55 +++++++++++++++++----------- .github/workflows/release.yml | 1 - 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 9e5aeff..f86bb0b 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -74,7 +74,6 @@ jobs: asdfVersion: ${{ needs.get_asdf_version.outputs.asdf_version }} dev_container_ecr: dev-container-quality-checks dev_container_image_tag: PR-${{ needs.get_issue_number_and_commit_id.outputs.issue_number }}-${{ needs.get_issue_number_and_commit_id.outputs.sha_short }} - tag_latest: false secrets: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} PUSH_IMAGE_ROLE: ${{ secrets.PUSH_IMAGE_ROLE }} diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 7aef08c..d4803ec 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -33,10 +33,6 @@ on: type: string description: "The tag to use for the dev container image." required: true - tag_latest: - type: boolean - description: "If true, the action will also tag the dev container image as 'latest' in ECR." - required: true check_ecr_image_scan_results_script_tag: type: string description: "The tag to download check_ecr_image_scan_results.sh script." @@ -360,8 +356,10 @@ jobs: fetch-depth: 0 - name: Download check_ecr_image_scan_results.sh script + env: + SCRIPT_TAG: ${{ inputs.check_ecr_image_scan_results_script_tag }} run: | - curl -L https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/heads/${{inputs.check_ecr_image_scan_results_script_tag}}/.github/scripts/check_ecr_image_scan_results.sh -o check_ecr_image_scan_results.sh + curl -L "https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/heads/${SCRIPT_TAG}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh chmod +x check_ecr_image_scan_results.sh - name: Build dev container run: | @@ -387,9 +385,13 @@ jobs: aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com - name: Push x64 image to Amazon ECR + env: + ECR_REPOSITORY: ${{ inputs.dev_container_ecr }} + IMAGE_TAG: ${{ inputs.dev_container_image_tag }} + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} run: | - docker tag "dev-container-image" "${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-amd64" - docker push "${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-amd64" + docker tag "dev-container-image" "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" + docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" - name: Check dev container scan results env: REPOSITORY_NAME: ${{ inputs.dev_container_ecr }} @@ -410,9 +412,14 @@ jobs: fetch-depth: 0 - name: Download check_ecr_image_scan_results.sh script + env: + SCRIPT_TAG: ${{ inputs.check_ecr_image_scan_results_script_tag }} run: | - curl -L https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/heads/${{inputs.check_ecr_image_scan_results_script_tag}}/.github/scripts/check_ecr_image_scan_results.sh -o check_ecr_image_scan_results.sh + curl -L "https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/heads/${SCRIPT_TAG}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh chmod +x check_ecr_image_scan_results.sh + - name: Build dev container + run: | + docker build -f .devcontainer/Dockerfile -t dev-container-image . - name: Build dev container run: | @@ -438,9 +445,13 @@ jobs: aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com - name: Push ARM64 image to Amazon ECR + env: + ECR_REPOSITORY: ${{ inputs.dev_container_ecr }} + IMAGE_TAG: ${{ inputs.dev_container_image_tag }} + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} run: | - docker tag "dev-container-image-arm" "${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-arm64" - docker push "${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-arm64" + docker tag "dev-container-image-arm" "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" + docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" - name: Check dev container scan results env: REPOSITORY_NAME: ${{ inputs.dev_container_ecr }} @@ -480,21 +491,21 @@ jobs: aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com - name: Create and push multi-architecture manifest for tag + env: + ECR_REPOSITORY: ${{ inputs.dev_container_ecr }} + IMAGE_TAG: ${{ inputs.dev_container_image_tag }} + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} run: | # Create manifest list combining both architectures - docker buildx imagetools create -t ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }} \ - ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-amd64 \ - ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-arm64 - - - name: Create and push multi-architecture manifest for latest tag - if: ${{ inputs.tag_latest == true }} - run: | - # Also create latest tag - docker buildx imagetools create -t ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:latest \ - ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-amd64 \ - ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }}-arm64 + docker buildx imagetools create -t "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" - name: Verify multi-architecture manifest + env: + ECR_REPOSITORY: ${{ inputs.dev_container_ecr }} + IMAGE_TAG: ${{ inputs.dev_container_image_tag }} + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} run: | echo "=== Verifying multi-architecture manifest ===" - docker buildx imagetools inspect ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com/${{ inputs.dev_container_ecr }}:${{ inputs.dev_container_image_tag }} + docker buildx imagetools inspect "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4acedfd..65b8768 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -48,7 +48,6 @@ jobs: uses: ./.github/workflows/quality-checks.yml with: asdfVersion: ${{ needs.get_asdf_version.outputs.asdf_version }} - tag_latest: true dev_container_ecr: dev-container-quality-checks dev_container_image_tag: release-${{ needs.get_commit_id.outputs.sha_short }} secrets: From ddc04e4c9d4c7530c2e54169687921e8eaa46c59 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 19:38:21 +0000 Subject: [PATCH 31/62] use hash --- .github/workflows/quality-checks.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index d4803ec..738d7f5 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -366,7 +366,7 @@ jobs: docker build -f .devcontainer/Dockerfile -t dev-container-image . - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v5 + uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 id: connect-aws-deploy with: aws-region: eu-west-2 @@ -426,7 +426,7 @@ jobs: docker build -f .devcontainer/Dockerfile -t dev-container-image-arm . - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v5 + uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 id: connect-aws-deploy with: aws-region: eu-west-2 @@ -473,7 +473,7 @@ jobs: uses: docker/setup-buildx-action@v3 - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v5 + uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 with: aws-region: eu-west-2 role-to-assume: ${{ secrets.PUSH_IMAGE_ROLE }} From 8c2c53c3750d5da61f09b5555259b08f89057433 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 19:52:31 +0000 Subject: [PATCH 32/62] apply latest tag --- .github/workflows/pull_request.yml | 9 +++ .github/workflows/quality-checks.yml | 3 +- .../workflows/tag_latest_dev_container.yml | 70 +++++++++++++++++++ 3 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/tag_latest_dev_container.yml diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index f86bb0b..8c19bc9 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -77,6 +77,15 @@ jobs: secrets: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} PUSH_IMAGE_ROLE: ${{ secrets.PUSH_IMAGE_ROLE }} + tag_latest_dev_container: + needs: [quality_checks, get_issue_number_and_commit_id] + uses: ./.github/workflows/tag_latest_dev_container.yml + with: + dev_container_ecr: dev-container-quality-checks + dev_container_image_tag: PR-${{ needs.get_issue_number_and_commit_id.outputs.issue_number }}-${{ needs.get_issue_number_and_commit_id.outputs.sha_short }} + version_tag_to_apply: FooBar + secrets: + PUSH_IMAGE_ROLE: ${{ secrets.PUSH_IMAGE_ROLE }} tag_release: needs: [quality_checks, get_asdf_version] uses: NHSDigital/eps-workflow-semantic-release/.github/workflows/tag-release.yml@f80157cecce288dd175e61b477a1d2dbe9c88b99 diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 738d7f5..0744121 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -467,10 +467,9 @@ jobs: id-token: write runs-on: ubuntu-22.04 needs: [build_dev_container_x64, build_dev_container_arm64] - if: ${{ inputs.dev_container_ecr != '' && inputs.dev_container_image_tag != '' }} steps: - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 diff --git a/.github/workflows/tag_latest_dev_container.yml b/.github/workflows/tag_latest_dev_container.yml new file mode 100644 index 0000000..40800a9 --- /dev/null +++ b/.github/workflows/tag_latest_dev_container.yml @@ -0,0 +1,70 @@ +name: Tag Latest Dev Container + +on: + workflow_call: + secrets: + PUSH_IMAGE_ROLE: + required: true + inputs: + dev_container_ecr: + type: string + description: "The name of the ECR repository to push the dev container image to." + required: true + dev_container_image_tag: + type: string + description: "The tag to use for the dev container image." + required: true + version_tag_to_apply: + type: string + description: "The version tag to apply to the latest dev container image." + required: true +jobs: + create_multi_arch_manifest: + permissions: + id-token: write + runs-on: ubuntu-22.04 + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 + with: + aws-region: eu-west-2 + role-to-assume: ${{ secrets.PUSH_IMAGE_ROLE }} + role-session-name: multi-arch-manifest + output-credentials: true + + - name: Retrieve AWS Account ID + id: retrieve-deploy-account-id + run: | + ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) + echo "account_id=$ACCOUNT_ID" >> "$GITHUB_OUTPUT" + + - name: Login to Amazon ECR + run: | + aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com + + - name: Create and push multi-architecture manifest for tag + env: + ECR_REPOSITORY: ${{ inputs.dev_container_ecr }} + IMAGE_TAG: ${{ inputs.dev_container_image_tag }} + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + VERSION_TAG_TO_APPLY: ${{ inputs.version_tag_to_apply }} + run: | + # Create manifest list combining both architectures + docker buildx imagetools create -t "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" + docker buildx imagetools create -t "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" + + - name: Verify multi-architecture manifest + env: + ECR_REPOSITORY: ${{ inputs.dev_container_ecr }} + IMAGE_TAG: ${{ inputs.dev_container_image_tag }} + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + run: | + echo "=== Verifying multi-architecture manifest ===" + docker buildx imagetools inspect "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest" From c16e0983866236d41a7ecdfbf38780d52b72cff9 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 22 Oct 2025 19:53:24 +0000 Subject: [PATCH 33/62] fix name --- .github/workflows/tag_latest_dev_container.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tag_latest_dev_container.yml b/.github/workflows/tag_latest_dev_container.yml index 40800a9..f8b8440 100644 --- a/.github/workflows/tag_latest_dev_container.yml +++ b/.github/workflows/tag_latest_dev_container.yml @@ -19,7 +19,7 @@ on: description: "The version tag to apply to the latest dev container image." required: true jobs: - create_multi_arch_manifest: + tag_latest_dev_container: permissions: id-token: write runs-on: ubuntu-22.04 From 0f8dc72727ed600ee119ca8d7ad0619c9da58630 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Thu, 23 Oct 2025 07:37:06 +0000 Subject: [PATCH 34/62] appy tag to image --- .github/workflows/tag_latest_dev_container.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.github/workflows/tag_latest_dev_container.yml b/.github/workflows/tag_latest_dev_container.yml index f8b8440..b1b73b4 100644 --- a/.github/workflows/tag_latest_dev_container.yml +++ b/.github/workflows/tag_latest_dev_container.yml @@ -60,6 +60,22 @@ jobs: "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" \ "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" + # Apply additional tags to individual architecture images + docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}-amd64" + docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}-arm64" + docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest-amd64" + docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest-arm64" + + # Push the tagged images + docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}-amd64" + docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}-arm64" + docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest-amd64" + docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest-arm64" + - name: Verify multi-architecture manifest env: ECR_REPOSITORY: ${{ inputs.dev_container_ecr }} From 46623108a32af5a7db0311a5352cf67ccb2248fc Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Thu, 23 Oct 2025 07:46:20 +0000 Subject: [PATCH 35/62] build nhsd_git_secrets --- .github/workflows/build_nhsd_git_secrets.yml | 184 +++++++++++++++++++ .github/workflows/pull_request.yml | 10 + .github/workflows/quality-checks.yml | 3 - 3 files changed, 194 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/build_nhsd_git_secrets.yml diff --git a/.github/workflows/build_nhsd_git_secrets.yml b/.github/workflows/build_nhsd_git_secrets.yml new file mode 100644 index 0000000..f127656 --- /dev/null +++ b/.github/workflows/build_nhsd_git_secrets.yml @@ -0,0 +1,184 @@ +name: Build nhsd git secrets + +on: + workflow_call: + secrets: + SONAR_TOKEN: + required: false + PUSH_IMAGE_ROLE: + required: true + inputs: + git_secrets_container_ecr: + type: string + description: "The name of the ECR repository to push the dev container image to." + required: true + git_secrets_container_image_tag: + type: string + description: "The tag to use for the dev container image." + required: true + check_ecr_image_scan_results_script_tag: + type: string + description: "The tag to download check_ecr_image_scan_results.sh script." + required: false + default: "dev_container_build" +jobs: + build_nhsd_git_secrets_x64: + permissions: + id-token: write + runs-on: ubuntu-22.04 + steps: + - name: Checkout code + uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - name: Download check_ecr_image_scan_results.sh script + env: + SCRIPT_TAG: ${{ inputs.check_ecr_image_scan_results_script_tag }} + run: | + curl -L "https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/heads/${SCRIPT_TAG}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh + chmod +x check_ecr_image_scan_results.sh + - name: Build dev container + run: | + docker build -f dockerfiles/nhsd-git-secrets.dockerfile -t nhsd-git-secrets-image . + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 + id: connect-aws-deploy + with: + aws-region: eu-west-2 + role-to-assume: ${{ secrets.PUSH_IMAGE_ROLE }} + role-session-name: dev-container-build-x64 + output-credentials: true + + - name: Retrieve AWS Account ID + id: retrieve-deploy-account-id + run: | + ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) + echo "account_id=$ACCOUNT_ID" >> "$GITHUB_OUTPUT" + + - name: Login to Amazon ECR + run: | + aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com + + - name: Push x64 image to Amazon ECR + env: + ECR_REPOSITORY: ${{ inputs.git_secrets_container_ecr }} + IMAGE_TAG: ${{ inputs.git_secrets_container_image_tag }} + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + run: | + docker tag "dev-container-image" "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" + docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" + - name: Check dev container scan results + env: + REPOSITORY_NAME: ${{ inputs.git_secrets_container_ecr }} + IMAGE_TAG: ${{ inputs.git_secrets_container_image_tag }}-amd64 + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + run: | + sleep 30 + ./check_ecr_image_scan_results.sh + + build_nhsd_git_secrets_arm64: + permissions: + id-token: write + runs-on: ubuntu-22.04-arm + steps: + - name: Checkout code + uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - name: Download check_ecr_image_scan_results.sh script + env: + SCRIPT_TAG: ${{ inputs.check_ecr_image_scan_results_script_tag }} + run: | + curl -L "https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/heads/${SCRIPT_TAG}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh + chmod +x check_ecr_image_scan_results.sh + + - name: Build dev container + run: | + docker build -f dockerfiles/nhsd-git-secrets.dockerfile -t nhsd-git-secrets-image-arm . + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 + id: connect-aws-deploy + with: + aws-region: eu-west-2 + role-to-assume: ${{ secrets.PUSH_IMAGE_ROLE }} + role-session-name: dev-container-build-arm64 + output-credentials: true + + - name: Retrieve AWS Account ID + id: retrieve-deploy-account-id + run: | + ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) + echo "account_id=$ACCOUNT_ID" >> "$GITHUB_OUTPUT" + + - name: Login to Amazon ECR + run: | + aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com + + - name: Push ARM64 image to Amazon ECR + env: + ECR_REPOSITORY: ${{ inputs.git_secrets_container_ecr }} + IMAGE_TAG: ${{ inputs.git_secrets_container_image_tag }} + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + run: | + docker tag "dev-container-image-arm" "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" + docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" + - name: Check dev container scan results + env: + REPOSITORY_NAME: ${{ inputs.git_secrets_container_ecr }} + IMAGE_TAG: ${{ inputs.git_secrets_container_image_tag }}-arm64 + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + run: | + # Wait a moment for ECR to process the new manifest + sleep 30 + ./check_ecr_image_scan_results.sh + + create_multi_arch_manifest: + permissions: + id-token: write + runs-on: ubuntu-22.04 + needs: [build_nhsd_git_secrets_x64, build_nhsd_git_secrets_arm64] + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 + with: + aws-region: eu-west-2 + role-to-assume: ${{ secrets.PUSH_IMAGE_ROLE }} + role-session-name: multi-arch-manifest + output-credentials: true + + - name: Retrieve AWS Account ID + id: retrieve-deploy-account-id + run: | + ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) + echo "account_id=$ACCOUNT_ID" >> "$GITHUB_OUTPUT" + + - name: Login to Amazon ECR + run: | + aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com + + - name: Create and push multi-architecture manifest for tag + env: + ECR_REPOSITORY: ${{ inputs.git_secrets_container_ecr }} + IMAGE_TAG: ${{ inputs.git_secrets_container_image_tag }} + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + run: | + # Create manifest list combining both architectures + docker buildx imagetools create -t "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" + + - name: Verify multi-architecture manifest + env: + ECR_REPOSITORY: ${{ inputs.git_secrets_container_ecr }} + IMAGE_TAG: ${{ inputs.git_secrets_container_image_tag }} + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + run: | + echo "=== Verifying multi-architecture manifest ===" + docker buildx imagetools inspect "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}" diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 8c19bc9..74723c8 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -77,6 +77,16 @@ jobs: secrets: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} PUSH_IMAGE_ROLE: ${{ secrets.PUSH_IMAGE_ROLE }} + + build_nhsd_git_secrets_x64: + uses: ./.github/workflows/build_nhsd_git_secrets.yml + needs: [get_asdf_version, get_issue_number_and_commit_id] + with: + git_secrets_container_ecr: dev-container-quality-checks + git_secrets_container_image_tag: PR-${{ needs.get_issue_number_and_commit_id.outputs.issue_number }}-${{ needs.get_issue_number_and_commit_id.outputs.sha_short }} + secrets: + PUSH_IMAGE_ROLE: ${{ secrets.PUSH_IMAGE_ROLE }} + tag_latest_dev_container: needs: [quality_checks, get_issue_number_and_commit_id] uses: ./.github/workflows/tag_latest_dev_container.yml diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 0744121..d848edc 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -417,9 +417,6 @@ jobs: run: | curl -L "https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/heads/${SCRIPT_TAG}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh chmod +x check_ecr_image_scan_results.sh - - name: Build dev container - run: | - docker build -f .devcontainer/Dockerfile -t dev-container-image . - name: Build dev container run: | From c7d49dbc07f53b8012f82b96b511cc98f6901248 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Thu, 23 Oct 2025 07:54:59 +0000 Subject: [PATCH 36/62] correct build --- .github/workflows/build_nhsd_git_secrets.yml | 4 ++-- .github/workflows/pull_request.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build_nhsd_git_secrets.yml b/.github/workflows/build_nhsd_git_secrets.yml index f127656..6af8313 100644 --- a/.github/workflows/build_nhsd_git_secrets.yml +++ b/.github/workflows/build_nhsd_git_secrets.yml @@ -67,7 +67,7 @@ jobs: IMAGE_TAG: ${{ inputs.git_secrets_container_image_tag }} ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} run: | - docker tag "dev-container-image" "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" + docker tag "nhsd-git-secrets-image" "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" - name: Check dev container scan results env: @@ -124,7 +124,7 @@ jobs: IMAGE_TAG: ${{ inputs.git_secrets_container_image_tag }} ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} run: | - docker tag "dev-container-image-arm" "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" + docker tag "nhsd-git-secrets-image-arm" "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" - name: Check dev container scan results env: diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 74723c8..0e30bae 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -83,7 +83,7 @@ jobs: needs: [get_asdf_version, get_issue_number_and_commit_id] with: git_secrets_container_ecr: dev-container-quality-checks - git_secrets_container_image_tag: PR-${{ needs.get_issue_number_and_commit_id.outputs.issue_number }}-${{ needs.get_issue_number_and_commit_id.outputs.sha_short }} + git_secrets_container_image_tag: PR-${{ needs.get_issue_number_and_commit_id.outputs.issue_number }}-${{ needs.get_issue_number_and_commit_id.outputs.sha_short }}-nhsd-git-secrets secrets: PUSH_IMAGE_ROLE: ${{ secrets.PUSH_IMAGE_ROLE }} From 6ddd57dd785dc6626a1301abda95e4c3c7b59ba6 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Thu, 23 Oct 2025 07:57:41 +0000 Subject: [PATCH 37/62] try to not push --- .../workflows/tag_latest_dev_container.yml | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/.github/workflows/tag_latest_dev_container.yml b/.github/workflows/tag_latest_dev_container.yml index b1b73b4..e1159a4 100644 --- a/.github/workflows/tag_latest_dev_container.yml +++ b/.github/workflows/tag_latest_dev_container.yml @@ -60,21 +60,15 @@ jobs: "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" \ "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" - # Apply additional tags to individual architecture images - docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" \ - "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}-amd64" - docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" \ - "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}-arm64" - docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" \ - "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest-amd64" - docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" \ - "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest-arm64" - - # Push the tagged images - docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}-amd64" - docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}-arm64" - docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest-amd64" - docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest-arm64" + # Create additional tags for individual architecture images without pulling + docker buildx imagetools create -t "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}-amd64" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" + docker buildx imagetools create -t "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}-arm64" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" + docker buildx imagetools create -t "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest-amd64" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" + docker buildx imagetools create -t "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest-arm64" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" - name: Verify multi-architecture manifest env: From 03a0bd7f91c972946492b044a560608442a59d4c Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Thu, 23 Oct 2025 08:11:38 +0000 Subject: [PATCH 38/62] use different commands to tag --- .../workflows/tag_latest_dev_container.yml | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/.github/workflows/tag_latest_dev_container.yml b/.github/workflows/tag_latest_dev_container.yml index e1159a4..3ba39dd 100644 --- a/.github/workflows/tag_latest_dev_container.yml +++ b/.github/workflows/tag_latest_dev_container.yml @@ -60,15 +60,30 @@ jobs: "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" \ "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" - # Create additional tags for individual architecture images without pulling - docker buildx imagetools create -t "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}-amd64" \ - "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" - docker buildx imagetools create -t "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}-arm64" \ - "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" - docker buildx imagetools create -t "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest-amd64" \ - "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" - docker buildx imagetools create -t "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest-arm64" \ - "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" + - name: Tag images for individual architectures + env: + ECR_REPOSITORY: ${{ inputs.dev_container_ecr }} + IMAGE_TAG: ${{ inputs.dev_container_image_tag }} + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + VERSION_TAG_TO_APPLY: ${{ inputs.version_tag_to_apply }} + run: | + # Tag the image (this creates an alias without pulling) + docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}-amd64" + docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}-arm64" + + docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest-amd64" + docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest-arm64" + + # Push the new tags + docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}-amd64" + docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}-arm64" + + docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest-amd64" + docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest-arm64" - name: Verify multi-architecture manifest env: From 61ae19fc6b37758d8dc256c509658c35e69a8dc7 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Thu, 23 Oct 2025 08:24:58 +0000 Subject: [PATCH 39/62] tag image a different way --- .devcontainer/devcontainer.json | 1 + .../workflows/tag_latest_dev_container.yml | 37 ++++++++++++------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 9806958..d62fc83 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -3,6 +3,7 @@ { "name": "Ubuntu", // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "foo", "build": { "dockerfile": "Dockerfile", "context": "..", diff --git a/.github/workflows/tag_latest_dev_container.yml b/.github/workflows/tag_latest_dev_container.yml index 3ba39dd..c08f065 100644 --- a/.github/workflows/tag_latest_dev_container.yml +++ b/.github/workflows/tag_latest_dev_container.yml @@ -67,23 +67,32 @@ jobs: ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} VERSION_TAG_TO_APPLY: ${{ inputs.version_tag_to_apply }} run: | - # Tag the image (this creates an alias without pulling) - docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" \ - "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}-amd64" - docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" \ - "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}-arm64" + # Get the image manifest + MANIFEST=$(aws ecr batch-get-image \ + --repository-name "${ECR_REPOSITORY}" \ + --image-ids imageTag="${IMAGE_TAG}-amd64" \ + --output text --query 'images[].imageManifest') - docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" \ - "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest-amd64" - docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" \ - "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest-arm64" + # Put the image with a new tag using the same manifest + aws ecr put-image --repository-name "${ECR_REPOSITORY}" \ + --image-manifest "$MANIFEST" \ + --image-tag "${VERSION_TAG_TO_APPLY}-amd64" + aws ecr put-image --repository-name "${ECR_REPOSITORY}" \ + --image-manifest "$MANIFEST" \ + --image-tag latest-amd64 - # Push the new tags - docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}-amd64" - docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}-arm64" + MANIFEST=$(aws ecr batch-get-image \ + --repository-name "${ECR_REPOSITORY}" \ + --image-ids imageTag="${IMAGE_TAG}-arm64" \ + --output text --query 'images[].imageManifest') - docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest-amd64" - docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest-arm64" + # Put the image with a new tag using the same manifest + aws ecr put-image --repository-name "${ECR_REPOSITORY}" \ + --image-manifest "$MANIFEST" \ + --image-tag "${VERSION_TAG_TO_APPLY}-arm64" + aws ecr put-image --repository-name "${ECR_REPOSITORY}" \ + --image-manifest "$MANIFEST" \ + --image-tag latest-arm64 - name: Verify multi-architecture manifest env: From 14ca9621271afc8902543e83b1565fdf5721ba97 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Fri, 24 Oct 2025 07:31:51 +0000 Subject: [PATCH 40/62] tag in right place --- .devcontainer/devcontainer.json | 1 - .github/workflows/pull_request.yml | 9 --------- .github/workflows/release.yml | 9 +++++++++ README.md | 3 ++- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index d62fc83..9806958 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -3,7 +3,6 @@ { "name": "Ubuntu", // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile - "image": "foo", "build": { "dockerfile": "Dockerfile", "context": "..", diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 0e30bae..0d36d75 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -87,15 +87,6 @@ jobs: secrets: PUSH_IMAGE_ROLE: ${{ secrets.PUSH_IMAGE_ROLE }} - tag_latest_dev_container: - needs: [quality_checks, get_issue_number_and_commit_id] - uses: ./.github/workflows/tag_latest_dev_container.yml - with: - dev_container_ecr: dev-container-quality-checks - dev_container_image_tag: PR-${{ needs.get_issue_number_and_commit_id.outputs.issue_number }}-${{ needs.get_issue_number_and_commit_id.outputs.sha_short }} - version_tag_to_apply: FooBar - secrets: - PUSH_IMAGE_ROLE: ${{ secrets.PUSH_IMAGE_ROLE }} tag_release: needs: [quality_checks, get_asdf_version] uses: NHSDigital/eps-workflow-semantic-release/.github/workflows/tag-release.yml@f80157cecce288dd175e61b477a1d2dbe9c88b99 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 65b8768..66cae30 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -63,3 +63,12 @@ jobs: publish_package: false tag_format: ${{ needs.get_asdf_version.outputs.tag_format }} secrets: inherit + tag_latest_dev_container: + needs: [quality_checks, get_commit_id, tag_release] + uses: ./.github/workflows/tag_latest_dev_container.yml + with: + dev_container_ecr: dev-container-quality-checks + dev_container_image_tag: release-${{ needs.get_commit_id.outputs.sha_short }} + version_tag_to_apply: ${{ needs.tag_release.outputs.version_tag }} + secrets: + PUSH_IMAGE_ROLE: ${{ secrets.PUSH_IMAGE_ROLE }} diff --git a/README.md b/README.md index b2271a1..7d76183 100644 --- a/README.md +++ b/README.md @@ -12,13 +12,14 @@ A workflow to run the quality checks for EPS repositories. The main element of t - **Validate CloudFormation Templates** (*Conditional*): If CloudFormation, AWS SAM templates or CDK are present, runs `cfn-lint` (SAM and cloudformation only) and `cfn-guard` to validate templates against AWS best practices and security rules. - **CDK Synth** (*Conditional*): Runs `make cdk-synth` if packages/cdk folder exists - **Check Licenses**: Runs `make check-licenses`. -- **Check Python Licenses** (*Conditional*): If the project uses Poetry, scans Python dependencies for incompatible licenses. +-- **Build dev containers**: Builds dev containers (for x64 and arm64 architecture), pushes to ECR and checks vulnerability scan results The secret scanning also has a dockerfile, which can be run against a repo in order to scan it manually (or as part of pre-commit hooks). This can be done like so: ```bash docker build -f https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/tags/v3.0.0/dockerfiles/nhsd-git-secrets.dockerfile -t git-secrets . docker run -v /path/to/repo:/src git-secrets --scan-history . ``` +Or it can be pulled from ECR For usage of the script, see the [source repo](https://github.com/NHSDigital/software-engineering-quality-framework/blob/main/tools/nhsd-git-secrets/git-secrets). Generally, you will either need `--scan -r .` or `--scan-history .`. The arguments default to `--scan -r .`, i.e. scanning the current state of the code. In order to enable the pre-commit hook for secret scanning (to prevent developers from committing secrets in the first place), add the following to the `.devcontainer/devcontainer.json` file: From a7af10420735dc9bb63581d439c8827524553dd0 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Fri, 24 Oct 2025 07:41:14 +0000 Subject: [PATCH 41/62] remove unused file --- .github/workflows/pull_request.yml | 6 +- .github/workflows/release.yml | 22 +++++- MULTI_ARCH_DOCKER.md | 123 ----------------------------- 3 files changed, 23 insertions(+), 128 deletions(-) delete mode 100644 MULTI_ARCH_DOCKER.md diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 0d36d75..8532e62 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -76,16 +76,16 @@ jobs: dev_container_image_tag: PR-${{ needs.get_issue_number_and_commit_id.outputs.issue_number }}-${{ needs.get_issue_number_and_commit_id.outputs.sha_short }} secrets: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - PUSH_IMAGE_ROLE: ${{ secrets.PUSH_IMAGE_ROLE }} + PUSH_IMAGE_ROLE: ${{ secrets.DEV_CONTAINER_PUSH_IMAGE_ROLE }} - build_nhsd_git_secrets_x64: + build_nhsd_git_secrets: uses: ./.github/workflows/build_nhsd_git_secrets.yml needs: [get_asdf_version, get_issue_number_and_commit_id] with: git_secrets_container_ecr: dev-container-quality-checks git_secrets_container_image_tag: PR-${{ needs.get_issue_number_and_commit_id.outputs.issue_number }}-${{ needs.get_issue_number_and_commit_id.outputs.sha_short }}-nhsd-git-secrets secrets: - PUSH_IMAGE_ROLE: ${{ secrets.PUSH_IMAGE_ROLE }} + PUSH_IMAGE_ROLE: ${{ secrets.DEV_CONTAINER_PUSH_IMAGE_ROLE }} tag_release: needs: [quality_checks, get_asdf_version] diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 66cae30..a268434 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -52,7 +52,15 @@ jobs: dev_container_image_tag: release-${{ needs.get_commit_id.outputs.sha_short }} secrets: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - PUSH_IMAGE_ROLE: ${{ secrets.PUSH_IMAGE_ROLE }} + PUSH_IMAGE_ROLE: ${{ secrets.DEV_CONTAINER_PUSH_IMAGE_ROLE }} + build_nhsd_git_secrets: + uses: ./.github/workflows/build_nhsd_git_secrets.yml + needs: [get_asdf_version, get_commit_id] + with: + git_secrets_container_ecr: dev-container-quality-checks + git_secrets_container_image_tag: release-${{ needs.get_commit_id.outputs.sha_short }} + secrets: + PUSH_IMAGE_ROLE: ${{ secrets.DEV_CONTAINER_PUSH_IMAGE_ROLE }} tag_release: needs: [quality_checks, get_asdf_version] uses: NHSDigital/eps-workflow-semantic-release/.github/workflows/tag-release.yml@f80157cecce288dd175e61b477a1d2dbe9c88b99 @@ -71,4 +79,14 @@ jobs: dev_container_image_tag: release-${{ needs.get_commit_id.outputs.sha_short }} version_tag_to_apply: ${{ needs.tag_release.outputs.version_tag }} secrets: - PUSH_IMAGE_ROLE: ${{ secrets.PUSH_IMAGE_ROLE }} + PUSH_IMAGE_ROLE: ${{ secrets.DEV_CONTAINER_PUSH_IMAGE_ROLE }} + + tag_latest_nhsd_git_secrets: + needs: [quality_checks, get_commit_id, tag_release] + uses: ./.github/workflows/tag_latest_dev_container.yml + with: + dev_container_ecr: dev-container-quality-checks + dev_container_image_tag: release-${{ needs.get_commit_id.outputs.sha_short }} + version_tag_to_apply: ${{ needs.tag_release.outputs.version_tag }} + secrets: + PUSH_IMAGE_ROLE: ${{ secrets.DEV_CONTAINER_PUSH_IMAGE_ROLE }} diff --git a/MULTI_ARCH_DOCKER.md b/MULTI_ARCH_DOCKER.md deleted file mode 100644 index 57303c9..0000000 --- a/MULTI_ARCH_DOCKER.md +++ /dev/null @@ -1,123 +0,0 @@ -# Multi-Architecture Docker Images (Separate Build Approach) - -This workflow builds multi-architecture Docker images by combining separate architecture-specific builds. This approach is more efficient than cross-compilation when you have native runners for each architecture. - -## How It Works - -### 1. Separate Architecture Builds -- **`build_dev_container_x64`**: Builds on `ubuntu-22.04` (native x64) -- **`build_dev_container_arm64`**: Builds on `ubuntu-22.04-arm` (native ARM64) - -Each job: -1. Builds the Docker image natively for its architecture -2. Pushes it to ECR with an architecture-specific tag (e.g., `:v1.0.0-amd64`, `:v1.0.0-arm64`) - -### 2. Multi-Architecture Manifest Creation -- **`create_multi_arch_manifest`**: Combines both images into a multi-arch manifest -- Uses `docker buildx imagetools create` to create a manifest list -- Creates both versioned tag (`:v1.0.0`) and `:latest` tag - -## Usage - -### To Build and Push Multi-Architecture Images - -Call the workflow with both required inputs: - -```yaml -uses: ./.github/workflows/quality-checks.yml -with: - dev_container_ecr: "your-repo-name" - dev_container_image_tag: "v1.0.0" - asdfVersion: "v0.10.2" -secrets: - CLOUD_FORMATION_DEPLOY_ROLE: ${{ secrets.CLOUD_FORMATION_DEPLOY_ROLE }} -``` - -This will: -1. Build x64 image → push as `:v1.0.0-amd64` -2. Build ARM64 image → push as `:v1.0.0-arm64` -3. Create manifest combining both → available as `:v1.0.0` and `:latest` - -### To Skip Multi-Architecture Build - -Call without ECR inputs to skip the container builds entirely: - -```yaml -uses: ./.github/workflows/quality-checks.yml -with: - asdfVersion: "v0.10.2" -``` - -## What Users Get - -Users can pull with a single command: -```bash -docker pull 123456789012.dkr.ecr.eu-west-2.amazonaws.com/your-repo:v1.0.0 -``` - -Docker automatically serves: -- `:v1.0.0-amd64` for Intel/AMD x64 systems -- `:v1.0.0-arm64` for ARM64 systems (Apple Silicon, ARM servers) - -## Benefits of This Approach - -✅ **Faster builds**: Native compilation is much faster than cross-compilation -✅ **Parallel execution**: Both architectures build simultaneously -✅ **Automatic platform detection**: Users get the right architecture transparently -✅ **Conditional execution**: Only runs when ECR inputs are provided -✅ **Security scanning**: Includes ECR vulnerability scanning -✅ **Verification**: Confirms multi-arch manifest was created correctly - -## Architecture Flow - -``` -┌─────────────────┐ ┌─────────────────┐ -│ build_x64 │ │ build_arm64 │ -│ (ubuntu-22.04) │ │ (ubuntu-22.04- │ -│ │ │ arm) │ -│ Build & Push │ │ Build & Push │ -│ :tag-amd64 │ │ :tag-arm64 │ -└─────────┬───────┘ └─────────┬───────┘ - │ │ - └──────────┬───────────┘ - │ - ┌────────────▼────────────┐ - │ create_multi_arch_ │ - │ manifest │ - │ (ubuntu-22.04) │ - │ │ - │ Combine into: │ - │ :tag (multi-arch) │ - │ :latest (multi-arch) │ - └─────────────────────────┘ -``` - -## Verification - -After the workflow completes, you can verify the multi-architecture manifest: - -```bash -# Check the manifest -docker buildx imagetools inspect 123456789012.dkr.ecr.eu-west-2.amazonaws.com/your-repo:v1.0.0 - -# Should show both architectures: -Name: 123456789012.dkr.ecr.eu-west-2.amazonaws.com/your-repo:v1.0.0 -MediaType: application/vnd.docker.distribution.manifest.list.v2+json - -Manifests: - Name: ...your-repo:v1.0.0@sha256:... - MediaType: application/vnd.docker.distribution.manifest.v2+json - Platform: linux/amd64 - - Name: ...your-repo:v1.0.0@sha256:... - MediaType: application/vnd.docker.distribution.manifest.v2+json - Platform: linux/arm64 -``` - -## Technical Details - -- **Job Dependencies**: `create_multi_arch_manifest` waits for both build jobs via `needs:` -- **Conditional Execution**: All container jobs only run when ECR inputs are provided -- **AWS Authentication**: Each job authenticates separately to AWS -- **Build Tools**: Uses Docker Buildx imagetools for manifest creation -- **Security**: 30-second delay before scanning allows ECR to process new images From 88acd30300099e4fc24cf007e4082bbe140ff989 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Fri, 24 Oct 2025 07:43:39 +0000 Subject: [PATCH 42/62] update readme --- README.md | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7d76183..1098102 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,46 @@ repos: ## Inputs -None +The workflow accepts the following input parameters: + +### `install_java` +- **Type**: boolean +- **Required**: false +- **Default**: false +- **Description**: If true, the action will install Java into the runner, separately from ASDF. + +### `run_sonar` +- **Type**: boolean +- **Required**: false +- **Default**: true +- **Description**: Toggle to run SonarCloud code analysis on this repository. + +### `asdfVersion` +- **Type**: string +- **Required**: true +- **Description**: The version of ASDF to use for managing runtime versions. + +### `reinstall_poetry` +- **Type**: boolean +- **Required**: false +- **Default**: false +- **Description**: Toggle to reinstall Poetry on top of the Python version installed by ASDF. + +### `dev_container_ecr` +- **Type**: string +- **Required**: true +- **Description**: The name of the ECR repository to push the dev container image to. + +### `dev_container_image_tag` +- **Type**: string +- **Required**: true +- **Description**: The tag to use for the dev container image. + +### `check_ecr_image_scan_results_script_tag` +- **Type**: string +- **Required**: false +- **Default**: "dev_container_build" +- **Description**: The tag to download the check_ecr_image_scan_results.sh script from. ## Required Makefile targets @@ -68,11 +107,17 @@ In order to run, these `make` commands must be present. They may be mocked, if t - `check-licenses` - `cdk-synth` - only needed if packages/cdk folder exists -## Environment variables +## Secrets + +The workflow requires the following secrets: ### `SONAR_TOKEN` +- **Required**: false +- **Description**: Required for the SonarCloud Scan step, which analyzes your code for quality and security issues using SonarCloud. -Required for the SonarCloud Scan step, which analyzes your code for quality and security issues using SonarCloud. +### `PUSH_IMAGE_ROLE` +- **Required**: true +- **Description**: AWS IAM role ARN used to authenticate and push dev container images to ECR. # Example Workflow Call @@ -90,6 +135,16 @@ on: jobs: quality_checks: uses: NHSDigital/eps-workflow-quality-checks/.github/workflows/quality-checks.yml@4.0.2 + with: + asdfVersion: "v0.14.1" + dev_container_ecr: "your-ecr-repo-name" + dev_container_image_tag: "latest" + # Optional inputs + install_java: false + run_sonar: true + reinstall_poetry: false + check_ecr_image_scan_results_script_tag: "dev_container_build" secrets: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + PUSH_IMAGE_ROLE: ${{ secrets.DEV_CONTAINER_PUSH_IMAGE_ROLE }} ``` From fe6a798a77248d3a8ad1be22708cdb008014f52c Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Fri, 24 Oct 2025 07:46:02 +0000 Subject: [PATCH 43/62] more updates to readme --- README.md | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 1098102..5f7a7b0 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,13 @@ # eps-workflow-quality-checks +This repository provides reusable GitHub Actions workflows for EPS repositories: -A workflow to run the quality checks for EPS repositories. The main element of this lives in the [`quality-checks.yml`](./.github/workflows/quality-checks.yml) configuration file. The steps executed by this workflow are as follows: +1. **Quality Checks Workflow** ([`quality-checks.yml`](./.github/workflows/quality-checks.yml)) - Comprehensive quality checks including linting, testing, security scanning, and dev container building +2. **Tag Latest Dev Container Workflow** ([`tag_latest_dev_container.yml`](./.github/workflows/tag_latest_dev_container.yml)) - Tags dev container images with version and latest tags + +## Quality Checks Workflow + +The main quality checks workflow runs comprehensive checks for EPS repositories. The steps executed by this workflow are as follows: - **Install Project Dependencies** - **Generate and Check SBOMs**: Creates Software Bill of Materials (SBOMs) to track dependencies for security and compliance. Uses [THIS](https://github.com/NHSDigital/eps-action-sbom) action. @@ -52,7 +58,7 @@ repos: language: system ``` -# Usage +# Quality Checks Workflow Usage ## Inputs @@ -119,7 +125,7 @@ The workflow requires the following secrets: - **Required**: true - **Description**: AWS IAM role ARN used to authenticate and push dev container images to ECR. -# Example Workflow Call +## Example Workflow Call To use this workflow in your repository, call it from another workflow file: @@ -148,3 +154,57 @@ jobs: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} PUSH_IMAGE_ROLE: ${{ secrets.DEV_CONTAINER_PUSH_IMAGE_ROLE }} ``` + +# Tag Latest Dev Container Workflow + +This repository also provides a reusable workflow [`tag_latest_dev_container.yml`](./.github/workflows/tag_latest_dev_container.yml) for tagging dev container images with version tags and `latest` in ECR. + +## Purpose + +This workflow takes existing dev container images (built for both x64 and arm64 architectures) and applies additional tags to them, including: +- A custom version tag (e.g., `v1.0.0`) +- The `latest` tag +- Architecture-specific tags (e.g., `v1.0.0-amd64`, `latest-arm64`) + +## Inputs + +### `dev_container_ecr` +- **Type**: string +- **Required**: true +- **Description**: The name of the ECR repository containing the dev container images. + +### `dev_container_image_tag` +- **Type**: string +- **Required**: true +- **Description**: The current tag of the dev container images to be re-tagged (should exist for both `-amd64` and `-arm64` suffixes). + +### `version_tag_to_apply` +- **Type**: string +- **Required**: true +- **Description**: The version tag to apply to the dev container images (e.g., `v1.0.0`). + +## Secrets + +### `PUSH_IMAGE_ROLE` +- **Required**: true +- **Description**: AWS IAM role ARN used to authenticate and push images to ECR. + +## Example Usage + +```yaml +name: Tag Dev Container as Latest + +on: + release: + types: [published] + +jobs: + tag_dev_container: + uses: NHSDigital/eps-workflow-quality-checks/.github/workflows/tag_latest_dev_container.yml@main + with: + dev_container_ecr: "your-ecr-repo-name" + dev_container_image_tag: "build-123" # The tag created by quality-checks workflow + version_tag_to_apply: ${{ github.event.release.tag_name }} + secrets: + PUSH_IMAGE_ROLE: ${{ secrets.DEV_CONTAINER_PUSH_IMAGE_ROLE }} +``` From cd694365993c194d655f0356542be4eeb8604e54 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Fri, 24 Oct 2025 08:03:24 +0000 Subject: [PATCH 44/62] update readme --- .github/workflows/pull_request.yml | 2 +- .github/workflows/release.yml | 2 +- README.md | 93 +++++++++++++++++------------- 3 files changed, 54 insertions(+), 43 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 8532e62..3b2c64c 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -82,7 +82,7 @@ jobs: uses: ./.github/workflows/build_nhsd_git_secrets.yml needs: [get_asdf_version, get_issue_number_and_commit_id] with: - git_secrets_container_ecr: dev-container-quality-checks + git_secrets_container_ecr: dev-container-git-secrets git_secrets_container_image_tag: PR-${{ needs.get_issue_number_and_commit_id.outputs.issue_number }}-${{ needs.get_issue_number_and_commit_id.outputs.sha_short }}-nhsd-git-secrets secrets: PUSH_IMAGE_ROLE: ${{ secrets.DEV_CONTAINER_PUSH_IMAGE_ROLE }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a268434..9bce146 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -85,7 +85,7 @@ jobs: needs: [quality_checks, get_commit_id, tag_release] uses: ./.github/workflows/tag_latest_dev_container.yml with: - dev_container_ecr: dev-container-quality-checks + dev_container_ecr: dev-container-git-secrets dev_container_image_tag: release-${{ needs.get_commit_id.outputs.sha_short }} version_tag_to_apply: ${{ needs.tag_release.outputs.version_tag }} secrets: diff --git a/README.md b/README.md index 5f7a7b0..1866947 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ This repository provides reusable GitHub Actions workflows for EPS repositories: 1. **Quality Checks Workflow** ([`quality-checks.yml`](./.github/workflows/quality-checks.yml)) - Comprehensive quality checks including linting, testing, security scanning, and dev container building 2. **Tag Latest Dev Container Workflow** ([`tag_latest_dev_container.yml`](./.github/workflows/tag_latest_dev_container.yml)) - Tags dev container images with version and latest tags +It also contains a dockerfile that builds an image that contains git-secrets which is used in pre-commit hooks in EPS repositories + ## Quality Checks Workflow The main quality checks workflow runs comprehensive checks for EPS repositories. The steps executed by this workflow are as follows: @@ -20,43 +22,6 @@ The main quality checks workflow runs comprehensive checks for EPS repositories. - **Check Licenses**: Runs `make check-licenses`. -- **Build dev containers**: Builds dev containers (for x64 and arm64 architecture), pushes to ECR and checks vulnerability scan results -The secret scanning also has a dockerfile, which can be run against a repo in order to scan it manually (or as part of pre-commit hooks). This can be done like so: -```bash -docker build -f https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/tags/v3.0.0/dockerfiles/nhsd-git-secrets.dockerfile -t git-secrets . -docker run -v /path/to/repo:/src git-secrets --scan-history . -``` -Or it can be pulled from ECR -For usage of the script, see the [source repo](https://github.com/NHSDigital/software-engineering-quality-framework/blob/main/tools/nhsd-git-secrets/git-secrets). Generally, you will either need `--scan -r .` or `--scan-history .`. The arguments default to `--scan -r .`, i.e. scanning the current state of the code. - -In order to enable the pre-commit hook for secret scanning (to prevent developers from committing secrets in the first place), add the following to the `.devcontainer/devcontainer.json` file: -```json -{ - "remoteEnv": { "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}" }, - "postAttachCommand": "docker build -f https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/tags/v4.0.2/dockerfiles/nhsd-git-secrets.dockerfile -t git-secrets . && pre-commit install --install-hooks -f", - "features": { - "ghcr.io/devcontainers/features/docker-outside-of-docker:1": { - "version": "latest", - "moby": "true", - "installDockerBuildx": "true" - } - } -} -``` - -And the this pre-commit hook to the `.pre-commit-config.yaml` file: -```yaml -repos: -- repo: local - hooks: - - id: git-secrets - name: Git Secrets - description: git-secrets scans commits, commit messages, and --no-ff merges to prevent adding secrets into your git repositories. - entry: bash - args: - - -c - - 'docker run -v "$LOCAL_WORKSPACE_FOLDER:/src" git-secrets --pre_commit_hook' - language: system -``` # Quality Checks Workflow Usage @@ -100,8 +65,8 @@ The workflow accepts the following input parameters: ### `check_ecr_image_scan_results_script_tag` - **Type**: string - **Required**: false -- **Default**: "dev_container_build" -- **Description**: The tag to download the check_ecr_image_scan_results.sh script from. +- **Default**: "main" +- **Description**: The git ref to download the check_ecr_image_scan_results.sh script from. ## Required Makefile targets @@ -203,8 +168,54 @@ jobs: uses: NHSDigital/eps-workflow-quality-checks/.github/workflows/tag_latest_dev_container.yml@main with: dev_container_ecr: "your-ecr-repo-name" - dev_container_image_tag: "build-123" # The tag created by quality-checks workflow - version_tag_to_apply: ${{ github.event.release.tag_name }} + dev_container_image_tag: release-${{ needs.get_commit_id.outputs.sha_short }} # The tag applied as part of the quality-checks workflow + version_tag_to_apply: ${{ needs.tag_release.outputs.version_tag }} # The git tag created by tag_release workflow secrets: PUSH_IMAGE_ROLE: ${{ secrets.DEV_CONTAINER_PUSH_IMAGE_ROLE }} ``` + +## Git secrets +There is a dockerfile at ([`nhsd-git-secrets.dockerfile`](./dockerfiles/nhsd-git-secrets.dockerfile)) that builds a docker image that is used to run git secrets. This image is pushed to ECR as part of this projects release pipeline. +This can be manually built and used to scan manually (or as part of pre-commit hooks). +```bash +docker build -f https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/tags/v3.0.0/dockerfiles/nhsd-git-secrets.dockerfile -t git-secrets . +docker run -v /path/to/repo:/src git-secrets --scan-history . +``` +Or it can be pulled from ECR +```bash +export AWS_PROFILE=prescription-dev +aws sso login --sso-session sso-session +aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin 591291862413.dkr.ecr.eu-west-2.amazonaws.com +docker pull 591291862413.dkr.ecr.eu-west-2.amazonaws.com/dev-container-git-secrets:latest +``` +For usage of the script, see the [source repo](https://github.com/NHSDigital/software-engineering-quality-framework/blob/main/tools/nhsd-git-secrets/git-secrets). Generally, you will either need `--scan -r .` or `--scan-history .`. The arguments default to `--scan -r .`, i.e. scanning the current state of the code. + +In order to enable the pre-commit hook for secret scanning (to prevent developers from committing secrets in the first place), add the following to the `.devcontainer/devcontainer.json` file: +```json +{ + "remoteEnv": { "LOCAL_WORKSPACE_FOLDER": "${localWorkspaceFolder}" }, + "postAttachCommand": "docker build -f https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/tags/v4.0.2/dockerfiles/nhsd-git-secrets.dockerfile -t git-secrets . && pre-commit install --install-hooks -f", + "features": { + "ghcr.io/devcontainers/features/docker-outside-of-docker:1": { + "version": "latest", + "moby": "true", + "installDockerBuildx": "true" + } + } +} +``` + +And the this pre-commit hook to the `.pre-commit-config.yaml` file: +```yaml +repos: +- repo: local + hooks: + - id: git-secrets + name: Git Secrets + description: git-secrets scans commits, commit messages, and --no-ff merges to prevent adding secrets into your git repositories. + entry: bash + args: + - -c + - 'docker run -v "$LOCAL_WORKSPACE_FOLDER:/src" git-secrets --pre_commit_hook' + language: system +``` From f99b3f52f78491cf5a7afaeeae1662c5601b61c1 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Fri, 24 Oct 2025 08:18:31 +0000 Subject: [PATCH 45/62] update readme --- .github/workflows/quality-checks.yml | 4 ++-- README.md | 15 +++++++++------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index d848edc..15542d4 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -209,10 +209,10 @@ jobs: run: make lint - name: actionlint - uses: raven-actions/actionlint@v2 + uses: raven-actions/actionlint@3a24062651993d40fed1019b58ac6fbdfbf276cc - name: Run ShellCheck - uses: ludeeus/action-shellcheck@master + uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 with: ignore_paths: >- *test* diff --git a/README.md b/README.md index 1866947..102b53e 100644 --- a/README.md +++ b/README.md @@ -11,15 +11,18 @@ It also contains a dockerfile that builds an image that contains git-secrets whi The main quality checks workflow runs comprehensive checks for EPS repositories. The steps executed by this workflow are as follows: +- **Scan git history for secrets**: Scans for secret-like patterns, using https://github.com/NHSDigital/software-engineering-quality-framework/blob/main/tools/nhsd-git-secrets/git-secrets - **Install Project Dependencies** +- **Check Licenses**: Runs `make check-licenses`. +- **Run Linting** Runs `make lint`. +- **Run actionlint** Runs actionlint using [actionlint](https://github.com/raven-actions/actionlint) +- **Run shellcheck**: Runs shellcheck using [action-shellcheck](https://github.com/ludeeus/action-shellcheck) +- **Run cfn-lint** Runs [cfn-lint](https://github.com/aws-cloudformation/cfn-lint) against files in cloudformation and SAMtemplates folders +- **Run Unit Tests** Runs `make test`. +- **CDK Synth** (*Conditional*): Runs `make cdk-synth` if packages/cdk folder exists +- **Run cloudformation-guard** (*Conditional*): Runs [cfn-guard](https://github.com/aws-cloudformation/cloudformation-guard) if CloudFormation, AWS SAM templates or CDK are present - **Generate and Check SBOMs**: Creates Software Bill of Materials (SBOMs) to track dependencies for security and compliance. Uses [THIS](https://github.com/NHSDigital/eps-action-sbom) action. -- **Run Linting** -- **Run Unit Tests** -- **Scan git history for secrets**: Scans for secret-like patterns, using https://github.com/NHSDigital/software-engineering-quality-framework/blob/main/tools/nhsd-git-secrets/git-secrets - **SonarCloud Scan**: Performs code analysis using SonarCloud to detect quality issues and vulnerabilities. -- **Validate CloudFormation Templates** (*Conditional*): If CloudFormation, AWS SAM templates or CDK are present, runs `cfn-lint` (SAM and cloudformation only) and `cfn-guard` to validate templates against AWS best practices and security rules. -- **CDK Synth** (*Conditional*): Runs `make cdk-synth` if packages/cdk folder exists -- **Check Licenses**: Runs `make check-licenses`. -- **Build dev containers**: Builds dev containers (for x64 and arm64 architecture), pushes to ECR and checks vulnerability scan results From 7a7a5bd902fcbd68ec01c456396b61e4d56444e0 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Fri, 24 Oct 2025 10:45:28 +0000 Subject: [PATCH 46/62] trigger build From f19a2b8ff231feec2cf04c4c96cc37f310022048 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Fri, 24 Oct 2025 10:59:30 +0000 Subject: [PATCH 47/62] use local script for build git secrets --- .github/workflows/build_nhsd_git_secrets.yml | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/.github/workflows/build_nhsd_git_secrets.yml b/.github/workflows/build_nhsd_git_secrets.yml index 6af8313..5fcd925 100644 --- a/.github/workflows/build_nhsd_git_secrets.yml +++ b/.github/workflows/build_nhsd_git_secrets.yml @@ -32,12 +32,6 @@ jobs: with: fetch-depth: 0 - - name: Download check_ecr_image_scan_results.sh script - env: - SCRIPT_TAG: ${{ inputs.check_ecr_image_scan_results_script_tag }} - run: | - curl -L "https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/heads/${SCRIPT_TAG}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh - chmod +x check_ecr_image_scan_results.sh - name: Build dev container run: | docker build -f dockerfiles/nhsd-git-secrets.dockerfile -t nhsd-git-secrets-image . @@ -76,7 +70,7 @@ jobs: ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} run: | sleep 30 - ./check_ecr_image_scan_results.sh + ./.github/scripts/check_ecr_image_scan_results.sh build_nhsd_git_secrets_arm64: permissions: @@ -88,13 +82,6 @@ jobs: with: fetch-depth: 0 - - name: Download check_ecr_image_scan_results.sh script - env: - SCRIPT_TAG: ${{ inputs.check_ecr_image_scan_results_script_tag }} - run: | - curl -L "https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/heads/${SCRIPT_TAG}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh - chmod +x check_ecr_image_scan_results.sh - - name: Build dev container run: | docker build -f dockerfiles/nhsd-git-secrets.dockerfile -t nhsd-git-secrets-image-arm . @@ -134,7 +121,7 @@ jobs: run: | # Wait a moment for ECR to process the new manifest sleep 30 - ./check_ecr_image_scan_results.sh + ./.github/scripts/check_ecr_image_scan_results.sh create_multi_arch_manifest: permissions: From 66ee78b80e4733e5c80df61e7c1fc9c9284502de Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Fri, 24 Oct 2025 17:32:50 +0000 Subject: [PATCH 48/62] better cfn guard init --- .github/workflows/quality-checks.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 2d8edb5..fd7e215 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -248,11 +248,10 @@ jobs: rm -rf /tmp/ruleset rm -rf cfn_guard_output - wget -O /tmp/ruleset.zip https://github.com/aws-cloudformation/aws-guard-rules-registry/releases/download/1.0.2/ruleset-build-v1.0.2.zip >/dev/null 2>&1 - unzip /tmp/ruleset.zip -d /tmp/ruleset/ >/dev/null 2>&1 - - curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/aws-cloudformation/cloudformation-guard/main/install-guard.sh | sh >/dev/null 2>&1 - + wget -O /tmp/ruleset.zip https://github.com/aws-cloudformation/aws-guard-rules-registry/releases/download/1.0.2/ruleset-build-v1.0.2.zip + unzip /tmp/ruleset.zip -d /tmp/ruleset/ + curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/aws-cloudformation/cloudformation-guard/main/install-guard.sh -o /tmp/install-guard.sh + sh /tmp/install-guard.sh mkdir -p cfn_guard_output - name: Run cfn-guard script for sam templates @@ -317,7 +316,7 @@ jobs: - name: Download terraform plans uses: actions/download-artifact@v5 with: - pattern: '*_terraform_plan' + pattern: "*_terraform_plan" path: terraform_plans/ merge-multiple: true @@ -332,7 +331,7 @@ jobs: ls -l terraform_plans/ echo "terraform_plans_exist=true" >> "$GITHUB_OUTPUT" fi - + - name: Run cfn-guard script for terraform plans if: steps.check_terraform_plans.outputs.terraform_plans_exist == 'true' run: | From 7d1908d60cffeb131888f46ab8ae946caa7e95a5 Mon Sep 17 00:00:00 2001 From: Anthony Brown <121869075+anthony-nhs@users.noreply.github.com> Date: Wed, 12 Nov 2025 19:32:53 +0000 Subject: [PATCH 49/62] changes following feedback --- .github/workflows/build_nhsd_git_secrets.yml | 5 - .github/workflows/release.yml | 12 +- .../workflows/tag_latest_container_images.yml | 104 ++++++++++++++++++ .../workflows/tag_latest_dev_container.yml | 104 ------------------ 4 files changed, 110 insertions(+), 115 deletions(-) create mode 100644 .github/workflows/tag_latest_container_images.yml delete mode 100644 .github/workflows/tag_latest_dev_container.yml diff --git a/.github/workflows/build_nhsd_git_secrets.yml b/.github/workflows/build_nhsd_git_secrets.yml index 5fcd925..d04f149 100644 --- a/.github/workflows/build_nhsd_git_secrets.yml +++ b/.github/workflows/build_nhsd_git_secrets.yml @@ -16,11 +16,6 @@ on: type: string description: "The tag to use for the dev container image." required: true - check_ecr_image_scan_results_script_tag: - type: string - description: "The tag to download check_ecr_image_scan_results.sh script." - required: false - default: "dev_container_build" jobs: build_nhsd_git_secrets_x64: permissions: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8447698..2a436d7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -73,20 +73,20 @@ jobs: secrets: inherit tag_latest_dev_container: needs: [quality_checks, get_commit_id, tag_release] - uses: ./.github/workflows/tag_latest_dev_container.yml + uses: ./.github/workflows/tag_latest_container_images.yml with: - dev_container_ecr: dev-container-quality-checks - dev_container_image_tag: release-${{ needs.get_commit_id.outputs.sha_short }} + ecr_name: dev-container-quality-checks + container_image_tag: release-${{ needs.get_commit_id.outputs.sha_short }} version_tag_to_apply: ${{ needs.tag_release.outputs.version_tag }} secrets: PUSH_IMAGE_ROLE: ${{ secrets.DEV_CONTAINER_PUSH_IMAGE_ROLE }} tag_latest_nhsd_git_secrets: needs: [quality_checks, get_commit_id, tag_release] - uses: ./.github/workflows/tag_latest_dev_container.yml + uses: ./.github/workflows/tag_latest_container_images.yml with: - dev_container_ecr: dev-container-git-secrets - dev_container_image_tag: release-${{ needs.get_commit_id.outputs.sha_short }} + ecr_name: git-secrets + container_image_tag: release-${{ needs.get_commit_id.outputs.sha_short }} version_tag_to_apply: ${{ needs.tag_release.outputs.version_tag }} secrets: PUSH_IMAGE_ROLE: ${{ secrets.DEV_CONTAINER_PUSH_IMAGE_ROLE }} diff --git a/.github/workflows/tag_latest_container_images.yml b/.github/workflows/tag_latest_container_images.yml new file mode 100644 index 0000000..b7382fd --- /dev/null +++ b/.github/workflows/tag_latest_container_images.yml @@ -0,0 +1,104 @@ +name: Tag Latest container images + +on: + workflow_call: + secrets: + PUSH_IMAGE_ROLE: + required: true + inputs: + ecr_name: + type: string + description: "The name of the ECR repository to push the dev container image to." + required: true + container_image_tag: + type: string + description: "The tag to use for the dev container image." + required: true + version_tag_to_apply: + type: string + description: "The version tag to apply to the latest dev container image." + required: true +jobs: + tag_latest_container_images: + permissions: + id-token: write + runs-on: ubuntu-22.04 + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 + with: + aws-region: eu-west-2 + role-to-assume: ${{ secrets.PUSH_IMAGE_ROLE }} + role-session-name: multi-arch-manifest + output-credentials: true + + - name: Retrieve AWS Account ID + id: retrieve-deploy-account-id + run: | + ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) + echo "account_id=$ACCOUNT_ID" >> "$GITHUB_OUTPUT" + + - name: Login to Amazon ECR + run: | + aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com + + - name: Create and push multi-architecture manifest for tag + env: + ECR_REPOSITORY: ${{ inputs.ecr_name }} + IMAGE_TAG: ${{ inputs.container_image_tag }} + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + VERSION_TAG_TO_APPLY: ${{ inputs.version_tag_to_apply }} + run: | + # Create manifest list combining both architectures + docker buildx imagetools create -t "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" + docker buildx imagetools create -t "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" + + - name: Tag images for individual architectures + env: + ECR_REPOSITORY: ${{ inputs.ecr_name }} + IMAGE_TAG: ${{ inputs.container_image_tag }} + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + VERSION_TAG_TO_APPLY: ${{ inputs.version_tag_to_apply }} + run: | + # Get the image manifest + MANIFEST=$(aws ecr batch-get-image \ + --repository-name "${ECR_REPOSITORY}" \ + --image-ids imageTag="${IMAGE_TAG}-amd64" \ + --output text --query 'images[].imageManifest') + + # Put the image with a new tag using the same manifest + aws ecr put-image --repository-name "${ECR_REPOSITORY}" \ + --image-manifest "$MANIFEST" \ + --image-tag "${VERSION_TAG_TO_APPLY}-amd64" + aws ecr put-image --repository-name "${ECR_REPOSITORY}" \ + --image-manifest "$MANIFEST" \ + --image-tag latest-amd64 + + MANIFEST=$(aws ecr batch-get-image \ + --repository-name "${ECR_REPOSITORY}" \ + --image-ids imageTag="${IMAGE_TAG}-arm64" \ + --output text --query 'images[].imageManifest') + + # Put the image with a new tag using the same manifest + aws ecr put-image --repository-name "${ECR_REPOSITORY}" \ + --image-manifest "$MANIFEST" \ + --image-tag "${VERSION_TAG_TO_APPLY}-arm64" + aws ecr put-image --repository-name "${ECR_REPOSITORY}" \ + --image-manifest "$MANIFEST" \ + --image-tag latest-arm64 + + - name: Verify multi-architecture manifest + env: + ECR_REPOSITORY: ${{ inputs.ecr_name }} + IMAGE_TAG: ${{ inputs.container_image_tag }} + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + run: | + echo "=== Verifying multi-architecture manifest ===" + docker buildx imagetools inspect "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest" diff --git a/.github/workflows/tag_latest_dev_container.yml b/.github/workflows/tag_latest_dev_container.yml deleted file mode 100644 index c08f065..0000000 --- a/.github/workflows/tag_latest_dev_container.yml +++ /dev/null @@ -1,104 +0,0 @@ -name: Tag Latest Dev Container - -on: - workflow_call: - secrets: - PUSH_IMAGE_ROLE: - required: true - inputs: - dev_container_ecr: - type: string - description: "The name of the ECR repository to push the dev container image to." - required: true - dev_container_image_tag: - type: string - description: "The tag to use for the dev container image." - required: true - version_tag_to_apply: - type: string - description: "The version tag to apply to the latest dev container image." - required: true -jobs: - tag_latest_dev_container: - permissions: - id-token: write - runs-on: ubuntu-22.04 - steps: - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 - - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 - with: - aws-region: eu-west-2 - role-to-assume: ${{ secrets.PUSH_IMAGE_ROLE }} - role-session-name: multi-arch-manifest - output-credentials: true - - - name: Retrieve AWS Account ID - id: retrieve-deploy-account-id - run: | - ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) - echo "account_id=$ACCOUNT_ID" >> "$GITHUB_OUTPUT" - - - name: Login to Amazon ECR - run: | - aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com - - - name: Create and push multi-architecture manifest for tag - env: - ECR_REPOSITORY: ${{ inputs.dev_container_ecr }} - IMAGE_TAG: ${{ inputs.dev_container_image_tag }} - ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} - VERSION_TAG_TO_APPLY: ${{ inputs.version_tag_to_apply }} - run: | - # Create manifest list combining both architectures - docker buildx imagetools create -t "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest" \ - "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" \ - "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" - docker buildx imagetools create -t "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${VERSION_TAG_TO_APPLY}" \ - "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" \ - "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" - - - name: Tag images for individual architectures - env: - ECR_REPOSITORY: ${{ inputs.dev_container_ecr }} - IMAGE_TAG: ${{ inputs.dev_container_image_tag }} - ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} - VERSION_TAG_TO_APPLY: ${{ inputs.version_tag_to_apply }} - run: | - # Get the image manifest - MANIFEST=$(aws ecr batch-get-image \ - --repository-name "${ECR_REPOSITORY}" \ - --image-ids imageTag="${IMAGE_TAG}-amd64" \ - --output text --query 'images[].imageManifest') - - # Put the image with a new tag using the same manifest - aws ecr put-image --repository-name "${ECR_REPOSITORY}" \ - --image-manifest "$MANIFEST" \ - --image-tag "${VERSION_TAG_TO_APPLY}-amd64" - aws ecr put-image --repository-name "${ECR_REPOSITORY}" \ - --image-manifest "$MANIFEST" \ - --image-tag latest-amd64 - - MANIFEST=$(aws ecr batch-get-image \ - --repository-name "${ECR_REPOSITORY}" \ - --image-ids imageTag="${IMAGE_TAG}-arm64" \ - --output text --query 'images[].imageManifest') - - # Put the image with a new tag using the same manifest - aws ecr put-image --repository-name "${ECR_REPOSITORY}" \ - --image-manifest "$MANIFEST" \ - --image-tag "${VERSION_TAG_TO_APPLY}-arm64" - aws ecr put-image --repository-name "${ECR_REPOSITORY}" \ - --image-manifest "$MANIFEST" \ - --image-tag latest-arm64 - - - name: Verify multi-architecture manifest - env: - ECR_REPOSITORY: ${{ inputs.dev_container_ecr }} - IMAGE_TAG: ${{ inputs.dev_container_image_tag }} - ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} - run: | - echo "=== Verifying multi-architecture manifest ===" - docker buildx imagetools inspect "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:latest" From ca0b67d08063431f8ff3917f0c18a5ac1f3c3d0f Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Fri, 21 Nov 2025 12:28:31 +0000 Subject: [PATCH 50/62] add it back in --- .github/workflows/quality-checks.yml | 161 +++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index bf591b9..e2a3a42 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -419,3 +419,164 @@ jobs: with: name: cfn_guard_output path: cfn_guard_output + + build_dev_container_x64: + permissions: + id-token: write + runs-on: ubuntu-22.04 + steps: + - name: Checkout code + uses: actions/checkout@v5 + with: + fetch-depth: 0 + + - name: Download check_ecr_image_scan_results.sh script + env: + SCRIPT_TAG: ${{ inputs.check_ecr_image_scan_results_script_tag }} + run: | + curl -L "https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/heads/${SCRIPT_TAG}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh + chmod +x check_ecr_image_scan_results.sh + - name: Build dev container + run: | + docker build -f .devcontainer/Dockerfile -t dev-container-image . + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 + id: connect-aws-deploy + with: + aws-region: eu-west-2 + role-to-assume: ${{ secrets.PUSH_IMAGE_ROLE }} + role-session-name: dev-container-build-x64 + output-credentials: true + + - name: Retrieve AWS Account ID + id: retrieve-deploy-account-id + run: | + ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) + echo "account_id=$ACCOUNT_ID" >> "$GITHUB_OUTPUT" + + - name: Login to Amazon ECR + run: | + aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com + + - name: Push x64 image to Amazon ECR + env: + ECR_REPOSITORY: ${{ inputs.dev_container_ecr }} + IMAGE_TAG: ${{ inputs.dev_container_image_tag }} + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + run: | + docker tag "dev-container-image" "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" + docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" + - name: Check dev container scan results + env: + REPOSITORY_NAME: ${{ inputs.dev_container_ecr }} + IMAGE_TAG: ${{ inputs.dev_container_image_tag }}-amd64 + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + run: | + sleep 30 + ./check_ecr_image_scan_results.sh + + build_dev_container_arm64: + permissions: + id-token: write + runs-on: ubuntu-22.04-arm + steps: + - name: Checkout code + uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 + with: + fetch-depth: 0 + + - name: Download check_ecr_image_scan_results.sh script + env: + SCRIPT_TAG: ${{ inputs.check_ecr_image_scan_results_script_tag }} + run: | + curl -L "https://raw.githubusercontent.com/NHSDigital/eps-common-workflows/refs/heads/${SCRIPT_TAG}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh + chmod +x check_ecr_image_scan_results.sh + + - name: Build dev container + run: | + docker build -f .devcontainer/Dockerfile -t dev-container-image-arm . + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 + id: connect-aws-deploy + with: + aws-region: eu-west-2 + role-to-assume: ${{ secrets.PUSH_IMAGE_ROLE }} + role-session-name: dev-container-build-arm64 + output-credentials: true + + - name: Retrieve AWS Account ID + id: retrieve-deploy-account-id + run: | + ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) + echo "account_id=$ACCOUNT_ID" >> "$GITHUB_OUTPUT" + + - name: Login to Amazon ECR + run: | + aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com + + - name: Push ARM64 image to Amazon ECR + env: + ECR_REPOSITORY: ${{ inputs.dev_container_ecr }} + IMAGE_TAG: ${{ inputs.dev_container_image_tag }} + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + run: | + docker tag "dev-container-image-arm" "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" + docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" + - name: Check dev container scan results + env: + REPOSITORY_NAME: ${{ inputs.dev_container_ecr }} + IMAGE_TAG: ${{ inputs.dev_container_image_tag }}-arm64 + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + run: | + # Wait a moment for ECR to process the new manifest + sleep 30 + ./check_ecr_image_scan_results.sh + + create_multi_arch_manifest: + permissions: + id-token: write + runs-on: ubuntu-22.04 + needs: [build_dev_container_x64, build_dev_container_arm64] + steps: + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 + with: + aws-region: eu-west-2 + role-to-assume: ${{ secrets.PUSH_IMAGE_ROLE }} + role-session-name: multi-arch-manifest + output-credentials: true + + - name: Retrieve AWS Account ID + id: retrieve-deploy-account-id + run: | + ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) + echo "account_id=$ACCOUNT_ID" >> "$GITHUB_OUTPUT" + + - name: Login to Amazon ECR + run: | + aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com + + - name: Create and push multi-architecture manifest for tag + env: + ECR_REPOSITORY: ${{ inputs.dev_container_ecr }} + IMAGE_TAG: ${{ inputs.dev_container_image_tag }} + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + run: | + # Create manifest list combining both architectures + docker buildx imagetools create -t "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" \ + "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" + + - name: Verify multi-architecture manifest + env: + ECR_REPOSITORY: ${{ inputs.dev_container_ecr }} + IMAGE_TAG: ${{ inputs.dev_container_image_tag }} + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + run: | + echo "=== Verifying multi-architecture manifest ===" + docker buildx imagetools inspect "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}" From 3bdce193b63ec5b806418ae0ef05a501207f0d1a Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Fri, 21 Nov 2025 14:32:12 +0000 Subject: [PATCH 51/62] fix ecr name --- .github/workflows/pull_request.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 2dd6724..2f7f77a 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -87,7 +87,7 @@ jobs: uses: ./.github/workflows/build_nhsd_git_secrets.yml needs: [get_asdf_version, get_issue_number_and_commit_id] with: - git_secrets_container_ecr: dev-container-git-secrets + git_secrets_container_ecr: git-secrets git_secrets_container_image_tag: PR-${{ needs.get_issue_number_and_commit_id.outputs.issue_number }}-${{ needs.get_issue_number_and_commit_id.outputs.sha_short }}-nhsd-git-secrets secrets: PUSH_IMAGE_ROLE: ${{ secrets.DEV_CONTAINER_PUSH_IMAGE_ROLE }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3079a53..d03b388 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -57,7 +57,7 @@ jobs: uses: ./.github/workflows/build_nhsd_git_secrets.yml needs: [get_asdf_version, get_commit_id] with: - git_secrets_container_ecr: dev-container-quality-checks + git_secrets_container_ecr: git-secrets git_secrets_container_image_tag: release-${{ needs.get_commit_id.outputs.sha_short }} secrets: PUSH_IMAGE_ROLE: ${{ secrets.DEV_CONTAINER_PUSH_IMAGE_ROLE }} From e0488279fce299ba58f34987b2b55f046eb625c6 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Fri, 21 Nov 2025 17:12:47 +0000 Subject: [PATCH 52/62] use correct path --- .github/actions/get_called_ref/action.yml | 27 +++++++++++++++++++++++ .github/workflows/quality-checks.yml | 16 ++++++++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 .github/actions/get_called_ref/action.yml diff --git a/.github/actions/get_called_ref/action.yml b/.github/actions/get_called_ref/action.yml new file mode 100644 index 0000000..d4bf70b --- /dev/null +++ b/.github/actions/get_called_ref/action.yml @@ -0,0 +1,27 @@ +name: Get called workflow ref + +description: > + A workaround to the issue: https://github.com/actions/toolkit/issues/1264. + + This is needed for the reusable workflow to be able to access its own version (commit hash) + that is being called by the caller workflow. This allows for using a proper ref of composite actions + inside the reusable workflow. +inputs: + GH_TOKEN_ADMIN: + required: true + description: 'GitHub token with admin permissions to access workflow run details.' + +outputs: + caller-ref: + description: 'The reference (commit hash or branch) of the called workflow' + value: ${{ steps.workflows-ref.outputs.caller-ref }} + +runs: + using: composite + steps: + - name: Get workflow reference + id: workflows-ref + shell: bash + run: | + ref=$(curl -L -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${{ inputs.GH_TOKEN_ADMIN }}" -H "X-GitHub-Api-Version: 2022-11-28" https://api.github.com/repos/${{ github.repository }}/actions/runs/${{ github.run_id }} | jq -r '.referenced_workflows[0] | .ref') + echo "caller-ref=$ref" >> $GITHUB_OUTPUT diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index e2a3a42..d49a1cf 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -39,6 +39,16 @@ on: required: false default: "dev_container_build" jobs: + get-called-ref: + name: Get called ref + runs-on: ubuntu-latest + outputs: + ref: ${{ steps.get_called_ref.outputs.caller-ref }} + steps: + - id: get_called_ref + uses: NHSDigital/eps-common-workflows/.github/actions/get_called_ref@dev_container_build + with: + GH_TOKEN_ADMIN: ${{ secrets.GITHUB_TOKEN }} quality_checks: runs-on: ubuntu-22.04 steps: @@ -421,6 +431,7 @@ jobs: path: cfn_guard_output build_dev_container_x64: + needs: [get-called-ref] permissions: id-token: write runs-on: ubuntu-22.04 @@ -434,7 +445,7 @@ jobs: env: SCRIPT_TAG: ${{ inputs.check_ecr_image_scan_results_script_tag }} run: | - curl -L "https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/heads/${SCRIPT_TAG}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh + curl -L "https://raw.githubusercontent.com/NHSDigital/eps-common-workflows/${{ needs.get-called-ref.outputs.ref }}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh chmod +x check_ecr_image_scan_results.sh - name: Build dev container run: | @@ -477,6 +488,7 @@ jobs: ./check_ecr_image_scan_results.sh build_dev_container_arm64: + needs: [get-called-ref] permissions: id-token: write runs-on: ubuntu-22.04-arm @@ -490,7 +502,7 @@ jobs: env: SCRIPT_TAG: ${{ inputs.check_ecr_image_scan_results_script_tag }} run: | - curl -L "https://raw.githubusercontent.com/NHSDigital/eps-common-workflows/refs/heads/${SCRIPT_TAG}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh + curl -L "https://raw.githubusercontent.com/NHSDigital/eps-common-workflows/${{ needs.get-called-ref.outputs.ref }}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh chmod +x check_ecr_image_scan_results.sh - name: Build dev container From 1e06c91e9cd278311857a8b1f41eb6c1a3bd0057 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Fri, 21 Nov 2025 17:14:50 +0000 Subject: [PATCH 53/62] do not need input --- .github/workflows/quality-checks.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index d49a1cf..3b50295 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -33,11 +33,6 @@ on: type: string description: "The tag to use for the dev container image." required: true - check_ecr_image_scan_results_script_tag: - type: string - description: "The tag to download check_ecr_image_scan_results.sh script." - required: false - default: "dev_container_build" jobs: get-called-ref: name: Get called ref @@ -442,8 +437,6 @@ jobs: fetch-depth: 0 - name: Download check_ecr_image_scan_results.sh script - env: - SCRIPT_TAG: ${{ inputs.check_ecr_image_scan_results_script_tag }} run: | curl -L "https://raw.githubusercontent.com/NHSDigital/eps-common-workflows/${{ needs.get-called-ref.outputs.ref }}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh chmod +x check_ecr_image_scan_results.sh @@ -499,8 +492,6 @@ jobs: fetch-depth: 0 - name: Download check_ecr_image_scan_results.sh script - env: - SCRIPT_TAG: ${{ inputs.check_ecr_image_scan_results_script_tag }} run: | curl -L "https://raw.githubusercontent.com/NHSDigital/eps-common-workflows/${{ needs.get-called-ref.outputs.ref }}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh chmod +x check_ecr_image_scan_results.sh From 0d90bb4d62feac768c85d06866ada71575a27fcc Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Fri, 21 Nov 2025 17:26:51 +0000 Subject: [PATCH 54/62] Revert "do not need input" This reverts commit 1e06c91e9cd278311857a8b1f41eb6c1a3bd0057. --- .github/workflows/quality-checks.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index 3b50295..d49a1cf 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -33,6 +33,11 @@ on: type: string description: "The tag to use for the dev container image." required: true + check_ecr_image_scan_results_script_tag: + type: string + description: "The tag to download check_ecr_image_scan_results.sh script." + required: false + default: "dev_container_build" jobs: get-called-ref: name: Get called ref @@ -437,6 +442,8 @@ jobs: fetch-depth: 0 - name: Download check_ecr_image_scan_results.sh script + env: + SCRIPT_TAG: ${{ inputs.check_ecr_image_scan_results_script_tag }} run: | curl -L "https://raw.githubusercontent.com/NHSDigital/eps-common-workflows/${{ needs.get-called-ref.outputs.ref }}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh chmod +x check_ecr_image_scan_results.sh @@ -492,6 +499,8 @@ jobs: fetch-depth: 0 - name: Download check_ecr_image_scan_results.sh script + env: + SCRIPT_TAG: ${{ inputs.check_ecr_image_scan_results_script_tag }} run: | curl -L "https://raw.githubusercontent.com/NHSDigital/eps-common-workflows/${{ needs.get-called-ref.outputs.ref }}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh chmod +x check_ecr_image_scan_results.sh From 229d9dcaed14252f76f3ddacf99411d2261373a0 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Fri, 21 Nov 2025 17:27:11 +0000 Subject: [PATCH 55/62] Revert "use correct path" This reverts commit e0488279fce299ba58f34987b2b55f046eb625c6. --- .github/actions/get_called_ref/action.yml | 27 ----------------------- .github/workflows/quality-checks.yml | 16 ++------------ 2 files changed, 2 insertions(+), 41 deletions(-) delete mode 100644 .github/actions/get_called_ref/action.yml diff --git a/.github/actions/get_called_ref/action.yml b/.github/actions/get_called_ref/action.yml deleted file mode 100644 index d4bf70b..0000000 --- a/.github/actions/get_called_ref/action.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Get called workflow ref - -description: > - A workaround to the issue: https://github.com/actions/toolkit/issues/1264. - - This is needed for the reusable workflow to be able to access its own version (commit hash) - that is being called by the caller workflow. This allows for using a proper ref of composite actions - inside the reusable workflow. -inputs: - GH_TOKEN_ADMIN: - required: true - description: 'GitHub token with admin permissions to access workflow run details.' - -outputs: - caller-ref: - description: 'The reference (commit hash or branch) of the called workflow' - value: ${{ steps.workflows-ref.outputs.caller-ref }} - -runs: - using: composite - steps: - - name: Get workflow reference - id: workflows-ref - shell: bash - run: | - ref=$(curl -L -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${{ inputs.GH_TOKEN_ADMIN }}" -H "X-GitHub-Api-Version: 2022-11-28" https://api.github.com/repos/${{ github.repository }}/actions/runs/${{ github.run_id }} | jq -r '.referenced_workflows[0] | .ref') - echo "caller-ref=$ref" >> $GITHUB_OUTPUT diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index d49a1cf..e2a3a42 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -39,16 +39,6 @@ on: required: false default: "dev_container_build" jobs: - get-called-ref: - name: Get called ref - runs-on: ubuntu-latest - outputs: - ref: ${{ steps.get_called_ref.outputs.caller-ref }} - steps: - - id: get_called_ref - uses: NHSDigital/eps-common-workflows/.github/actions/get_called_ref@dev_container_build - with: - GH_TOKEN_ADMIN: ${{ secrets.GITHUB_TOKEN }} quality_checks: runs-on: ubuntu-22.04 steps: @@ -431,7 +421,6 @@ jobs: path: cfn_guard_output build_dev_container_x64: - needs: [get-called-ref] permissions: id-token: write runs-on: ubuntu-22.04 @@ -445,7 +434,7 @@ jobs: env: SCRIPT_TAG: ${{ inputs.check_ecr_image_scan_results_script_tag }} run: | - curl -L "https://raw.githubusercontent.com/NHSDigital/eps-common-workflows/${{ needs.get-called-ref.outputs.ref }}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh + curl -L "https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/heads/${SCRIPT_TAG}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh chmod +x check_ecr_image_scan_results.sh - name: Build dev container run: | @@ -488,7 +477,6 @@ jobs: ./check_ecr_image_scan_results.sh build_dev_container_arm64: - needs: [get-called-ref] permissions: id-token: write runs-on: ubuntu-22.04-arm @@ -502,7 +490,7 @@ jobs: env: SCRIPT_TAG: ${{ inputs.check_ecr_image_scan_results_script_tag }} run: | - curl -L "https://raw.githubusercontent.com/NHSDigital/eps-common-workflows/${{ needs.get-called-ref.outputs.ref }}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh + curl -L "https://raw.githubusercontent.com/NHSDigital/eps-common-workflows/refs/heads/${SCRIPT_TAG}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh chmod +x check_ecr_image_scan_results.sh - name: Build dev container From e233a8a6f209f680b97f24dac80d181f72510eb3 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Sat, 22 Nov 2025 11:05:37 +0000 Subject: [PATCH 56/62] use correct ecr --- .github/workflows/pull_request.yml | 2 +- .github/workflows/release.yml | 4 ++-- .github/workflows/tag_latest_container_images.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 2f7f77a..5f50a01 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -77,7 +77,7 @@ jobs: needs: [get_asdf_version, get_issue_number_and_commit_id] with: asdfVersion: ${{ needs.get_asdf_version.outputs.asdf_version }} - dev_container_ecr: dev-container-quality-checks + dev_container_ecr: dev-container-common-workflows dev_container_image_tag: PR-${{ needs.get_issue_number_and_commit_id.outputs.issue_number }}-${{ needs.get_issue_number_and_commit_id.outputs.sha_short }} secrets: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d03b388..56e4adc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -48,7 +48,7 @@ jobs: uses: ./.github/workflows/quality-checks.yml with: asdfVersion: ${{ needs.get_asdf_version.outputs.asdf_version }} - dev_container_ecr: dev-container-quality-checks + dev_container_ecr: dev-container-common-workflows dev_container_image_tag: release-${{ needs.get_commit_id.outputs.sha_short }} secrets: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} @@ -75,7 +75,7 @@ jobs: needs: [quality_checks, get_commit_id, tag_release] uses: ./.github/workflows/tag_latest_container_images.yml with: - ecr_name: dev-container-quality-checks + ecr_name: dev-container-common-workflows container_image_tag: release-${{ needs.get_commit_id.outputs.sha_short }} version_tag_to_apply: ${{ needs.tag_release.outputs.version_tag }} secrets: diff --git a/.github/workflows/tag_latest_container_images.yml b/.github/workflows/tag_latest_container_images.yml index b7382fd..6f72069 100644 --- a/.github/workflows/tag_latest_container_images.yml +++ b/.github/workflows/tag_latest_container_images.yml @@ -12,7 +12,7 @@ on: required: true container_image_tag: type: string - description: "The tag to use for the dev container image." + description: "The tag of an existing image to apply version tag to." required: true version_tag_to_apply: type: string From 44746cc1138cc9b6d6e359f69b2677bd486f5f40 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Tue, 25 Nov 2025 10:34:20 +0000 Subject: [PATCH 57/62] add workflow to push to github --- .gitallowed | 1 + .../publish_nhsd_git_secrets_to_github.yml | 95 +++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 .github/workflows/publish_nhsd_git_secrets_to_github.yml diff --git a/.gitallowed b/.gitallowed index e7593cf..10c7e75 100644 --- a/.gitallowed +++ b/.gitallowed @@ -1,3 +1,4 @@ token: ?"?\$\{\{\s*secrets\.GITHUB_TOKEN\s*\}\}"? .*\.gitallowed.* id-token: write +password: \${{ secrets\.GITHUB_TOKEN }} diff --git a/.github/workflows/publish_nhsd_git_secrets_to_github.yml b/.github/workflows/publish_nhsd_git_secrets_to_github.yml new file mode 100644 index 0000000..7926535 --- /dev/null +++ b/.github/workflows/publish_nhsd_git_secrets_to_github.yml @@ -0,0 +1,95 @@ +# +name: Create and publish a Docker image + +on: + workflow_call: + secrets: + PUSH_IMAGE_ROLE: + required: true + inputs: + ecr_name: + type: string + description: "The name of the ECR repository to push the dev container image to." + required: true + container_image_tag: + type: string + description: "The tag of an existing image to publish to github." + required: true + +# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds. +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu. +jobs: + build-and-push-image: + runs-on: ubuntu-latest + # Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job. + permissions: + contents: read + packages: write + attestations: write + id-token: write + # + steps: + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 + id: connect-aws-deploy + with: + aws-region: eu-west-2 + role-to-assume: ${{ secrets.PUSH_IMAGE_ROLE }} + role-session-name: dev-container-build-x64 + output-credentials: true + - name: Retrieve AWS Account ID + id: retrieve-deploy-account-id + run: | + ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) + echo "account_id=$ACCOUNT_ID" >> "$GITHUB_OUTPUT" + + - name: Login to Amazon ECR + run: | + aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com + + - name: pull image + run: | + docker pull "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" + docker pull "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" + env: + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + ECR_REPOSITORY: ${{ inputs.ecr_name }} + IMAGE_TAG: ${{ inputs.container_image_tag }} + + - name: Log in to the Container registry + uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Tag and push amd64 image + run: | + docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${IMAGE_TAG}-amd64" + docker push "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${IMAGE_TAG}-amd64" + env: + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + ECR_REPOSITORY: ${{ inputs.ecr_name }} + IMAGE_TAG: ${{ inputs.container_image_tag }} + + - name: Tag and push arm64 image + run: | + docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${IMAGE_TAG}-arm64" + docker push "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${IMAGE_TAG}-arm64" + env: + ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + ECR_REPOSITORY: ${{ inputs.ecr_name }} + IMAGE_TAG: ${{ inputs.container_image_tag }} + + - name: Create and push multi-arch manifest + run: | + docker manifest create "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${IMAGE_TAG}" \ + --amend "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${IMAGE_TAG}-amd64" \ + --amend "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${IMAGE_TAG}-arm64" + docker manifest push "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${IMAGE_TAG}" + env: + IMAGE_TAG: ${{ inputs.container_image_tag }} From fcdd04dbb5f32a156052e9d9659322e6ea7763cb Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Tue, 25 Nov 2025 10:46:41 +0000 Subject: [PATCH 58/62] call publish to github --- .../workflows/publish_nhsd_git_secrets_to_github.yml | 2 +- .github/workflows/pull_request.yml | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish_nhsd_git_secrets_to_github.yml b/.github/workflows/publish_nhsd_git_secrets_to_github.yml index 7926535..516cd8d 100644 --- a/.github/workflows/publish_nhsd_git_secrets_to_github.yml +++ b/.github/workflows/publish_nhsd_git_secrets_to_github.yml @@ -9,7 +9,7 @@ on: inputs: ecr_name: type: string - description: "The name of the ECR repository to push the dev container image to." + description: "The name of the ECR repository to pull the git-secrets image from." required: true container_image_tag: type: string diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 8dd404d..3e74134 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -92,6 +92,16 @@ jobs: secrets: PUSH_IMAGE_ROLE: ${{ secrets.DEV_CONTAINER_PUSH_IMAGE_ROLE }} + publish_nhsd_git_secrets_to_github: + needs: + [get_asdf_version, get_issue_number_and_commit_id, build_nhsd_git_secrets] + uses: ./.github/workflows/publish_nhsd_git_secrets_to_github.yml + with: + ecr_name: git-secrets + container_image_tag: PR-${{ needs.get_issue_number_and_commit_id.outputs.issue_number }}-${{ needs.get_issue_number_and_commit_id.outputs.sha_short }}-nhsd-git-secrets + secrets: + PUSH_IMAGE_ROLE: ${{ secrets.DEV_CONTAINER_PUSH_IMAGE_ROLE }} + tag_release: needs: [quality_checks, get_asdf_version] uses: ./.github/workflows/tag-release.yml From 4a14f7dbfef25884eb657e0c052ac79edcaf5396 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Tue, 25 Nov 2025 11:26:17 +0000 Subject: [PATCH 59/62] common workflow for build and push --- ...ts.yml => build_and_push_docker_image.yml} | 82 +++++---- .github/workflows/pull_request.yml | 7 +- .github/workflows/quality-checks.yml | 169 +----------------- .github/workflows/release.yml | 7 +- 4 files changed, 67 insertions(+), 198 deletions(-) rename .github/workflows/{build_nhsd_git_secrets.yml => build_and_push_docker_image.yml} (66%) diff --git a/.github/workflows/build_nhsd_git_secrets.yml b/.github/workflows/build_and_push_docker_image.yml similarity index 66% rename from .github/workflows/build_nhsd_git_secrets.yml rename to .github/workflows/build_and_push_docker_image.yml index d04f149..2e6dde6 100644 --- a/.github/workflows/build_nhsd_git_secrets.yml +++ b/.github/workflows/build_and_push_docker_image.yml @@ -1,23 +1,31 @@ -name: Build nhsd git secrets +name: Build and push docker image on: workflow_call: secrets: - SONAR_TOKEN: - required: false PUSH_IMAGE_ROLE: required: true inputs: - git_secrets_container_ecr: + container_ecr: + type: string + description: "The name of the ECR repository to push the container image to." + required: true + container_image_tag: type: string - description: "The name of the ECR repository to push the dev container image to." + description: "The tag to use for the container image." required: true - git_secrets_container_image_tag: + docker_file: type: string - description: "The tag to use for the dev container image." + description: "The Dockerfile to use for building the container image." required: true + check_ecr_image_scan_results_script_tag: + type: string + description: "The tag to download check_ecr_image_scan_results.sh script." + required: false + default: "dev_container_build" + jobs: - build_nhsd_git_secrets_x64: + build_image_amd64: permissions: id-token: write runs-on: ubuntu-22.04 @@ -27,9 +35,11 @@ jobs: with: fetch-depth: 0 - - name: Build dev container + - name: Build container run: | - docker build -f dockerfiles/nhsd-git-secrets.dockerfile -t nhsd-git-secrets-image . + docker build -f "${DOCKER_FILE}" -t x64-image . + env: + DOCKER_FILE: ${{ inputs.docker_file }} - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 @@ -37,7 +47,7 @@ jobs: with: aws-region: eu-west-2 role-to-assume: ${{ secrets.PUSH_IMAGE_ROLE }} - role-session-name: dev-container-build-x64 + role-session-name: dev-container-build-amd64 output-credentials: true - name: Retrieve AWS Account ID @@ -52,22 +62,26 @@ jobs: - name: Push x64 image to Amazon ECR env: - ECR_REPOSITORY: ${{ inputs.git_secrets_container_ecr }} - IMAGE_TAG: ${{ inputs.git_secrets_container_image_tag }} + ECR_REPOSITORY: ${{ inputs.container_ecr }} + IMAGE_TAG: ${{ inputs.container_image_tag }} ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} run: | - docker tag "nhsd-git-secrets-image" "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" + docker tag "amd64-image" "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" + - name: Check dev container scan results env: - REPOSITORY_NAME: ${{ inputs.git_secrets_container_ecr }} - IMAGE_TAG: ${{ inputs.git_secrets_container_image_tag }}-amd64 + REPOSITORY_NAME: ${{ inputs.container_ecr }} + IMAGE_TAG: ${{ inputs.container_image_tag }}-amd64 ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + SCRIPT_TAG: ${{ inputs.check_ecr_image_scan_results_script_tag }} run: | + curl -L "https://raw.githubusercontent.com/NHSDigital/eps-common-workflows/refs/heads/${SCRIPT_TAG}/.github/scripts/check_ecr_image_scan_results.sh" -o /tmp/check_ecr_image_scan_results.sh + chmod +x /tmp/check_ecr_image_scan_results.sh sleep 30 - ./.github/scripts/check_ecr_image_scan_results.sh + /tmp/check_ecr_image_scan_results.sh - build_nhsd_git_secrets_arm64: + build_image_arm64: permissions: id-token: write runs-on: ubuntu-22.04-arm @@ -77,9 +91,11 @@ jobs: with: fetch-depth: 0 - - name: Build dev container + - name: Build container run: | - docker build -f dockerfiles/nhsd-git-secrets.dockerfile -t nhsd-git-secrets-image-arm . + docker build -f "${DOCKER_FILE}" -t arm64-image . + env: + DOCKER_FILE: ${{ inputs.docker_file }} - name: Configure AWS Credentials uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 @@ -102,27 +118,29 @@ jobs: - name: Push ARM64 image to Amazon ECR env: - ECR_REPOSITORY: ${{ inputs.git_secrets_container_ecr }} - IMAGE_TAG: ${{ inputs.git_secrets_container_image_tag }} + ECR_REPOSITORY: ${{ inputs.container_ecr }} + IMAGE_TAG: ${{ inputs.container_image_tag }} ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} run: | - docker tag "nhsd-git-secrets-image-arm" "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" + docker tag "arm64-image" "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" - name: Check dev container scan results env: - REPOSITORY_NAME: ${{ inputs.git_secrets_container_ecr }} - IMAGE_TAG: ${{ inputs.git_secrets_container_image_tag }}-arm64 + REPOSITORY_NAME: ${{ inputs.container_ecr }} + IMAGE_TAG: ${{ inputs.container_image_tag }}-arm64 ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} + SCRIPT_TAG: ${{ inputs.check_ecr_image_scan_results_script_tag }} run: | - # Wait a moment for ECR to process the new manifest + curl -L "https://raw.githubusercontent.com/NHSDigital/eps-common-workflows/refs/heads/${SCRIPT_TAG}/.github/scripts/check_ecr_image_scan_results.sh" -o /tmp/check_ecr_image_scan_results.sh + chmod +x /tmp/check_ecr_image_scan_results.sh sleep 30 - ./.github/scripts/check_ecr_image_scan_results.sh + /tmp/check_ecr_image_scan_results.sh create_multi_arch_manifest: permissions: id-token: write runs-on: ubuntu-22.04 - needs: [build_nhsd_git_secrets_x64, build_nhsd_git_secrets_arm64] + needs: [build_image_amd64, build_image_arm64] steps: - name: Set up Docker Buildx uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 @@ -147,8 +165,8 @@ jobs: - name: Create and push multi-architecture manifest for tag env: - ECR_REPOSITORY: ${{ inputs.git_secrets_container_ecr }} - IMAGE_TAG: ${{ inputs.git_secrets_container_image_tag }} + ECR_REPOSITORY: ${{ inputs.container_ecr }} + IMAGE_TAG: ${{ inputs.container_image_tag }} ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} run: | # Create manifest list combining both architectures @@ -158,8 +176,8 @@ jobs: - name: Verify multi-architecture manifest env: - ECR_REPOSITORY: ${{ inputs.git_secrets_container_ecr }} - IMAGE_TAG: ${{ inputs.git_secrets_container_image_tag }} + ECR_REPOSITORY: ${{ inputs.container_ecr }} + IMAGE_TAG: ${{ inputs.container_image_tag }} ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} run: | echo "=== Verifying multi-architecture manifest ===" diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 3e74134..f1e3be5 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -84,11 +84,12 @@ jobs: PUSH_IMAGE_ROLE: ${{ secrets.DEV_CONTAINER_PUSH_IMAGE_ROLE }} build_nhsd_git_secrets: - uses: ./.github/workflows/build_nhsd_git_secrets.yml + uses: ./.github/workflows/build_and_push_docker_image.yml needs: [get_asdf_version, get_issue_number_and_commit_id] with: - git_secrets_container_ecr: git-secrets - git_secrets_container_image_tag: PR-${{ needs.get_issue_number_and_commit_id.outputs.issue_number }}-${{ needs.get_issue_number_and_commit_id.outputs.sha_short }}-nhsd-git-secrets + container_ecr: git-secrets + container_image_tag: PR-${{ needs.get_issue_number_and_commit_id.outputs.issue_number }}-${{ needs.get_issue_number_and_commit_id.outputs.sha_short }}-nhsd-git-secrets + docker_file: dockerfiles/nhsd-git-secrets.dockerfile secrets: PUSH_IMAGE_ROLE: ${{ secrets.DEV_CONTAINER_PUSH_IMAGE_ROLE }} diff --git a/.github/workflows/quality-checks.yml b/.github/workflows/quality-checks.yml index e97f275..6638732 100644 --- a/.github/workflows/quality-checks.yml +++ b/.github/workflows/quality-checks.yml @@ -420,163 +420,12 @@ jobs: name: cfn_guard_output path: cfn_guard_output - build_dev_container_x64: - permissions: - id-token: write - runs-on: ubuntu-22.04 - steps: - - name: Checkout code - uses: actions/checkout@v5 - with: - fetch-depth: 0 - - - name: Download check_ecr_image_scan_results.sh script - env: - SCRIPT_TAG: ${{ inputs.check_ecr_image_scan_results_script_tag }} - run: | - curl -L "https://raw.githubusercontent.com/NHSDigital/eps-workflow-quality-checks/refs/heads/${SCRIPT_TAG}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh - chmod +x check_ecr_image_scan_results.sh - - name: Build dev container - run: | - docker build -f .devcontainer/Dockerfile -t dev-container-image . - - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 - id: connect-aws-deploy - with: - aws-region: eu-west-2 - role-to-assume: ${{ secrets.PUSH_IMAGE_ROLE }} - role-session-name: dev-container-build-x64 - output-credentials: true - - - name: Retrieve AWS Account ID - id: retrieve-deploy-account-id - run: | - ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) - echo "account_id=$ACCOUNT_ID" >> "$GITHUB_OUTPUT" - - - name: Login to Amazon ECR - run: | - aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com - - - name: Push x64 image to Amazon ECR - env: - ECR_REPOSITORY: ${{ inputs.dev_container_ecr }} - IMAGE_TAG: ${{ inputs.dev_container_image_tag }} - ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} - run: | - docker tag "dev-container-image" "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" - docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" - - name: Check dev container scan results - env: - REPOSITORY_NAME: ${{ inputs.dev_container_ecr }} - IMAGE_TAG: ${{ inputs.dev_container_image_tag }}-amd64 - ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} - run: | - sleep 30 - ./check_ecr_image_scan_results.sh - - build_dev_container_arm64: - permissions: - id-token: write - runs-on: ubuntu-22.04-arm - steps: - - name: Checkout code - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 - with: - fetch-depth: 0 - - - name: Download check_ecr_image_scan_results.sh script - env: - SCRIPT_TAG: ${{ inputs.check_ecr_image_scan_results_script_tag }} - run: | - curl -L "https://raw.githubusercontent.com/NHSDigital/eps-common-workflows/refs/heads/${SCRIPT_TAG}/.github/scripts/check_ecr_image_scan_results.sh" -o check_ecr_image_scan_results.sh - chmod +x check_ecr_image_scan_results.sh - - - name: Build dev container - run: | - docker build -f .devcontainer/Dockerfile -t dev-container-image-arm . - - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 - id: connect-aws-deploy - with: - aws-region: eu-west-2 - role-to-assume: ${{ secrets.PUSH_IMAGE_ROLE }} - role-session-name: dev-container-build-arm64 - output-credentials: true - - - name: Retrieve AWS Account ID - id: retrieve-deploy-account-id - run: | - ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) - echo "account_id=$ACCOUNT_ID" >> "$GITHUB_OUTPUT" - - - name: Login to Amazon ECR - run: | - aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com - - - name: Push ARM64 image to Amazon ECR - env: - ECR_REPOSITORY: ${{ inputs.dev_container_ecr }} - IMAGE_TAG: ${{ inputs.dev_container_image_tag }} - ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} - run: | - docker tag "dev-container-image-arm" "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" - docker push "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" - - name: Check dev container scan results - env: - REPOSITORY_NAME: ${{ inputs.dev_container_ecr }} - IMAGE_TAG: ${{ inputs.dev_container_image_tag }}-arm64 - ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} - run: | - # Wait a moment for ECR to process the new manifest - sleep 30 - ./check_ecr_image_scan_results.sh - - create_multi_arch_manifest: - permissions: - id-token: write - runs-on: ubuntu-22.04 - needs: [build_dev_container_x64, build_dev_container_arm64] - steps: - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 - - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@00943011d9042930efac3dcd3a170e4273319bc8 - with: - aws-region: eu-west-2 - role-to-assume: ${{ secrets.PUSH_IMAGE_ROLE }} - role-session-name: multi-arch-manifest - output-credentials: true - - - name: Retrieve AWS Account ID - id: retrieve-deploy-account-id - run: | - ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) - echo "account_id=$ACCOUNT_ID" >> "$GITHUB_OUTPUT" - - - name: Login to Amazon ECR - run: | - aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com - - - name: Create and push multi-architecture manifest for tag - env: - ECR_REPOSITORY: ${{ inputs.dev_container_ecr }} - IMAGE_TAG: ${{ inputs.dev_container_image_tag }} - ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} - run: | - # Create manifest list combining both architectures - docker buildx imagetools create -t "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}" \ - "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" \ - "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" - - - name: Verify multi-architecture manifest - env: - ECR_REPOSITORY: ${{ inputs.dev_container_ecr }} - IMAGE_TAG: ${{ inputs.dev_container_image_tag }} - ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} - run: | - echo "=== Verifying multi-architecture manifest ===" - docker buildx imagetools inspect "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}" + build_and_push_dev_container_image: + uses: ./.github/workflows/build_and_push_docker_image.yml + with: + container_ecr: ${{ inputs.dev_container_ecr }} + container_image_tag: ${{ inputs.dev_container_image_tag }} + docker_file: ".devcontainer/Dockerfile" + check_ecr_image_scan_results_script_tag: ${{ inputs.check_ecr_image_scan_results_script_tag }} + secrets: + PUSH_IMAGE_ROLE: ${{ secrets.PUSH_IMAGE_ROLE }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b322182..83824bd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -54,11 +54,12 @@ jobs: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} PUSH_IMAGE_ROLE: ${{ secrets.DEV_CONTAINER_PUSH_IMAGE_ROLE }} build_nhsd_git_secrets: - uses: ./.github/workflows/build_nhsd_git_secrets.yml + uses: ./.github/workflows/build_and_push_docker_image.yml needs: [get_asdf_version, get_commit_id] with: - git_secrets_container_ecr: git-secrets - git_secrets_container_image_tag: release-${{ needs.get_commit_id.outputs.sha_short }} + container_ecr: git-secrets + container_image_tag: release-${{ needs.get_commit_id.outputs.sha_short }} + docker_file: dockerfiles/nhsd-git-secrets.dockerfile secrets: PUSH_IMAGE_ROLE: ${{ secrets.DEV_CONTAINER_PUSH_IMAGE_ROLE }} tag_release: From 7e18204007773d7dcc849cf2cd31cdd126f56f1c Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Tue, 25 Nov 2025 11:29:48 +0000 Subject: [PATCH 60/62] fix image name --- .github/workflows/build_and_push_docker_image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_push_docker_image.yml b/.github/workflows/build_and_push_docker_image.yml index 2e6dde6..c2427d5 100644 --- a/.github/workflows/build_and_push_docker_image.yml +++ b/.github/workflows/build_and_push_docker_image.yml @@ -37,7 +37,7 @@ jobs: - name: Build container run: | - docker build -f "${DOCKER_FILE}" -t x64-image . + docker build -f "${DOCKER_FILE}" -t amd64-image . env: DOCKER_FILE: ${{ inputs.docker_file }} From 74e04d1c3d895808c9bacdf1056c04b0c7511b15 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Tue, 25 Nov 2025 11:33:37 +0000 Subject: [PATCH 61/62] fix step name --- .github/workflows/build_and_push_docker_image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_push_docker_image.yml b/.github/workflows/build_and_push_docker_image.yml index c2427d5..64f3295 100644 --- a/.github/workflows/build_and_push_docker_image.yml +++ b/.github/workflows/build_and_push_docker_image.yml @@ -60,7 +60,7 @@ jobs: run: | aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin ${{ steps.retrieve-deploy-account-id.outputs.account_id }}.dkr.ecr.eu-west-2.amazonaws.com - - name: Push x64 image to Amazon ECR + - name: Push amd64 image to Amazon ECR env: ECR_REPOSITORY: ${{ inputs.container_ecr }} IMAGE_TAG: ${{ inputs.container_image_tag }} From 8b6283c0844caf3db1d4d6fea4055f986d2022e6 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Tue, 25 Nov 2025 11:40:09 +0000 Subject: [PATCH 62/62] force image name to lowercase --- .../publish_nhsd_git_secrets_to_github.yml | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/publish_nhsd_git_secrets_to_github.yml b/.github/workflows/publish_nhsd_git_secrets_to_github.yml index 516cd8d..99dcf49 100644 --- a/.github/workflows/publish_nhsd_git_secrets_to_github.yml +++ b/.github/workflows/publish_nhsd_git_secrets_to_github.yml @@ -69,8 +69,9 @@ jobs: - name: Tag and push amd64 image run: | - docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${IMAGE_TAG}-amd64" - docker push "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${IMAGE_TAG}-amd64" + IMAGE_NAME_LOWER=$(echo "${{ env.IMAGE_NAME }}" | tr '[:upper:]' '[:lower:]') + docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-amd64" "${{ env.REGISTRY }}/${IMAGE_NAME_LOWER}:${IMAGE_TAG}-amd64" + docker push "${{ env.REGISTRY }}/${IMAGE_NAME_LOWER}:${IMAGE_TAG}-amd64" env: ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} ECR_REPOSITORY: ${{ inputs.ecr_name }} @@ -78,8 +79,9 @@ jobs: - name: Tag and push arm64 image run: | - docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${IMAGE_TAG}-arm64" - docker push "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${IMAGE_TAG}-arm64" + IMAGE_NAME_LOWER=$(echo "${{ env.IMAGE_NAME }}" | tr '[:upper:]' '[:lower:]') + docker tag "${ACCOUNT_ID}.dkr.ecr.eu-west-2.amazonaws.com/${ECR_REPOSITORY}:${IMAGE_TAG}-arm64" "${{ env.REGISTRY }}/${IMAGE_NAME_LOWER}:${IMAGE_TAG}-arm64" + docker push "${{ env.REGISTRY }}/${IMAGE_NAME_LOWER}:${IMAGE_TAG}-arm64" env: ACCOUNT_ID: ${{ steps.retrieve-deploy-account-id.outputs.account_id }} ECR_REPOSITORY: ${{ inputs.ecr_name }} @@ -87,9 +89,10 @@ jobs: - name: Create and push multi-arch manifest run: | - docker manifest create "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${IMAGE_TAG}" \ - --amend "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${IMAGE_TAG}-amd64" \ - --amend "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${IMAGE_TAG}-arm64" - docker manifest push "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${IMAGE_TAG}" + IMAGE_NAME_LOWER=$(echo "${{ env.IMAGE_NAME }}" | tr '[:upper:]' '[:lower:]') + docker manifest create "${{ env.REGISTRY }}/${IMAGE_NAME_LOWER}:${IMAGE_TAG}" \ + --amend "${{ env.REGISTRY }}/${IMAGE_NAME_LOWER}:${IMAGE_TAG}-amd64" \ + --amend "${{ env.REGISTRY }}/${IMAGE_NAME_LOWER}:${IMAGE_TAG}-arm64" + docker manifest push "${{ env.REGISTRY }}/${IMAGE_NAME_LOWER}:${IMAGE_TAG}" env: IMAGE_TAG: ${{ inputs.container_image_tag }}