From 4e343ca0817f0f1f0252de22f460fca5205646ac Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Sat, 28 Mar 2026 10:58:47 +0000 Subject: [PATCH 01/42] use zizmor --- .devcontainer/devcontainer.json | 2 +- .github/workflows/combine-dependabot-prs.yml | 67 --------- .../dependabot-auto-approve-and-merge.yml | 2 +- .github/workflows/get-repo-config.yml | 1 + .github/workflows/pull_request.yml | 1 - combine-prs.js | 127 ------------------ zizmor.yml | 26 ++++ 7 files changed, 29 insertions(+), 197 deletions(-) delete mode 100644 .github/workflows/combine-dependabot-prs.yml delete mode 100644 combine-prs.js create mode 100644 zizmor.yml diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index d19c9683..d71c2158 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -6,7 +6,7 @@ "args": { "DOCKER_GID": "${env:DOCKER_GID:}", "IMAGE_NAME": "node_24_python_3_14", - "IMAGE_VERSION": "v1.2.0", + "IMAGE_VERSION": "pr-68-7f136dd", "USER_UID": "${localEnv:USER_ID:}", "USER_GID": "${localEnv:GROUP_ID:}" }, diff --git a/.github/workflows/combine-dependabot-prs.yml b/.github/workflows/combine-dependabot-prs.yml deleted file mode 100644 index b73f45ff..00000000 --- a/.github/workflows/combine-dependabot-prs.yml +++ /dev/null @@ -1,67 +0,0 @@ -name: "Combine PRs" - -on: - workflow_call: - inputs: - branchPrefix: - description: "Branch prefix to find combinable PRs based on" - default: "dependabot" - type: string - mustBeGreen: - description: "Only combine PRs that are green (status is success)" - default: true - type: boolean - combineBranchName: - description: "Name of the branch to combine PRs into" - default: "combine-dependabot-PRs" - type: string - ignoreLabel: - description: "Exclude PRs with this label" - default: "nocombine" - type: string - - # Allow manual triggering of the workflow for this repo - workflow_dispatch: - inputs: - branchPrefix: - description: "Branch prefix to find combinable PRs based on" - default: "dependabot" - type: string - mustBeGreen: - description: "Only combine PRs that are green (status is success)" - default: true - type: boolean - combineBranchName: - description: "Name of the branch to combine PRs into" - default: "combine-dependabot-PRs" - type: string - ignoreLabel: - description: "Exclude PRs with this label" - default: "nocombine" - type: string - -jobs: - combine-prs: - runs-on: ubuntu-22.04 - steps: - - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - with: - repository: NHSDigital/eps-common-workflows - sparse-checkout-cone-mode: false - sparse-checkout: | - combine-prs.js - - - name: Create Combined PR - uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd - id: create-combined-pr - env: - branchPrefix: ${{ inputs.branchPrefix }} - mustBeGreen: ${{ inputs.mustBeGreen }} - combineBranchName: ${{ inputs.combineBranchName }} - ignoreLabel: ${{ inputs.ignoreLabel }} - with: - github-token: ${{secrets.GITHUB_TOKEN}} - script: | - const combinePRs = require('./combine-prs.js'); - await combinePRs({ github, context, core }); diff --git a/.github/workflows/dependabot-auto-approve-and-merge.yml b/.github/workflows/dependabot-auto-approve-and-merge.yml index 6ed23f00..27a4fab2 100644 --- a/.github/workflows/dependabot-auto-approve-and-merge.yml +++ b/.github/workflows/dependabot-auto-approve-and-merge.yml @@ -15,7 +15,7 @@ permissions: jobs: dependabot: runs-on: ubuntu-22.04 - if: ${{ github.actor == 'dependabot[bot]' }} + if: (github.event.pull_request.user.login == 'dependabot[bot]' || github.event.pull_request.user.login == 'eps-create-pull-request[bot]') && github.repository == github.event.pull_request.head.repo.full_name steps: - name: Get token from Github App id: get_app_token diff --git a/.github/workflows/get-repo-config.yml b/.github/workflows/get-repo-config.yml index cc6a9260..916b5267 100644 --- a/.github/workflows/get-repo-config.yml +++ b/.github/workflows/get-repo-config.yml @@ -53,6 +53,7 @@ jobs: with: ref: ${{ env.BRANCH_NAME }} fetch-depth: 0 + persist-credentials: false - name: Load config value id: load-config diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index c21199fe..46429bed 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -43,4 +43,3 @@ jobs: pinned_image: ${{ needs.get_config_values.outputs.pinned_image }} branch_name: ${{ github.event.pull_request.head.ref }} tag_format: ${{ needs.get_config_values.outputs.tag_format }} - secrets: inherit diff --git a/combine-prs.js b/combine-prs.js deleted file mode 100644 index 70e5c5c9..00000000 --- a/combine-prs.js +++ /dev/null @@ -1,127 +0,0 @@ -module.exports = async ({ github, context, core }) => { - const branchPrefix = process.env.branchPrefix; - const mustBeGreen = Boolean(process.env.mustBeGreen); - const combineBranchName = process.env.combineBranchName; - const ignoreLabel = process.env.ignoreLabel; - - const pulls = await github.paginate('GET /repos/:owner/:repo/pulls', { - owner: context.repo.owner, - repo: context.repo.repo - }); - let branchesAndPRStrings = []; - let baseBranch = null; - let baseBranchSHA = null; - - for (const pull of pulls) { - const branch = pull['head']['ref']; - console.log('Pull for branch: ' + branch); - - if (branch.startsWith(branchPrefix)) { - console.log('Branch matched prefix: ' + branch); - let statusOK = true; - if (mustBeGreen) { - console.log('Checking green status: ' + branch); - const stateQuery = `query($owner: String!, $repo: String!, $pull_number: Int!) { - repository(owner: $owner, name: $repo) { - pullRequest(number:$pull_number) { - commits(last: 1) { - nodes { - commit { - statusCheckRollup { - state - } - } - } - } - } - } - }` - const vars = { - owner: context.repo.owner, - repo: context.repo.repo, - pull_number: pull['number'] - }; - const result = await github.graphql(stateQuery, vars); - const [{ commit }] = result.repository.pullRequest.commits.nodes; - const state = commit.statusCheckRollup.state - console.log('Validating status: ' + state); - if (state != 'SUCCESS') { - console.log('Discarding ' + branch + ' with status ' + state); - statusOK = false; - } - } - - console.log('Checking labels: ' + branch); - const labels = pull['labels']; - for (const label of labels) { - const labelName = label['name']; - console.log('Checking label: ' + labelName); - if (labelName == ignoreLabel) { - console.log('Discarding ' + branch + ' with label ' + labelName); - statusOK = false; - } - } - - if (statusOK) { - console.log('Adding branch to array: ' + branch); - const prString = '#' + pull['number'] + ' ' + pull['title']; - branchesAndPRStrings.push({ branch, prString }); - baseBranch = pull['base']['ref']; - baseBranchSHA = pull['base']['sha']; - } - } - } - - if (branchesAndPRStrings.length == 0) { - core.setFailed('No PRs/branches matched criteria'); - return; - } - - try { - await github.rest.git.createRef({ - owner: context.repo.owner, - repo: context.repo.repo, - ref: 'refs/heads/' + combineBranchName, - sha: baseBranchSHA - }); - } catch (error) { - console.log(error); - core.setFailed('Failed to create combined branch - maybe a branch by that name already exists?'); - return; - } - - let combinedPRs = []; - let mergeFailedPRs = []; - for (const { branch, prString } of branchesAndPRStrings) { - try { - await github.rest.repos.merge({ - owner: context.repo.owner, - repo: context.repo.repo, - base: combineBranchName, - head: branch, - }); - console.log('Merged branch ' + branch); - combinedPRs.push(prString); - } catch (error) { - console.log('Failed to merge branch ' + branch); - mergeFailedPRs.push(prString); - } - } - - console.log('Creating combined PR'); - const combinedPRsString = combinedPRs.join('\n'); - let body = '✅ This PR was created by the Combine PRs action by combining the following PRs:\n' + combinedPRsString; - if (mergeFailedPRs.length > 0) { - const mergeFailedPRsString = mergeFailedPRs.join('\n'); - body += '\n\n⚠️ The following PRs were left out due to merge conflicts:\n' + mergeFailedPRsString - } - - await github.rest.pulls.create({ - owner: context.repo.owner, - repo: context.repo.repo, - title: 'Combined PR', - head: combineBranchName, - base: baseBranch, - body: body - }); -} diff --git a/zizmor.yml b/zizmor.yml new file mode 100644 index 00000000..94956500 --- /dev/null +++ b/zizmor.yml @@ -0,0 +1,26 @@ +rules: + dependabot-cooldown: + config: + days: 3 + secrets-outside-env: + ignore: + # this workflow uses secrets outside of an environment + - tag-release-devcontainer.yml:108:39 + - tag-release-devcontainer.yml:228:34 + - tag-release-devcontainer.yml:234:35 + - tag-release-devcontainer.yml:240:34 + - tag-release-devcontainer.yml:248:35 + - update-dev-container-version.yml:135:24 + - update-dev-container-version.yml:136:29 + - quality-checks-devcontainer.yml:210:28 + - quality-checks-devcontainer.yml:203:28 + - quality-checks-devcontainer.yml:190:29 + - dependabot-auto-approve-and-merge.yml:24:31 + - dependabot-auto-approve-and-merge.yml:25:36 + unpinned-images: + ignore: + - quality-checks-devcontainer.yml:32:7 + - quality-checks-devcontainer.yml:215:7 + - quality-checks-devcontainer.yml:285:7 + - quality-checks-devcontainer.yml:328:7 + - tag-release-devcontainer.yml:89:13 From 174180959926e90e336f7c387e77ad26608ae4f7 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Mon, 30 Mar 2026 10:02:16 +0000 Subject: [PATCH 02/42] more fixes --- .github/workflows/quality-checks-devcontainer.yml | 4 +++- .github/workflows/release.yml | 1 - .github/workflows/tag-release-devcontainer.yml | 6 +++++- .github/workflows/update-dev-container-version.yml | 12 +++++------- zizmor.yml | 7 +++++++ 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index fc562b42..89f2610c 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -317,10 +317,12 @@ jobs: - name: Show docker vulnerability output if: always() run: | - echo "Scan output for ${{ matrix.docker_image }}" + echo "Scan output for ${DOCKER_IMAGE}" if [ -f .trivy_out/dependency_results_docker.txt ]; then cat .trivy_out/dependency_results_docker.txt fi + env: + DOCKER_IMAGE: ${{ matrix.docker_image }} IaC-validation: runs-on: ubuntu-22.04 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dbb82b14..4b752eaf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,4 +28,3 @@ jobs: pinned_image: ${{ needs.get_config_values.outputs.pinned_image }} branch_name: main tag_format: ${{ needs.get_config_values.outputs.tag_format }} - secrets: inherit diff --git a/.github/workflows/tag-release-devcontainer.yml b/.github/workflows/tag-release-devcontainer.yml index 52fca83c..288649fc 100644 --- a/.github/workflows/tag-release-devcontainer.yml +++ b/.github/workflows/tag-release-devcontainer.yml @@ -114,6 +114,7 @@ jobs: with: repository: ${{ github.repository }} ref: ${{ github.sha }} + persist-credentials: true # needed for semantic-release to push tags and commits - name: Checkout semantic-release workflow uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd @@ -279,6 +280,7 @@ jobs: repository: ${{ github.repository }} ref: gh-pages path: gh-pages + persist-credentials: true # needed for push to gh-pages - name: Publish release notes to gh-pages if: ${{ !inputs.dry_run }} @@ -319,5 +321,7 @@ jobs: shell: bash run: | TIMESTAMP=$(date +%s) - VERSION=$(echo ${{ steps.output_version_tag.outputs.VERSION_TAG }} | tr . -) + VERSION=$(echo "${VERSION_TAG}" | tr . -) echo CHANGE_SET_VERSION="$VERSION-$TIMESTAMP" >> "$GITHUB_OUTPUT" + env: + VERSION_TAG: ${{ steps.output_version_tag.outputs.VERSION_TAG }} diff --git a/.github/workflows/update-dev-container-version.yml b/.github/workflows/update-dev-container-version.yml index 661bdec9..be8dffec 100644 --- a/.github/workflows/update-dev-container-version.yml +++ b/.github/workflows/update-dev-container-version.yml @@ -23,6 +23,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: fetch-depth: 0 + persist-credentials: false - name: Load config value id: load-config run: | @@ -98,9 +99,6 @@ jobs: run: | set -euo pipefail - - TARGET_VERSION='${{ steps.resolve-version.outputs.latest_version }}' - if [[ "$TARGET_VERSION" == "$DEVCONTAINER_VERSION" ]]; then echo "IMAGE_VERSION is already up to date (${DEVCONTAINER_VERSION})" exit 0 @@ -118,16 +116,16 @@ jobs: config = json.loads(config_file.read_text()) - config['build']['args']['IMAGE_VERSION'] = '${{ - steps.resolve-version.outputs.latest_version }}' + config['build']['args']['IMAGE_VERSION'] = '${TARGET_VERSION}' config_file.write_text(json.dumps(config, indent=2) + '\n') PY - echo "Updated IMAGE_VERSION from ${DEVCONTAINER_VERSION} to - ${LATEST_DEVCONTAINER_VERSION}" + echo "Updated IMAGE_VERSION from ${DEVCONTAINER_VERSION} to ${TARGET_VERSION}" + env: + TARGET_VERSION: "${{ steps.resolve-version.outputs.latest_version }}" - name: Create GitHub App Token uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 id: generate-token diff --git a/zizmor.yml b/zizmor.yml index 94956500..405c52de 100644 --- a/zizmor.yml +++ b/zizmor.yml @@ -17,6 +17,12 @@ rules: - quality-checks-devcontainer.yml:190:29 - dependabot-auto-approve-and-merge.yml:24:31 - dependabot-auto-approve-and-merge.yml:25:36 + - tag-release-devcontainer.yml:229:34 + - tag-release-devcontainer.yml:235:35 + - tag-release-devcontainer.yml:241:34 + - tag-release-devcontainer.yml:249:35 + - update-dev-container-version.yml:136:24 + - update-dev-container-version.yml:137:29 unpinned-images: ignore: - quality-checks-devcontainer.yml:32:7 @@ -24,3 +30,4 @@ rules: - quality-checks-devcontainer.yml:285:7 - quality-checks-devcontainer.yml:328:7 - tag-release-devcontainer.yml:89:13 + - quality-checks-devcontainer.yml:330:7 From ef034691c0df5e81fdfb0def4204df152133e5ba Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Mon, 30 Mar 2026 13:09:24 +0000 Subject: [PATCH 03/42] fix workflows --- .../workflows/quality-checks-devcontainer.yml | 1 + .../workflows/tag-release-devcontainer.yml | 1 + zizmor.yml | 38 +++++++++++++------ 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index 89f2610c..ce2c2f32 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -46,6 +46,7 @@ jobs: with: ref: ${{ env.BRANCH_NAME }} fetch-depth: 0 + persist-credentials: false - &setup_npmrc name: Setting up .npmrc diff --git a/.github/workflows/tag-release-devcontainer.yml b/.github/workflows/tag-release-devcontainer.yml index 288649fc..f0181030 100644 --- a/.github/workflows/tag-release-devcontainer.yml +++ b/.github/workflows/tag-release-devcontainer.yml @@ -128,6 +128,7 @@ jobs: release.config.cjs releaseNotesTemplates/commit.hbs packages/ + persist-credentials: false - name: Install semantic release dependencies globally run: | cd common_workflow_config diff --git a/zizmor.yml b/zizmor.yml index 405c52de..7c0b443d 100644 --- a/zizmor.yml +++ b/zizmor.yml @@ -4,7 +4,7 @@ rules: days: 3 secrets-outside-env: ignore: - # this workflow uses secrets outside of an environment + # these workflows use secrets outside of an environment because it is passed into the workflow - tag-release-devcontainer.yml:108:39 - tag-release-devcontainer.yml:228:34 - tag-release-devcontainer.yml:234:35 @@ -12,22 +12,36 @@ rules: - tag-release-devcontainer.yml:248:35 - update-dev-container-version.yml:135:24 - update-dev-container-version.yml:136:29 - - quality-checks-devcontainer.yml:210:28 - - quality-checks-devcontainer.yml:203:28 - - quality-checks-devcontainer.yml:190:29 + - quality-checks-devcontainer.yml:211:28 + - quality-checks-devcontainer.yml:204:28 + - quality-checks-devcontainer.yml:191:29 - dependabot-auto-approve-and-merge.yml:24:31 - dependabot-auto-approve-and-merge.yml:25:36 - - tag-release-devcontainer.yml:229:34 - - tag-release-devcontainer.yml:235:35 - - tag-release-devcontainer.yml:241:34 - - tag-release-devcontainer.yml:249:35 + - tag-release-devcontainer.yml:230:34 + - tag-release-devcontainer.yml:236:35 + - tag-release-devcontainer.yml:242:34 + - tag-release-devcontainer.yml:250:35 - update-dev-container-version.yml:136:24 - update-dev-container-version.yml:137:29 + - update-dev-container-version.yml:133:24 + - update-dev-container-version.yml:134:29 unpinned-images: + # these workflows use unpinned images because they are using a full image passed in that contains the tag ignore: - quality-checks-devcontainer.yml:32:7 - - quality-checks-devcontainer.yml:215:7 - - quality-checks-devcontainer.yml:285:7 - - quality-checks-devcontainer.yml:328:7 + - quality-checks-devcontainer.yml:216:7 + - quality-checks-devcontainer.yml:286:7 + - quality-checks-devcontainer.yml:329:7 - tag-release-devcontainer.yml:89:13 - - quality-checks-devcontainer.yml:330:7 + - quality-checks-devcontainer.yml:331:7 + excessive-permissions: + # these are possible excessive permissions but need time to work out if they are actually excessive or not + ignore: + - pull_request.yml:1:1 + - pull_request.yml:11:3 + - pull_request.yml:18:3 + - pull_request.yml:21:3 + - pull_request.yml:26:3 + - release.yml:1:1 + - release.yml:11:3 + - release.yml:13:3 From bc651abe69939a21be89455437bf9405e14a621f Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 06:23:23 +0000 Subject: [PATCH 04/42] run new checks --- .devcontainer/devcontainer.json | 4 ++ .../workflows/quality-checks-devcontainer.yml | 65 +++---------------- 2 files changed, 12 insertions(+), 57 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index d71c2158..2211e7fa 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -6,7 +6,11 @@ "args": { "DOCKER_GID": "${env:DOCKER_GID:}", "IMAGE_NAME": "node_24_python_3_14", +<<<<<<< Updated upstream "IMAGE_VERSION": "pr-68-7f136dd", +======= + "IMAGE_VERSION": "pr-69-0337303", +>>>>>>> Stashed changes "USER_UID": "${localEnv:USER_ID:}", "USER_GID": "${localEnv:GROUP_ID:}" }, diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index ce2c2f32..378c05b3 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -122,14 +122,7 @@ jobs: fi - name: Check licenses run: | - make trivy-license-check - - - name: Show license scan output - if: always() - run: | - if [ -f license_scan.txt ]; then - cat .trivy_out/license_scan.txt - fi + make grant-scan - name: Run code lint run: | make lint @@ -141,51 +134,19 @@ jobs: - name: Run unit tests run: | make test - - name: make generate sbom + - name: Generate sbom run: | - make trivy-generate-sbom + make syft-generate-sbom-dev-dependencies - name: Upload sbom uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f with: - name: sbom.cdx.json - path: .trivy_out/sbom.cdx.json + name: sbom.dev.cdx.json + path: .sbom/sbom.dev.cdx.json - - name: Check python vulnerabilities - if: ${{ steps.check_languages.outputs.uses_poetry == 'true' }} - continue-on-error: ${{ github.actor == 'dependabot[bot]' }} + - name: Check vulnerabilities run: | - make trivy-scan-python + make grype-scan-dev-dependencies - - name: Check node vulnerabilities - if: ${{ steps.check_languages.outputs.uses_node == 'true' }} - continue-on-error: ${{ github.actor == 'dependabot[bot]' }} - run: | - make trivy-scan-node - - name: Check go vulnerabilities - if: ${{ steps.check_languages.outputs.uses_go == 'true' }} - continue-on-error: ${{ github.actor == 'dependabot[bot]' }} - run: | - make trivy-scan-go - - name: Check java vulnerabilities - if: ${{ steps.check_languages.outputs.uses_java == 'true' }} - continue-on-error: ${{ github.actor == 'dependabot[bot]' }} - run: | - make trivy-scan-java - - name: Show vulnerability output - if: always() - run: | - if [ -f .trivy_out/dependency_results_python.txt ]; then - cat .trivy_out/dependency_results_python.txt - fi - if [ -f .trivy_out/dependency_results_node.txt ]; then - cat .trivy_out/dependency_results_node.txt - fi - if [ -f .trivy_out/dependency_results_java.txt ]; then - cat .trivy_out/dependency_results_java.txt - fi - if [ -f .trivy_out/dependency_results_go.txt ]; then - cat .trivy_out/dependency_results_go.txt - fi - name: "check is SONAR_TOKEN exists" env: super_secret: ${{ secrets.SONAR_TOKEN }} @@ -311,17 +272,7 @@ jobs: - name: Check docker vulnerabilities continue-on-error: ${{ github.actor == 'dependabot[bot]' }} run: | - make trivy-scan-docker - env: - DOCKER_IMAGE: ${{ matrix.docker_image }} - - - name: Show docker vulnerability output - if: always() - run: | - echo "Scan output for ${DOCKER_IMAGE}" - if [ -f .trivy_out/dependency_results_docker.txt ]; then - cat .trivy_out/dependency_results_docker.txt - fi + make grype-scan-docker-image env: DOCKER_IMAGE: ${{ matrix.docker_image }} From df02e8299e120a70479b14b4a6c018672707831f Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 06:26:39 +0000 Subject: [PATCH 05/42] fix it --- .github/workflows/sync_copilot.yml | 2 ++ zizmor.yml | 32 ++++++------------------------ 2 files changed, 8 insertions(+), 26 deletions(-) diff --git a/.github/workflows/sync_copilot.yml b/.github/workflows/sync_copilot.yml index dc78b993..652b40b0 100644 --- a/.github/workflows/sync_copilot.yml +++ b/.github/workflows/sync_copilot.yml @@ -28,12 +28,14 @@ jobs: with: ref: ${{ inputs.calling_repo_base_branch }} fetch-depth: 0 + persist-credentials: false - name: Checkout central repo code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: ref: ${{ inputs.common_workflows_ref }} fetch-depth: 0 + persist-credentials: false path: eps-common-workflows repository: NHSDigital/eps-common-workflows sparse-checkout: | diff --git a/zizmor.yml b/zizmor.yml index 7c0b443d..3e6ed945 100644 --- a/zizmor.yml +++ b/zizmor.yml @@ -5,35 +5,15 @@ rules: secrets-outside-env: ignore: # these workflows use secrets outside of an environment because it is passed into the workflow - - tag-release-devcontainer.yml:108:39 - - tag-release-devcontainer.yml:228:34 - - tag-release-devcontainer.yml:234:35 - - tag-release-devcontainer.yml:240:34 - - tag-release-devcontainer.yml:248:35 - - update-dev-container-version.yml:135:24 - - update-dev-container-version.yml:136:29 - - quality-checks-devcontainer.yml:211:28 - - quality-checks-devcontainer.yml:204:28 - - quality-checks-devcontainer.yml:191:29 - - dependabot-auto-approve-and-merge.yml:24:31 - - dependabot-auto-approve-and-merge.yml:25:36 - - tag-release-devcontainer.yml:230:34 - - tag-release-devcontainer.yml:236:35 - - tag-release-devcontainer.yml:242:34 - - tag-release-devcontainer.yml:250:35 - - update-dev-container-version.yml:136:24 - - update-dev-container-version.yml:137:29 - - update-dev-container-version.yml:133:24 - - update-dev-container-version.yml:134:29 + - tag-release-devcontainer.yml + - update-dev-container-version.yml + - quality-checks-devcontainer.yml + - dependabot-auto-approve-and-merge.yml unpinned-images: # these workflows use unpinned images because they are using a full image passed in that contains the tag ignore: - - quality-checks-devcontainer.yml:32:7 - - quality-checks-devcontainer.yml:216:7 - - quality-checks-devcontainer.yml:286:7 - - quality-checks-devcontainer.yml:329:7 - - tag-release-devcontainer.yml:89:13 - - quality-checks-devcontainer.yml:331:7 + - quality-checks-devcontainer.yml + - tag-release-devcontainer.yml excessive-permissions: # these are possible excessive permissions but need time to work out if they are actually excessive or not ignore: From 255be1631000e3745864d4ffb38e7a018d07e4b7 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 06:27:02 +0000 Subject: [PATCH 06/42] fix it --- .devcontainer/devcontainer.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 2211e7fa..d69392a5 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -6,11 +6,7 @@ "args": { "DOCKER_GID": "${env:DOCKER_GID:}", "IMAGE_NAME": "node_24_python_3_14", -<<<<<<< Updated upstream - "IMAGE_VERSION": "pr-68-7f136dd", -======= "IMAGE_VERSION": "pr-69-0337303", ->>>>>>> Stashed changes "USER_UID": "${localEnv:USER_ID:}", "USER_GID": "${localEnv:GROUP_ID:}" }, From ff3a0cecf4a3a4a759a85850b6b195875dfbc565 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 07:15:36 +0000 Subject: [PATCH 07/42] comment out licence --- .github/workflows/quality-checks-devcontainer.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index 378c05b3..7259765f 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -122,7 +122,9 @@ jobs: fi - name: Check licenses run: | - make grant-scan + echo "Not currently implemented" + exit 0 + # make grant-scan - name: Run code lint run: | make lint From d2f50a9b19cee6d1e6459e3cb496d10fc1e50ebc Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 07:23:37 +0000 Subject: [PATCH 08/42] suppress --- .gitignore | 1 + .grype.yaml | 6 ++++++ 2 files changed, 7 insertions(+) create mode 100644 .grype.yaml diff --git a/.gitignore b/.gitignore index 0ed3cb41..5f663f85 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ release_notes .venv .asdf .trivy_out +.sbom diff --git a/.grype.yaml b/.grype.yaml new file mode 100644 index 00000000..d59c9b25 --- /dev/null +++ b/.grype.yaml @@ -0,0 +1,6 @@ +ignore: + # undici + - vulnerability: GHSA-v9p9-hfj2-hcw8 + - vulnerability: GHSA-vrm6-8vpv-qv8q + # picomatch + - vulnerability: GHSA-c2c7-rcm5-vvqj From cf9ffd9fa63284b334755f47ba8bb0c315f99319 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 14:49:39 +0000 Subject: [PATCH 09/42] use published image --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index d69392a5..635b1bcf 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -6,7 +6,7 @@ "args": { "DOCKER_GID": "${env:DOCKER_GID:}", "IMAGE_NAME": "node_24_python_3_14", - "IMAGE_VERSION": "pr-69-0337303", + "IMAGE_VERSION": "v1.4.2", "USER_UID": "${localEnv:USER_ID:}", "USER_GID": "${localEnv:GROUP_ID:}" }, From beb31fa1f78334e370acf949fdaa7b1a2593e0db Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 14:50:57 +0000 Subject: [PATCH 10/42] fix --- .github/workflows/quality-checks-devcontainer.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index 7259765f..378c05b3 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -122,9 +122,7 @@ jobs: fi - name: Check licenses run: | - echo "Not currently implemented" - exit 0 - # make grant-scan + make grant-scan - name: Run code lint run: | make lint From afe5c7dae40dd32ce90a7f1fc60a7ed2d53b6797 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 15:14:53 +0000 Subject: [PATCH 11/42] remove 3 days --- .github/workflows/quality-checks.properties.json | 15 --------------- zizmor.yml | 3 --- 2 files changed, 18 deletions(-) delete mode 100644 .github/workflows/quality-checks.properties.json diff --git a/.github/workflows/quality-checks.properties.json b/.github/workflows/quality-checks.properties.json deleted file mode 100644 index 0eed82a5..00000000 --- a/.github/workflows/quality-checks.properties.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "Quality Checks Workflow", - "description": "A workflow template for running quality checks including linting, testing, and SBOM generation.", - "iconName": "octicon check", - "categories": [ - "Continuous integration", - "Security" - ], - "filePatterns": [ - "^Makefile$", - "^\\.tool-versions$", - "^package\\.json$" - ] - } - \ No newline at end of file diff --git a/zizmor.yml b/zizmor.yml index 3e6ed945..d9676a5c 100644 --- a/zizmor.yml +++ b/zizmor.yml @@ -1,7 +1,4 @@ rules: - dependabot-cooldown: - config: - days: 3 secrets-outside-env: ignore: # these workflows use secrets outside of an environment because it is passed into the workflow From 2685c974bd02dd1449ba7102c155d03d2fa4ef5c Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 17:08:02 +0000 Subject: [PATCH 12/42] fix permissions --- .github/workflows/pull_request.yml | 11 +++++++++++ .github/workflows/quality-checks-devcontainer.yml | 4 +++- .github/workflows/release.yml | 8 ++++++++ zizmor.yml | 11 ----------- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 46429bed..ddf44e61 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -7,10 +7,14 @@ on: env: BRANCH_NAME: ${{ github.event.pull_request.head.ref }} +permissions: {} jobs: dependabot-auto-approve-and-merge: needs: quality_checks uses: ./.github/workflows/dependabot-auto-approve-and-merge.yml + permissions: + contents: write + pull-requests: write secrets: AUTOMERGE_APP_ID: ${{ secrets.AUTOMERGE_APP_ID }} AUTOMERGE_PEM: ${{ secrets.AUTOMERGE_PEM }} @@ -20,12 +24,19 @@ jobs: get_config_values: uses: ./.github/workflows/get-repo-config.yml + permissions: + attestations: read + contents: read + packages: read with: verify_published_from_main_image: false quality_checks: uses: ./.github/workflows/quality-checks-devcontainer.yml needs: [get_config_values] + permissions: + contents: read + id-token: write with: pinned_image: ${{ needs.get_config_values.outputs.pinned_image }} secrets: diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index 378c05b3..97927f5c 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -24,7 +24,9 @@ on: pinned_image: type: string required: true - +permissions: + contents: read + id-token: write jobs: quality_checks: runs-on: ubuntu-22.04 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4b752eaf..e70da328 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,12 +7,20 @@ on: env: BRANCH_NAME: ${{ github.event.ref.BRANCH_NAME }} +permissions: {} jobs: get_config_values: uses: ./.github/workflows/get-repo-config.yml + permissions: + attestations: read + contents: read + packages: read quality_checks: needs: [get_config_values] uses: ./.github/workflows/quality-checks-devcontainer.yml + permissions: + contents: read + id-token: write with: pinned_image: ${{ needs.get_config_values.outputs.pinned_image }} secrets: diff --git a/zizmor.yml b/zizmor.yml index d9676a5c..911dda46 100644 --- a/zizmor.yml +++ b/zizmor.yml @@ -11,14 +11,3 @@ rules: ignore: - quality-checks-devcontainer.yml - tag-release-devcontainer.yml - excessive-permissions: - # these are possible excessive permissions but need time to work out if they are actually excessive or not - ignore: - - pull_request.yml:1:1 - - pull_request.yml:11:3 - - pull_request.yml:18:3 - - pull_request.yml:21:3 - - pull_request.yml:26:3 - - release.yml:1:1 - - release.yml:11:3 - - release.yml:13:3 From 2ce5b15a532d1612fe48449e7a5c6a3e930d5cea Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 17:10:33 +0000 Subject: [PATCH 13/42] fix --- .github/workflows/pull_request.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index ddf44e61..66dd5540 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -21,6 +21,8 @@ jobs: pr_title_format_check: uses: ./.github/workflows/pr_title_check.yml + permissions: + pull-requests: write get_config_values: uses: ./.github/workflows/get-repo-config.yml From 0d726622c9b78ccd7e20cf34438a73ada86bc502 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 17:15:46 +0000 Subject: [PATCH 14/42] more --- .github/workflows/quality-checks-devcontainer.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index 97927f5c..64233c8b 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -27,6 +27,7 @@ on: permissions: contents: read id-token: write + packages: read jobs: quality_checks: runs-on: ubuntu-22.04 From 546fcd3cb4cfc2857d5ba9bbc4318cf3006a22e3 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 17:17:29 +0000 Subject: [PATCH 15/42] fix --- .github/workflows/pull_request.yml | 1 + .github/workflows/release.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 66dd5540..5b28367f 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -39,6 +39,7 @@ jobs: permissions: contents: read id-token: write + packages: read with: pinned_image: ${{ needs.get_config_values.outputs.pinned_image }} secrets: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e70da328..0b95dfc3 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,6 +21,7 @@ jobs: permissions: contents: read id-token: write + packages: read with: pinned_image: ${{ needs.get_config_values.outputs.pinned_image }} secrets: From cc9305ef2df55172f28ff74a55c9a3212df7570d Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 17:20:29 +0000 Subject: [PATCH 16/42] fix docs --- .../workflows/quality-checks-devcontainer.yml | 2 +- README.md | 18 ------------------ trivy.yaml | 1 - 3 files changed, 1 insertion(+), 20 deletions(-) delete mode 100644 trivy.yaml diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index 64233c8b..bafbfe45 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -76,7 +76,7 @@ jobs: run: | make actionlint - - name: Check language tools used and setup trivy config + - name: Check language tools used id: check_languages run: | if [ -f "pyproject.toml" ] && grep -q '\[tool.poetry\]' "pyproject.toml"; then diff --git a/README.md b/README.md index 4ece54c1..5118ed2b 100644 --- a/README.md +++ b/README.md @@ -19,27 +19,9 @@ The workflows that are available to use are ## Other Docs -- [Adding Exclusions to Trivy Scanning](#adding-exclusions-to-trivy-scanning) - [Secret Scanning Docker](#secret-scanning-docker) - [Run All Releases](#run-all-releases) -## Adding Exclusions to Trivy Scanning -The quality checks job uses Trivy to scan for vulnerabilities. -There may be times you want to add an exclusion for a known vulnerability that we are happy to accept -To do this, in the calling repo, add trivy.yaml with this content -``` -ignorefile: ".trivyignore.yaml" -``` -and add a .trivyignore.yaml with this content -``` -vulnerabilities: - - id: CVE-2026-24842 - paths: - - "package-lock.json" - statement: downstream dependency for tar - waiting for new npm release - expired_at: 2026-06-01 -``` -See https://trivy.dev/docs/latest/configuration/filtering/#trivyignoreyaml for more details ## Combine Dependabot PRs diff --git a/trivy.yaml b/trivy.yaml deleted file mode 100644 index eb243375..00000000 --- a/trivy.yaml +++ /dev/null @@ -1 +0,0 @@ -ignorefile: ".trivyignore.yaml" From 332f36101225611e54bb3341c739926def4a785e Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 17:25:17 +0000 Subject: [PATCH 17/42] add zizmor --- .github/workflows/quality-checks-devcontainer.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index bafbfe45..3094b7e3 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -76,6 +76,10 @@ jobs: run: | make actionlint + - name: Run zizmor + run: | + make zizmor + - name: Check language tools used id: check_languages run: | From e0dad28197466d54e07c1fb275ac231340b8d8c0 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 17:56:42 +0000 Subject: [PATCH 18/42] copy grant config --- .github/workflows/quality-checks-devcontainer.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index 3094b7e3..4172e1b3 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -39,9 +39,10 @@ jobs: shell: bash steps: - &init_tool_versions - name: copy .tool-versions + name: copy .tool-versions and .grant.yaml from devcontainer user to runner home directory run: | cp /home/vscode/.tool-versions "$HOME/.tool-versions" + cp /home/vscode/.grant.yaml "$HOME/.grant.yaml" - &checkout name: Checkout code From 7abf7e3c769e4f51007f9e1bdd76f4f7df050bb4 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 18:20:01 +0000 Subject: [PATCH 19/42] copy zizmor --- .github/workflows/quality-checks-devcontainer.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index 4172e1b3..de43db4d 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -39,10 +39,12 @@ jobs: shell: bash steps: - &init_tool_versions - name: copy .tool-versions and .grant.yaml from devcontainer user to runner home directory + name: copy needed files from devcontainer user to runner home directory run: | cp /home/vscode/.tool-versions "$HOME/.tool-versions" cp /home/vscode/.grant.yaml "$HOME/.grant.yaml" + mkdir -p "$HOME/.local/bin" + cp /home/vscode/.local/bin/zizmor "$HOME/.local/bin/zizmor" - &checkout name: Checkout code From 56bba138566789c92f04ab5623717c0f5411000b Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 18:21:47 +0000 Subject: [PATCH 20/42] permissions to job level --- .../workflows/quality-checks-devcontainer.yml | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index de43db4d..ad9bc668 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -24,13 +24,16 @@ on: pinned_image: type: string required: true -permissions: - contents: read - id-token: write - packages: read + +permissions: {} + jobs: quality_checks: runs-on: ubuntu-22.04 + permissions: + contents: read + id-token: write + packages: read container: image: ${{ inputs.pinned_image }} options: --user 1001:1001 --group-add 128 @@ -251,6 +254,10 @@ jobs: echo "images=$NORMALIZED" >> "$GITHUB_OUTPUT" docker_vulnerability_scan: + permissions: + contents: read + id-token: write + packages: read runs-on: ubuntu-22.04 needs: get_docker_images_to_scan container: @@ -287,6 +294,10 @@ jobs: DOCKER_IMAGE: ${{ matrix.docker_image }} IaC-validation: + permissions: + contents: read + id-token: write + packages: read runs-on: ubuntu-22.04 container: image: ${{ inputs.pinned_image }} From 7607dfc734c0bab8085c690855a21333af334011 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 18:24:06 +0000 Subject: [PATCH 21/42] really tighten permissions --- .github/workflows/dependabot-auto-approve-and-merge.yml | 8 ++++---- .github/workflows/get-repo-config.yml | 1 + .github/workflows/pr_title_check.yml | 1 + .github/workflows/sync_copilot.yml | 1 + .github/workflows/tag-release-devcontainer.yml | 2 ++ .github/workflows/update-dev-container-version.yml | 1 + 6 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/dependabot-auto-approve-and-merge.yml b/.github/workflows/dependabot-auto-approve-and-merge.yml index 27a4fab2..54e73182 100644 --- a/.github/workflows/dependabot-auto-approve-and-merge.yml +++ b/.github/workflows/dependabot-auto-approve-and-merge.yml @@ -8,13 +8,13 @@ on: AUTOMERGE_PEM: required: true -permissions: - pull-requests: write - contents: write - +permissions: {} jobs: dependabot: runs-on: ubuntu-22.04 + permissions: + pull-requests: write + contents: write if: (github.event.pull_request.user.login == 'dependabot[bot]' || github.event.pull_request.user.login == 'eps-create-pull-request[bot]') && github.repository == github.event.pull_request.head.repo.full_name steps: - name: Get token from Github App diff --git a/.github/workflows/get-repo-config.yml b/.github/workflows/get-repo-config.yml index 916b5267..25244c53 100644 --- a/.github/workflows/get-repo-config.yml +++ b/.github/workflows/get-repo-config.yml @@ -39,6 +39,7 @@ on: description: Resolved digest for the supplied image reference value: ${{ jobs.verify_attestation.outputs.resolved_digest }} +permissions: {} jobs: get_config_values: runs-on: ubuntu-22.04 diff --git a/.github/workflows/pr_title_check.yml b/.github/workflows/pr_title_check.yml index f8fb08ef..9523196e 100644 --- a/.github/workflows/pr_title_check.yml +++ b/.github/workflows/pr_title_check.yml @@ -3,6 +3,7 @@ name: PR Title Check on: workflow_call: +permissions: {} jobs: pr_title_format_check: runs-on: ubuntu-22.04 diff --git a/.github/workflows/sync_copilot.yml b/.github/workflows/sync_copilot.yml index f47c62b8..a010386d 100644 --- a/.github/workflows/sync_copilot.yml +++ b/.github/workflows/sync_copilot.yml @@ -5,6 +5,7 @@ on: schedule: - cron: "0 6 * * 1" +permissions: {} jobs: sync-copilot-instructions: runs-on: ubuntu-22.04 diff --git a/.github/workflows/tag-release-devcontainer.yml b/.github/workflows/tag-release-devcontainer.yml index f0181030..22224db8 100644 --- a/.github/workflows/tag-release-devcontainer.yml +++ b/.github/workflows/tag-release-devcontainer.yml @@ -79,6 +79,8 @@ on: PYPI_TOKEN: required: false description: "PyPI token to publish packages" + +permissions: {} jobs: tag_release: permissions: diff --git a/.github/workflows/update-dev-container-version.yml b/.github/workflows/update-dev-container-version.yml index 765cd09c..a9546b48 100644 --- a/.github/workflows/update-dev-container-version.yml +++ b/.github/workflows/update-dev-container-version.yml @@ -4,6 +4,7 @@ on: workflow_dispatch: schedule: - cron: "0 6 * * 4" + permissions: {} jobs: From 525368dedc30184fda6787db43789a6fcdce5198 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 18:33:11 +0000 Subject: [PATCH 22/42] copy zizmor --- .github/workflows/quality-checks-devcontainer.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index ad9bc668..287cb4c9 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -42,12 +42,12 @@ jobs: shell: bash steps: - &init_tool_versions - name: copy needed files from devcontainer user to runner home directory + name: copy needed files from devcontainer user to runner home directory or bin directory run: | cp /home/vscode/.tool-versions "$HOME/.tool-versions" cp /home/vscode/.grant.yaml "$HOME/.grant.yaml" mkdir -p "$HOME/.local/bin" - cp /home/vscode/.local/bin/zizmor "$HOME/.local/bin/zizmor" + sudo cp /home/vscode/.local/bin/zizmor /usr/local/bin/zizmor - &checkout name: Checkout code From 41d3587b28595286e47bde78002a401ec1ba9626 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 18:44:57 +0000 Subject: [PATCH 23/42] update readme --- .../workflows/tag-release-devcontainer.yml | 2 +- README.md | 211 ------------------ 2 files changed, 1 insertion(+), 212 deletions(-) diff --git a/.github/workflows/tag-release-devcontainer.yml b/.github/workflows/tag-release-devcontainer.yml index 22224db8..8c555c8f 100644 --- a/.github/workflows/tag-release-devcontainer.yml +++ b/.github/workflows/tag-release-devcontainer.yml @@ -116,7 +116,7 @@ jobs: with: repository: ${{ github.repository }} ref: ${{ github.sha }} - persist-credentials: true # needed for semantic-release to push tags and commits + persist-credentials: ${{ ! inputs.dry_run }} # only persist credentials when not running in dry-run mode - name: Checkout semantic-release workflow uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd diff --git a/README.md b/README.md index 5118ed2b..1e5e796f 100644 --- a/README.md +++ b/README.md @@ -6,69 +6,17 @@ The workflows that are available to use are ## Workflow Index -- [Combine Dependabot PRs](#combine-dependabot-prs) - [Dependabot Auto Approve and Merge](#dependabot-auto-approve-and-merge) -- [Sync copilot instructions](#sync-copilot-instructions) - [PR Title Check](#pr-title-check) - [Get Repo Config](#get-repo-config) -- [Quality Checks](#quality-checks) - [Quality Checks - Dev Container Version](#quality-checks---dev-container-version) -- [Update Dev Container Version](#update-dev-container-version) -- [Tag Release](#tag-release) - [Tag Release - Devcontainer Version](#tag-release---devcontainer-version) ## Other Docs -- [Secret Scanning Docker](#secret-scanning-docker) - [Run All Releases](#run-all-releases) -## Combine Dependabot PRs - -This workflow can be called to combine multiple open Dependabot PRs into a single PR. - -#### Inputs - -- `branchPrefix`: Branch prefix to find combinable PRs based on. Default: `dependabot` -- `mustBeGreen`: Only combine PRs that are green (status is success). Default: `true` -- `combineBranchName`: Name of the branch to combine PRs into. Default: `combine-dependabot-PRs` -- `ignoreLabel`: Exclude PRs with this label. Default: `nocombine` - -#### Example - -```yaml -name: Combine Dependabot PRs - -on: - workflow_dispatch: - inputs: - branchPrefix: - description: "Branch prefix to find combinable PRs based on" - required: true - type: string - mustBeGreen: - description: "Only combine PRs that are green (status is success)" - required: true - type: boolean - combineBranchName: - description: "Name of the branch to combine PRs into" - required: true - type: string - ignoreLabel: - description: "Exclude PRs with this label" - required: true - type: string - -jobs: - combine-dependabot-prs: - uses: NHSDigital/eps-common-workflows/.github/workflows/combine-dependabot-prs.yml@f5c8313a10855d0cc911db6a9cd666494c00045a - with: - branchPrefix: ${{ github.event.inputs.branchPrefix }} - mustBeGreen: ${{ github.event.inputs.mustBeGreen }} - combineBranchName: ${{ github.event.inputs.combineBranchName }} - ignoreLabel: ${{ github.event.inputs.ignoreLabel }} -``` - ## Dependabot Auto Approve and Merge This workflow can be called to automatically approve and merge Dependabot PRs as part of the pull request workflow. @@ -92,40 +40,6 @@ jobs: AUTOMERGE_APP_ID: ${{ secrets.AUTOMERGE_APP_ID }} AUTOMERGE_PEM: ${{ secrets.AUTOMERGE_PEM }} ``` -## Sync copilot instructions -This workflow syncs Copilot instructions from this repo into another repo and opens a PR with the changes. -It uses the environment secrets CREATE_PULL_REQUEST_APP_ID and CREATE_PULL_REQUEST_PEM that are defined in the create_pull_request environment in each repo - -#### Inputs - -- `common_workflows_ref`: Branch in common workflows repo to sync from. Default: `main` -- `calling_repo_base_branch`: The base branch in the calling repository. Default: `main`. - - - -#### Example - -```yaml -name: Sync Copilot Instructions - -on: - workflow_dispatch: - inputs: - common_workflows_ref: - description: "Branch to sync from" - required: false - type: string - default: main - -jobs: - sync-copilot: - uses: NHSDigital/eps-common-workflows/.github/workflows/sync_copilot.yml@f5c8313a10855d0cc911db6a9cd666494c00045a - with: - ref: ${{ github.event.inputs.common_workflows_ref }} - secrets: - CREATE_PULL_REQUEST_APP_ID: ${{ secrets.CREATE_PULL_REQUEST_APP_ID }} - CREATE_PULL_REQUEST_PEM: ${{ secrets.CREATE_PULL_REQUEST_PEM }} -``` ## PR Title Check This workflow checks that all pull requests have a title that matches the required format, and comments on the PR with a link to the relevant ticket if a ticket reference is found. @@ -180,53 +94,6 @@ jobs: uses: NHSDigital/eps-common-workflows/.github/workflows/get-repo-config.yml@f5c8313a10855d0cc911db6a9cd666494c00045a ``` -## Quality Checks -This workflow runs common quality checks. -To use this, you must have the following Makefile targets defined -- install -- lint -- test -- install-node (only for cdk projects) -- compile (only for cdk projects) -- cdk-synth (only for cdk projects) -- docker-build (only if run_docker_scan is set to true) - -#### Inputs - -- `install_java`: Whether to install Java or not -- `run_sonar`: Whether to run Sonar checks or not. -- `asdfVersion`: Override the version of asdf to install. -- `reinstall_poetry`: If you are using this from a primarily Python based project, you should set this to true to force a poetry reinstallation after Python is installed -- `run_docker_scan`: whether to run a scan of Docker images -- `docker_images`: csv list of Docker images to scan. These must match images produced by make docker-build - -#### Secret Inputs -- `SONAR_TOKEN`: Token used to authenticate to Sonar - -#### Outputs - -None - -#### Example - -To use this workflow in your repository, call it from another workflow file: - -```yaml -name: Release - -on: - workflow_dispatch: - -jobs: - quality_checks: - uses: NHSDigital/eps-common-workflows/.github/workflows/quality-checks.yml@f5c8313a10855d0cc911db6a9cd666494c00045a - needs: [get_asdf_version] - with: - asdfVersion: ${{ needs.get_asdf_version.outputs.asdf_version }} - secrets: - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} -``` - ## Quality Checks - Dev Container Version This workflow runs common quality checks using a prebuilt devcontainer (https://github.com/NHSDigital/eps-devcontainers). To use this, you must have overridden any common makefile targets described in https://github.com/NHSDigital/eps-devcontainers?tab=readme-ov-file#common-makefile-targets @@ -268,46 +135,6 @@ jobs: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} ``` -## Update Dev Container Version -This workflow updates `.devcontainer/devcontainer.json` with the latest published `v*` version for your configured devcontainer image from GHCR, then opens (or updates) a pull request with that change. - -#### Requirements - -- `.devcontainer/devcontainer.json` must include `build.args.IMAGE_NAME` and `build.args.IMAGE_VERSION`. -- `CREATE_PULL_REQUEST_APP_ID` and `CREATE_PULL_REQUEST_PEM` secrets must be configured so the workflow can create a GitHub App token for PR creation. - -#### Inputs - -- `base_branch`: Target branch for the pull request. Default: `main`. - -#### Secret Inputs - -- `CREATE_PULL_REQUEST_APP_ID`: GitHub App ID used to generate an installation token. -- `CREATE_PULL_REQUEST_PEM`: GitHub App private key used to generate an installation token. - -#### Outputs - -None - -#### Example - -To use this workflow in your repository, call it from another workflow file: - -```yaml -name: Update Devcontainer Version - -on: - workflow_dispatch: - -jobs: - update_devcontainer_version: - uses: NHSDigital/eps-common-workflows/.github/workflows/update-dev-container-version.yml@f5c8313a10855d0cc911db6a9cd666494c00045a - with: - base_branch: main - secrets: - CREATE_PULL_REQUEST_APP_ID: ${{ secrets.CREATE_PULL_REQUEST_APP_ID }} - CREATE_PULL_REQUEST_PEM: ${{ secrets.CREATE_PULL_REQUEST_PEM }} -``` ## Tag Release This workflow uses the semantic-release npm package to generate a new version tag, changelog, and GitHub release for a repo. @@ -400,44 +227,6 @@ jobs: ``` -## Secret Scanning Docker - -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 . -``` -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 add 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 -``` ## Run All Releases From 9e5351b2349a88bb27e0a4d44f81604169f0d0ad Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 18:46:57 +0000 Subject: [PATCH 24/42] update zizmor config --- zizmor.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/zizmor.yml b/zizmor.yml index 911dda46..e427669e 100644 --- a/zizmor.yml +++ b/zizmor.yml @@ -11,3 +11,7 @@ rules: ignore: - quality-checks-devcontainer.yml - tag-release-devcontainer.yml + artipacked: + ignore: + # this is ignored as its based on using an input to the workflow + - tag-release-devcontainer.yml:114:15 From e57ff56c2d2586f52bcf178bde2e1b943a09da1b Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 18:58:12 +0000 Subject: [PATCH 25/42] explicit permissions --- .github/workflows/get-repo-config.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/get-repo-config.yml b/.github/workflows/get-repo-config.yml index 25244c53..19691866 100644 --- a/.github/workflows/get-repo-config.yml +++ b/.github/workflows/get-repo-config.yml @@ -43,6 +43,10 @@ permissions: {} jobs: get_config_values: runs-on: ubuntu-22.04 + permissions: + attestations: read + contents: read + packages: read outputs: tag_format: ${{ steps.load-config.outputs.TAG_FORMAT }} devcontainer_version: ${{ steps.load-config.outputs.DEVCONTAINER_VERSION }} From 5bc995b6d8ddce89fe60e9ddb61d13a5b9ced71c Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 19:00:01 +0000 Subject: [PATCH 26/42] more remove trivy --- .pre-commit-config.yaml | 9 +++++++++ .trivyignore.yaml | 36 ------------------------------------ 2 files changed, 9 insertions(+), 36 deletions(-) delete mode 100644 .trivyignore.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2f7f8656..2e5156cf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,6 +17,14 @@ repos: files: ^(.github) - repo: local hooks: + - id: grype-scan-local + name: Grype scan local changes + entry: make + args: ["grype-scan-local"] + language: system + pass_filenames: false + always_run: true + - id: check-commit-signing name: Check commit signing description: Ensures that commits are GPG signed @@ -45,6 +53,7 @@ repos: - -c - "git-secrets --pre_commit_hook" language: system + - id: lint-githubactions name: Lint github actions entry: make diff --git a/.trivyignore.yaml b/.trivyignore.yaml deleted file mode 100644 index 5376a7b0..00000000 --- a/.trivyignore.yaml +++ /dev/null @@ -1,36 +0,0 @@ -vulnerabilities: - - id: CVE-2026-24842 - paths: - - "package-lock.json" - statement: downstream dependency for tar - waiting for new npm release - expired_at: 2026-06-01 - - id: CVE-2026-26996 - statement: minimatch vulnerability accepted as risk - expired_at: 2026-06-01 - - id: CVE-2026-27903 - statement: minimatch vulnerability accepted as risk - dependency of npm (multiple) - expired_at: 2026-06-01 - - id: CVE-2026-27904 - statement: minimatch vulnerability accepted as risk - dependency of npm (multiple) - expired_at: 2026-06-01 - - id: CVE-2026-26960 - statement: tar vulnerability accepted as risk - expired_at: 2026-06-01 - - id: GHSA-qffp-2rhf-9h96 - statement: tar vulnerability accepted as risk - dependency of npm (multiple) - expired_at: 2026-06-01 - - id: CVE-2026-29786 - statement: tar vulnerability accepted as risk - dependency of npm (multiple) - expired_at: 2026-06-01 - - id: CVE-2026-31802 - statement: tar vulnerability accepted as risk - dependency of npm (multiple) - expired_at: 2026-06-01 - - id: CVE-2026-1526 - statement: undici vulnerability accepted as risk - expired_at: 2026-06-01 - - id: CVE-2026-2229 - statement: undici vulnerability accepted as risk - expired_at: 2026-06-01 - - id: CVE-2026-33036 - statement: fast-xml-parser vulnerability accepted as risk - expired_at: 2026-06-01 From 364ced9b4af7dc3c112812e85ad97e42d0fd2169 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 19:42:17 +0000 Subject: [PATCH 27/42] new devcontainer --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index a2608289..892fae06 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -6,7 +6,7 @@ "args": { "DOCKER_GID": "${env:DOCKER_GID:}", "IMAGE_NAME": "node_24_python_3_14", - "IMAGE_VERSION": "v1.4.2", + "IMAGE_VERSION": "v1.4.4", "USER_UID": "${localEnv:USER_ID:}", "USER_GID": "${localEnv:GROUP_ID:}" }, From 3fdc184cc584afb5772f81211307636b0e1bd694 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Wed, 1 Apr 2026 20:10:16 +0000 Subject: [PATCH 28/42] remove unneeded actions --- .github/workflows/get-repo-config.yml | 1 - .github/workflows/pr_title_check.yml | 37 ------------------- .../workflows/tag-release-devcontainer.yml | 27 +------------- 3 files changed, 1 insertion(+), 64 deletions(-) diff --git a/.github/workflows/get-repo-config.yml b/.github/workflows/get-repo-config.yml index 19691866..d7d7bc52 100644 --- a/.github/workflows/get-repo-config.yml +++ b/.github/workflows/get-repo-config.yml @@ -56,7 +56,6 @@ jobs: - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: - ref: ${{ env.BRANCH_NAME }} fetch-depth: 0 persist-credentials: false diff --git a/.github/workflows/pr_title_check.yml b/.github/workflows/pr_title_check.yml index 9523196e..f26e1f9b 100644 --- a/.github/workflows/pr_title_check.yml +++ b/.github/workflows/pr_title_check.yml @@ -51,43 +51,6 @@ jobs: exit 1 fi - - name: Comment on PR with Jira Link - if: steps.extract_ticket_reference.outcome == 'success' && steps.extract_ticket_reference.outputs.TICKET_REF != 'dependabot' - uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - TICKET_REF: ${{ steps.extract_ticket_reference.outputs.TICKET_REF }} - with: - message: | - This PR is linked to a ticket in an NHS Digital JIRA Project. Here's a handy link to the ticket: - # [${{ env.TICKET_REF }}](https://nhsd-jira.digital.nhs.uk/browse/${{ env.TICKET_REF }}) - comment-tag: pr-link - - - name: Comment on PR for dependabot - if: steps.extract_ticket_reference.outcome == 'success' && steps.extract_ticket_reference.outputs.TICKET_REF == 'dependabot' - uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - message: | - This PR is raised by Dependabot to update a dependency. - comment-tag: pr-link - - - name: Comment on PR for bad format - if: steps.check_prefix.outcome != 'success' || steps.check_ticket_reference.outcome != 'success' - uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - message: | - The PR title does not conform to the required format. - Please ensure your PR title is prefixed with a change type (Fix, Update, New, Breaking, Docs, Build, Upgrade, Chore) - and contains a ticket reference (eg. 'Fix: [AEA-####] - ...', or 'Chore: [dependabot] - ...'), - then push an empty commit or recreate your PR. - See the contributing guide for more details: - https://github.com/NHSDigital/eps-common-workflows/blob/main/CONTRIBUTING.md - comment-tag: pr-link - - name: Fail job due to invalid PR title format if: steps.check_prefix.outcome != 'success' || steps.check_ticket_reference.outcome != 'success' run: | diff --git a/.github/workflows/tag-release-devcontainer.yml b/.github/workflows/tag-release-devcontainer.yml index 8c555c8f..28823353 100644 --- a/.github/workflows/tag-release-devcontainer.yml +++ b/.github/workflows/tag-release-devcontainer.yml @@ -253,29 +253,6 @@ jobs: run: | npx semantic-release --tag-format "${TAG_FORMAT}" - - name: Get release for editing - if: ${{ !inputs.dry_run }} - id: get_release - # version 1.2.4 - uses: cardinalby/git-get-release-action@5172c3a026600b1d459b117738c605fabc9e4e44 - env: - GITHUB_TOKEN: ${{ github.token }} - with: - tag: ${{ steps.output_version_tag.outputs.VERSION_TAG }} - - - name: Edit Release - if: ${{ !inputs.dry_run }} - # version 1.2.0 - uses: irongut/EditRelease@ccf529ad26dddf9996e7dd0f24ca5da4ea507cc2 - with: - token: ${{ secrets.GITHUB_TOKEN }} - id: ${{ steps.get_release.outputs.id }} - body: | - ## Info - [Release workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) - Workflow ID: ${{ github.run_id }} - - It was initialized by [${{ github.event.sender.login }}](${{ github.event.sender.html_url }}) - - name: Checkout gh-pages branch if: ${{ !inputs.dry_run }} uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd @@ -289,7 +266,6 @@ jobs: if: ${{ !inputs.dry_run }} working-directory: gh-pages env: - RELEASE_ID: ${{ steps.get_release.outputs.id }} VERSION_TAG: ${{ steps.output_version_tag.outputs.VERSION_TAG }} GH_REPO: ${{ github.repository }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -299,8 +275,7 @@ jobs: notes_dir="release_notes" mkdir -p "$notes_dir" note_file="$notes_dir/${VERSION_TAG}.md" - - gh api "/repos/${GH_REPO}/releases/${RELEASE_ID}" | jq -r '.body // ""' > "$note_file" + cp ../electronic-prescription-service-api/CHANGELOG.md "$note_file" if [ ! -s "$note_file" ]; then echo "Release notes are empty; skipping gh-pages update." From 11d96f6edacfe28654582c91925158bf856aa626 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 2 Apr 2026 08:21:06 +0000 Subject: [PATCH 29/42] update readme --- README.md | 44 -------------------------------------------- 1 file changed, 44 deletions(-) diff --git a/README.md b/README.md index 1e5e796f..13270b95 100644 --- a/README.md +++ b/README.md @@ -135,50 +135,6 @@ jobs: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} ``` - -## Tag Release -This workflow uses the semantic-release npm package to generate a new version tag, changelog, and GitHub release for a repo. - -#### Inputs - -- `dry_run`: Whether to run in dry_run mode (do not create tags) or not -- `tag_format`: Default `v\\${version}`. A template for the version tag. -- `branch_name`: The branch name to base the release on -- `publish_packages`: comma separated list of package folders to publish to an npm registry -- `asdfVersion`: Override the version of asdf to install. -- `main_branch`: The branch to use for publishing. Defaults to main -- `extra_artifact_name`: optional param to include an extra artifact in the release -- `extra_artifact_id`: optional param of the extra artifact id to include in the release -- `extra_artifact_run_id`: optional param of the run id to download the extra artifact id to include in the release -- `extra_artifact_repository`: optional param to indicate which repo the run to download the artifact was from - -#### Outputs - -- `version_tag`: The version tag created by semantic-release. -- `change_set_version`: A timestamped string that can be used for creating changesets. -- `next_version_tag`: The next version tag that will be created. - -#### Example - -To use this workflow in your repository, call it from another workflow file: - -```yaml -name: Release - -on: - workflow_dispatch: - -jobs: - tag_release: - uses: NHSDigital/eps-common-workflows/.github/workflows/tag-release.yml@f5c8313a10855d0cc911db6a9cd666494c00045a - with: - tag_format: "v\\${version}-beta" - dry_run: true - asdfVersion: 0.18.0 - branch_name: main - publish_packages: "" -``` - ## Tag Release - Devcontainer Version This workflow uses the semantic-release npm package to generate a new version tag, changelog, and GitHub release for a repo. *The devcontainer MUST have Node installed* From 7ae7e1bdd33687f461250e02d073728007e9f35c Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 2 Apr 2026 09:48:10 +0000 Subject: [PATCH 30/42] fix --- .github/CODEOWNERS | 2 ++ .github/workflows/quality-checks-devcontainer.yml | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000..0492a665 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,2 @@ +# restrict access to approving workflow changes +.github/workflows/ @NHSDigital/eps-admins diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index 287cb4c9..df7273f5 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -77,6 +77,8 @@ jobs: make install - name: Run secrets scan run: | + git-secrets --register-aws + git-secrets --add-provider -- cat /usr/share/secrets-scanner/nhsd-rules-deny.txt make secret-scan - name: Run actionlint run: | From 97a731e304f7a91ca1656329a3bab0fc402fd6b6 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 2 Apr 2026 09:53:36 +0000 Subject: [PATCH 31/42] debug --- .github/workflows/quality-checks-devcontainer.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index df7273f5..1cb8a3d8 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -77,8 +77,12 @@ jobs: make install - name: Run secrets scan run: | + echo "Checking for secret scan config" + ls /usr/share/secrets-scanner/nhsd-rules-deny.txt + echo "Registering git-secrets AWS rules" git-secrets --register-aws git-secrets --add-provider -- cat /usr/share/secrets-scanner/nhsd-rules-deny.txt + echo "Running secret scan" make secret-scan - name: Run actionlint run: | From aead0eef8b98eaac235fb813fd6f89d670d4995f Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 2 Apr 2026 09:57:56 +0000 Subject: [PATCH 32/42] more debug --- .github/workflows/quality-checks-devcontainer.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index 1cb8a3d8..633310b5 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -82,6 +82,10 @@ jobs: echo "Registering git-secrets AWS rules" git-secrets --register-aws git-secrets --add-provider -- cat /usr/share/secrets-scanner/nhsd-rules-deny.txt + echo "Checking git-secrets configuration" + git-secrets --list + echo "Checking content of git-secrets rules" + cat /usr/share/secrets-scanner/nhsd-rules-deny.txt echo "Running secret scan" make secret-scan - name: Run actionlint From 2c51ba1accac9e4088c2aec9b5ad6346fa014903 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 2 Apr 2026 10:02:28 +0000 Subject: [PATCH 33/42] even more debug --- .github/workflows/quality-checks-devcontainer.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index 633310b5..dc7abb7c 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -86,6 +86,8 @@ jobs: git-secrets --list echo "Checking content of git-secrets rules" cat /usr/share/secrets-scanner/nhsd-rules-deny.txt + echo "Showing last few commits" + git log -5 --oneline echo "Running secret scan" make secret-scan - name: Run actionlint From 9812406b0013e12e29f84c501f520740f0879dbc Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 2 Apr 2026 10:06:30 +0000 Subject: [PATCH 34/42] scan a different way --- .github/workflows/quality-checks-devcontainer.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index dc7abb7c..06135398 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -89,7 +89,7 @@ jobs: echo "Showing last few commits" git log -5 --oneline echo "Running secret scan" - make secret-scan + git-secrets --scan-history . - name: Run actionlint run: | make actionlint From 6a2b506a9771e2b759c6f817af2825ddd5cae751 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 2 Apr 2026 10:15:58 +0000 Subject: [PATCH 35/42] remove . --- .github/workflows/quality-checks-devcontainer.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index 06135398..69ebcfa7 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -89,7 +89,8 @@ jobs: echo "Showing last few commits" git log -5 --oneline echo "Running secret scan" - git-secrets --scan-history . + git-secrets --scan-history + echo "scan complete" - name: Run actionlint run: | make actionlint From 909b981054452d18b967cdd04a127cf2c27b24d1 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 2 Apr 2026 10:22:40 +0000 Subject: [PATCH 36/42] no branch --- .github/workflows/quality-checks-devcontainer.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index 69ebcfa7..c8136088 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -53,7 +53,6 @@ jobs: name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd with: - ref: ${{ env.BRANCH_NAME }} fetch-depth: 0 persist-credentials: false From c856b025a2247d97c8406d7a820df5e9c22b2480 Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 2 Apr 2026 10:26:49 +0000 Subject: [PATCH 37/42] show bad commit --- .github/workflows/quality-checks-devcontainer.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index c8136088..11702162 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -87,6 +87,8 @@ jobs: cat /usr/share/secrets-scanner/nhsd-rules-deny.txt echo "Showing last few commits" git log -5 --oneline + echo "showing bad commits" + git show e8c26eb44639ad414727f8d5c74110cfd4e36ecc echo "Running secret scan" git-secrets --scan-history echo "scan complete" From 81f9b8a0b7aa1a2a58707cea467a0a0d74c281ff Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 2 Apr 2026 10:47:08 +0000 Subject: [PATCH 38/42] remove bad --- .gitallowed | 2 -- .github/workflows/quality-checks-devcontainer.yml | 2 -- 2 files changed, 4 deletions(-) diff --git a/.gitallowed b/.gitallowed index 685229fe..ae9f2aaf 100644 --- a/.gitallowed +++ b/.gitallowed @@ -8,5 +8,3 @@ token = os\.environ\.get\(\"GH_TOKEN\"\) poetry\.lock \-Dsonar\.token=\"\$SONAR_TOKEN\" token: "\${{ steps\.generate-token\.outputs\.token }}" -id-token: 'write' -id-token: "write" diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index 11702162..c8136088 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -87,8 +87,6 @@ jobs: cat /usr/share/secrets-scanner/nhsd-rules-deny.txt echo "Showing last few commits" git log -5 --oneline - echo "showing bad commits" - git show e8c26eb44639ad414727f8d5c74110cfd4e36ecc echo "Running secret scan" git-secrets --scan-history echo "scan complete" From 37d91af2fbe36fb369a0e0e65bd08ec8dce1e1ce Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 2 Apr 2026 11:01:55 +0000 Subject: [PATCH 39/42] go back --- .github/workflows/quality-checks-devcontainer.yml | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/.github/workflows/quality-checks-devcontainer.yml b/.github/workflows/quality-checks-devcontainer.yml index c8136088..085a5e8b 100644 --- a/.github/workflows/quality-checks-devcontainer.yml +++ b/.github/workflows/quality-checks-devcontainer.yml @@ -76,20 +76,9 @@ jobs: make install - name: Run secrets scan run: | - echo "Checking for secret scan config" - ls /usr/share/secrets-scanner/nhsd-rules-deny.txt - echo "Registering git-secrets AWS rules" git-secrets --register-aws git-secrets --add-provider -- cat /usr/share/secrets-scanner/nhsd-rules-deny.txt - echo "Checking git-secrets configuration" - git-secrets --list - echo "Checking content of git-secrets rules" - cat /usr/share/secrets-scanner/nhsd-rules-deny.txt - echo "Showing last few commits" - git log -5 --oneline - echo "Running secret scan" - git-secrets --scan-history - echo "scan complete" + make secret-scan - name: Run actionlint run: | make actionlint From 57625fee3b822daa818e3897050b7b821fc33b7b Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 2 Apr 2026 11:50:24 +0000 Subject: [PATCH 40/42] revert changes to gitignore --- .gitallowed | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitallowed b/.gitallowed index ae9f2aaf..685229fe 100644 --- a/.gitallowed +++ b/.gitallowed @@ -8,3 +8,5 @@ token = os\.environ\.get\(\"GH_TOKEN\"\) poetry\.lock \-Dsonar\.token=\"\$SONAR_TOKEN\" token: "\${{ steps\.generate-token\.outputs\.token }}" +id-token: 'write' +id-token: "write" From 38d45e1ebe4f8ba88d4588d7e8a5841658ac9f4b Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Thu, 2 Apr 2026 11:50:44 +0000 Subject: [PATCH 41/42] update --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5f663f85..0ed3cb41 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,3 @@ release_notes .venv .asdf .trivy_out -.sbom From f0c4e3c773bb7bedc7c442fce23367d2f6e3f09b Mon Sep 17 00:00:00 2001 From: Anthony Brown Date: Tue, 7 Apr 2026 07:32:17 +0000 Subject: [PATCH 42/42] ignore scripts --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e4662905..4f55190e 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ install: install-node install-python install-hooks install-node: - npm ci + npm ci --ignore-scripts true install-python: poetry install