From 96063bd7b59423a49bbbbbe432eac410720e771b Mon Sep 17 00:00:00 2001 From: aidenvaines-cgi Date: Tue, 25 Aug 2026 16:47:33 +0100 Subject: [PATCH 1/6] CCM-18043: Adding GPG Key for bot --- .github/workflows/release-notes-sync.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/release-notes-sync.yaml b/.github/workflows/release-notes-sync.yaml index 577e0a65..6f09203f 100644 --- a/.github/workflows/release-notes-sync.yaml +++ b/.github/workflows/release-notes-sync.yaml @@ -34,6 +34,17 @@ jobs: echo "has_changes=true" >> "$GITHUB_OUTPUT" fi + - name: "Configure GPG signing" + if: steps.changes.outputs.has_changes == 'true' + env: + GPG_PRIVATE_KEY: "${{ secrets.GPG_PRIVATE_KEY }}" + shell: bash + run: | + echo "$GPG_PRIVATE_KEY" | gpg --batch --import + KEY_ID=$(gpg --list-secret-keys --keyid-format LONG | awk '/^sec/{print $2}' | cut -d'/' -f2 | head -1) + git config --global user.signingkey "$KEY_ID" + git config --global commit.gpgsign true + - name: "Create pull request" if: steps.changes.outputs.has_changes == 'true' uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 From 7e932b7fefb44ac18f32ab5886fd3e563e16ff2a Mon Sep 17 00:00:00 2001 From: aidenvaines-cgi Date: Tue, 25 Aug 2026 16:53:47 +0100 Subject: [PATCH 2/6] CCM-18043: Adding GPG Key for bot --- .github/workflows/release-notes-sync.yaml | 33 ++++++++++++----------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/.github/workflows/release-notes-sync.yaml b/.github/workflows/release-notes-sync.yaml index 6f09203f..3ee1a642 100644 --- a/.github/workflows/release-notes-sync.yaml +++ b/.github/workflows/release-notes-sync.yaml @@ -44,22 +44,25 @@ jobs: KEY_ID=$(gpg --list-secret-keys --keyid-format LONG | awk '/^sec/{print $2}' | cut -d'/' -f2 | head -1) git config --global user.signingkey "$KEY_ID" git config --global commit.gpgsign true + git config --global gpg.program gpg - - name: "Create pull request" + - name: "Create signed commit and pull request" if: steps.changes.outputs.has_changes == 'true' - uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1 - with: - token: "${{ secrets.GITHUB_TOKEN }}" - branch: "automation/release-notes-cache" - delete-branch: true - commit-message: "sync release notes" - title: "CCM-18043: Sync release notes" - body: | - ## Summary + env: + GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + shell: bash + run: | + git checkout -B automation/release-notes-cache + git add docs/_data/release-notes.json + git commit -S -m "sync release notes" + git push --force-with-lease origin automation/release-notes-cache + gh pr create \ + --title "CCM-18043: Sync release notes" \ + --body "## Summary - This PR syncs the release notes generated from JIRA for the last year. + This PR syncs the release notes generated from JIRA for the last year. - - Trigger: `${{ github.event_name }}` - - Source: `JIRA_URL secret (expanded to REST API base path)` - add-paths: | - docs/_data/release-notes.json + - Trigger: \`${{ github.event_name }}\` + - Source: \`JIRA_URL secret (expanded to REST API base path)\`" \ + --base main \ + --head automation/release-notes-cache 2>/dev/null || echo "PR already exists" From 90b0d8c698fe10dc3b88e64aba516e5a9a5a990a Mon Sep 17 00:00:00 2001 From: aidenvaines-cgi Date: Wed, 26 Aug 2026 09:52:50 +0100 Subject: [PATCH 3/6] CCM-18043: Adding GPG Key for bot --- .github/workflows/release-notes-sync.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release-notes-sync.yaml b/.github/workflows/release-notes-sync.yaml index 3ee1a642..220fa345 100644 --- a/.github/workflows/release-notes-sync.yaml +++ b/.github/workflows/release-notes-sync.yaml @@ -42,6 +42,8 @@ jobs: run: | echo "$GPG_PRIVATE_KEY" | gpg --batch --import KEY_ID=$(gpg --list-secret-keys --keyid-format LONG | awk '/^sec/{print $2}' | cut -d'/' -f2 | head -1) + git config --global user.name "github-actions[bot]" + git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" git config --global user.signingkey "$KEY_ID" git config --global commit.gpgsign true git config --global gpg.program gpg From 8ad67f58a6a0d1eb75d22f60f644f55afe0058c3 Mon Sep 17 00:00:00 2001 From: aidenvaines-cgi Date: Wed, 26 Aug 2026 16:48:00 +0100 Subject: [PATCH 4/6] CCM-18043: Adding GPG Key for bot --- .github/workflows/release-notes-sync.yaml | 57 ++++++++++++++--------- .github/workflows/stage-1-commit.yaml | 19 ++++++-- 2 files changed, 50 insertions(+), 26 deletions(-) diff --git a/.github/workflows/release-notes-sync.yaml b/.github/workflows/release-notes-sync.yaml index 220fa345..54216d73 100644 --- a/.github/workflows/release-notes-sync.yaml +++ b/.github/workflows/release-notes-sync.yaml @@ -6,8 +6,7 @@ on: - cron: "0 6 * * 1" permissions: - contents: write - pull-requests: write + contents: read jobs: sync-release-notes: @@ -15,6 +14,13 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 10 steps: + - name: "Generate GitHub App token" + id: app-token + uses: actions/create-github-app-token@v1 + with: + app-id: "${{ vars.APP_CLIENT_ID }}" + private-key: "${{ secrets.APP_PEM_FILE }}" + - name: "Checkout code" uses: actions/checkout@v4 @@ -34,30 +40,39 @@ jobs: echo "has_changes=true" >> "$GITHUB_OUTPUT" fi - - name: "Configure GPG signing" + - name: "Commit and raise pull request" if: steps.changes.outputs.has_changes == 'true' env: - GPG_PRIVATE_KEY: "${{ secrets.GPG_PRIVATE_KEY }}" + GH_TOKEN: "${{ steps.app-token.outputs.token }}" shell: bash run: | - echo "$GPG_PRIVATE_KEY" | gpg --batch --import - KEY_ID=$(gpg --list-secret-keys --keyid-format LONG | awk '/^sec/{print $2}' | cut -d'/' -f2 | head -1) - git config --global user.name "github-actions[bot]" - git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" - git config --global user.signingkey "$KEY_ID" - git config --global commit.gpgsign true - git config --global gpg.program gpg + DEFAULT_SHA=$(gh api "repos/$GITHUB_REPOSITORY/git/ref/heads/main" --jq '.object.sha') + + # Create branch pointing to main, or force-reset it if it already exists + gh api --method POST "repos/$GITHUB_REPOSITORY/git/refs" \ + -f ref="refs/heads/automation/release-notes-cache" \ + -f sha="$DEFAULT_SHA" 2>/dev/null || \ + gh api --method PATCH "repos/$GITHUB_REPOSITORY/git/refs/heads/automation/release-notes-cache" \ + -f sha="$DEFAULT_SHA" \ + -F force=true + + # Commits via the Contents API are automatically verified by GitHub + FILE_SHA=$(gh api "repos/$GITHUB_REPOSITORY/contents/docs/_data/release-notes.json?ref=automation/release-notes-cache" --jq '.sha' 2>/dev/null || echo "") + FILE_CONTENT=$(base64 -w 0 docs/_data/release-notes.json) + + if [ -n "$FILE_SHA" ]; then + gh api --method PUT "repos/$GITHUB_REPOSITORY/contents/docs/_data/release-notes.json" \ + -f message="sync release notes" \ + -f content="$FILE_CONTENT" \ + -f sha="$FILE_SHA" \ + -f branch="automation/release-notes-cache" + else + gh api --method PUT "repos/$GITHUB_REPOSITORY/contents/docs/_data/release-notes.json" \ + -f message="sync release notes" \ + -f content="$FILE_CONTENT" \ + -f branch="automation/release-notes-cache" + fi - - name: "Create signed commit and pull request" - if: steps.changes.outputs.has_changes == 'true' - env: - GH_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - shell: bash - run: | - git checkout -B automation/release-notes-cache - git add docs/_data/release-notes.json - git commit -S -m "sync release notes" - git push --force-with-lease origin automation/release-notes-cache gh pr create \ --title "CCM-18043: Sync release notes" \ --body "## Summary diff --git a/.github/workflows/stage-1-commit.yaml b/.github/workflows/stage-1-commit.yaml index 3e4eef29..71ba8ee5 100644 --- a/.github/workflows/stage-1-commit.yaml +++ b/.github/workflows/stage-1-commit.yaml @@ -46,7 +46,16 @@ jobs: with: fetch-depth: 0 # Full history is needed to scan all commits - name: "Scan secrets" - uses: NHSDigital/nhs-notify-shared-modules/.github/actions/scan-secrets@5.1.0 # NOSONAR - githubactions:S7637 - internally controlled repo, pinned by tag + uses: NHSDigital/nhs-notify-shared-modules/.github/actions/scan-secrets@5.1.3 # NOSONAR - githubactions:S7637 - internally controlled repo, pinned by tag + validate-action-pins: + name: "Validate action SHA pins" + runs-on: ubuntu-latest + timeout-minutes: 2 + steps: + - name: "Checkout code" + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: "Validate action SHA pins" + uses: NHSDigital/nhs-notify-shared-modules/.github/actions/validate-action-pins@5.1.3 # NOSONAR - githubactions:S7637 - internally controlled repo, pinned by tag check-file-format: name: "Check file format" runs-on: ubuntu-latest @@ -57,7 +66,7 @@ jobs: with: fetch-depth: 0 # Full history is needed to compare branches - name: "Check file format" - uses: NHSDigital/nhs-notify-shared-modules/.github/actions/check-file-format@5.1.0 # NOSONAR - githubactions:S7637 - internally controlled repo, pinned by tag + uses: NHSDigital/nhs-notify-shared-modules/.github/actions/check-file-format@5.1.3 # NOSONAR - githubactions:S7637 - internally controlled repo, pinned by tag check-markdown-format: name: "Check Markdown format" runs-on: ubuntu-latest @@ -68,7 +77,7 @@ jobs: with: fetch-depth: 0 # Full history is needed to compare branches - name: "Check Markdown format" - uses: NHSDigital/nhs-notify-shared-modules/.github/actions/check-markdown-format@5.1.0 # NOSONAR - githubactions:S7637 - internally controlled repo, pinned by tag + uses: NHSDigital/nhs-notify-shared-modules/.github/actions/check-markdown-format@5.1.3 # NOSONAR - githubactions:S7637 - internally controlled repo, pinned by tag check-english-usage: name: "Check English usage" runs-on: ubuntu-latest @@ -79,7 +88,7 @@ jobs: with: fetch-depth: 0 # Full history is needed to compare branches - name: "Check English usage" - uses: NHSDigital/nhs-notify-shared-modules/.github/actions/check-english-usage@5.1.0 # NOSONAR - githubactions:S7637 - internally controlled repo, pinned by tag + uses: NHSDigital/nhs-notify-shared-modules/.github/actions/check-english-usage@5.1.3 # NOSONAR - githubactions:S7637 - internally controlled repo, pinned by tag count-lines-of-code: name: "Count lines of code" runs-on: ubuntu-latest @@ -91,7 +100,7 @@ jobs: - name: "Checkout code" uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7.0.1 - name: "Count lines of code" - uses: NHSDigital/nhs-notify-shared-modules/.github/actions/create-lines-of-code-report@5.1.0 # NOSONAR - githubactions:S7637 - internally controlled repo, pinned by tag + uses: NHSDigital/nhs-notify-shared-modules/.github/actions/create-lines-of-code-report@5.1.3 # NOSONAR - githubactions:S7637 - internally controlled repo, pinned by tag with: build_datetime: "${{ inputs.build_datetime }}" build_timestamp: "${{ inputs.build_timestamp }}" From 25730e0ee2ff3db889a422e25cfdbd7610bb2e4b Mon Sep 17 00:00:00 2001 From: aidenvaines-cgi Date: Wed, 26 Aug 2026 16:51:17 +0100 Subject: [PATCH 5/6] CCM-18043: Adding GPG Key for bot --- .github/workflows/release-notes-sync.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release-notes-sync.yaml b/.github/workflows/release-notes-sync.yaml index 54216d73..0716bc6d 100644 --- a/.github/workflows/release-notes-sync.yaml +++ b/.github/workflows/release-notes-sync.yaml @@ -16,9 +16,9 @@ jobs: steps: - name: "Generate GitHub App token" id: app-token - uses: actions/create-github-app-token@v1 + uses: actions/create-github-app-token@v3.2.0 with: - app-id: "${{ vars.APP_CLIENT_ID }}" + app-id: "${{ secrets.APP_CLIENT_ID }}" private-key: "${{ secrets.APP_PEM_FILE }}" - name: "Checkout code" From f287d4b144d8e70e622db227ea54b4ad17fdcc10 Mon Sep 17 00:00:00 2001 From: aidenvaines-cgi Date: Wed, 26 Aug 2026 17:15:27 +0100 Subject: [PATCH 6/6] CCM-18043: Adding GPG Key for bot --- .github/workflows/release-notes-sync.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-notes-sync.yaml b/.github/workflows/release-notes-sync.yaml index 0716bc6d..de9fb774 100644 --- a/.github/workflows/release-notes-sync.yaml +++ b/.github/workflows/release-notes-sync.yaml @@ -18,7 +18,7 @@ jobs: id: app-token uses: actions/create-github-app-token@v3.2.0 with: - app-id: "${{ secrets.APP_CLIENT_ID }}" + client-id: "${{ secrets.APP_CLIENT_ID }}" private-key: "${{ secrets.APP_PEM_FILE }}" - name: "Checkout code"