Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
},
"updateRemoteUserUID": false
},
"postAttachCommand": "git-secrets --register-aws; git-secrets --add-provider -- cat /usr/share/secrets-scanner/nhsd-rules-deny.txt",
"mounts": [
"source=${env:HOME}${env:USERPROFILE}/.aws,target=/home/vscode/.aws,type=bind",
Comment on lines 12 to 16
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing the postAttachCommand appears to drop the only repo-local setup that registers git-secrets patterns/providers (no other occurrences of git-secrets --register-aws / --add-provider remain in the repo). With the current pre-commit hook calling git-secrets --pre_commit_hook, this may cause secret scanning to become ineffective for new clones/devcontainers. If the devcontainer image no longer sets this up globally, consider restoring this setup or moving it into a dedicated bootstrap script that’s invoked from postAttachCommand.

Copilot uses AI. Check for mistakes.
"source=${env:HOME}${env:USERPROFILE}/.ssh,target=/home/vscode/.ssh,type=bind",
Expand Down
6 changes: 3 additions & 3 deletions .github/dependabot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ updates:
commit-message:
prefix: "Upgrade: [dependabot] - "
cooldown:
default-days: 3
default-days: 7

###################################
# Poetry #########################
Expand All @@ -29,7 +29,7 @@ updates:
commit-message:
prefix: "Upgrade: [dependabot] - "
cooldown:
default-days: 3
default-days: 7

###################################
# NPM workspace ##################
Expand All @@ -45,4 +45,4 @@ updates:
commit-message:
prefix: "Upgrade: [dependabot] - "
cooldown:
default-days: 3
default-days: 7
19 changes: 0 additions & 19 deletions .github/workflows/schedule_dev_container_update.yml

This file was deleted.

80 changes: 12 additions & 68 deletions .github/workflows/sync_copilot.yml
Original file line number Diff line number Diff line change
@@ -1,78 +1,22 @@
name: Sync copilot instructions
name: Sync Copilot Instructions

on:
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workflow is documented and used as a reusable workflow (called via uses: NHSDigital/eps-common-workflows/.github/workflows/sync_copilot.yml@...). Removing the workflow_call trigger means other repos can no longer call it, which is a breaking change and also conflicts with the project guidance that reusable workflows should expose workflow_call (see .github/instructions/project/instructions.md). Reintroduce workflow_call (inputs/secrets as needed), and optionally keep workflow_dispatch/schedule alongside it if you still want ad-hoc/scheduled runs in this repo.

Suggested change
on:
on:
workflow_call:
secrets:
CREATE_PULL_REQUEST_APP_ID:
required: true
CREATE_PULL_REQUEST_PEM:
required: true

Copilot uses AI. Check for mistakes.
workflow_call:
inputs:
common_workflows_ref:
description: "The ref to sync from the central repository"
required: false
default: "main"
type: string
calling_repo_base_branch:
description: "The base branch from the calling repository that should be merged into"
required: false
type: string
default: main
workflow_dispatch:
schedule:
- cron: "0 6 * * 1"

jobs:
sync:
sync-copilot-instructions:
runs-on: ubuntu-22.04
environment: "create_pull_request"
environment: create_pull_request
permissions:
contents: read
pull-requests: write

steps:
- name: Checkout calling repo code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- name: Sync shared instructions
uses: NHSDigital/eps-copilot-instructions@a7849a16aabd5c1edef13e29467a480fa08555f8
with:
ref: ${{ inputs.calling_repo_base_branch }}
fetch-depth: 0

- name: Checkout central repo code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
ref: ${{ inputs.common_workflows_ref }}
fetch-depth: 0
path: eps-common-workflows
repository: NHSDigital/eps-common-workflows
sparse-checkout: |
.github/instructions/general
.github/instructions/languages
.github/copilot-instructions.md
.github/prompts

- name: Copy central instructions
run: |
rm -rf .github/instructions/general
rm -rf .github/instructions/languages
rm -rf .github/copilot-instructions.md
rm -rf .github/prompts
mkdir -p .github/instructions/
cp -R eps-common-workflows/.github/instructions/general .github/instructions/general
cp -R eps-common-workflows/.github/instructions/languages .github/instructions/languages
cp eps-common-workflows/.github/copilot-instructions.md .github/copilot-instructions.md
cp -R eps-common-workflows/.github/prompts .github/prompts
rm -rf eps-common-workflows

- name: Create GitHub App Token
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859
id: generate-token
with:
app-id: "${{ secrets.CREATE_PULL_REQUEST_APP_ID }}"
private-key: "${{ secrets.CREATE_PULL_REQUEST_PEM }}"

- name: Create Pull Request
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0
with:
token: "${{ steps.generate-token.outputs.token }}"
commit-message: "Upgrade: [dependabot] - sync Copilot instructions"
title: "Upgrade: [dependabot] - sync Copilot instructions"
body: |
Syncing Copilot instructions from central repo.
Ref: `${{ inputs.common_workflows_ref }}`
branch: copilot-instructions-sync
base: ${{ inputs.calling_repo_base_branch }}
branch-suffix: random
sign-commits: true
delete-branch: true
copilot_instructions_ref: main
calling_repo_base_branch: main
CREATE_PULL_REQUEST_APP_ID: ${{ secrets.CREATE_PULL_REQUEST_APP_ID }}
CREATE_PULL_REQUEST_PEM: ${{ secrets.CREATE_PULL_REQUEST_PEM }}
155 changes: 15 additions & 140 deletions .github/workflows/update-dev-container-version.yml
Original file line number Diff line number Diff line change
@@ -1,148 +1,23 @@
name: Update Dev Container Image version
name: Update devcontainer version

Comment on lines +1 to +2
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description only mentions “use action for sync copilot”, but this change also modifies the devcontainer update workflow, dependabot cooldown timings, adds a new pre-commit hook enforcing commit-signing config, and removes a devcontainer postAttachCommand. Please update the PR description (or split into separate PRs) so reviewers and downstream consumers understand the full scope and intent.

Copilot uses AI. Check for mistakes.
on:
workflow_call:
inputs:
base_branch:
required: false
type: string
default: main
secrets:
CREATE_PULL_REQUEST_APP_ID:
required: true
CREATE_PULL_REQUEST_PEM:
required: true
workflow_dispatch:
schedule:
- cron: "0 6 * * 4"
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The scheduled devcontainer update time has changed (previously the separate scheduler workflow ran at 18:00 UTC Thursdays; this workflow now schedules at 06:00 UTC Thursdays). If this timing change isn’t intentional, keep the previous cron; otherwise it would be good to call out the new schedule in the PR description so it’s not a silent operational change.

Suggested change
- cron: "0 6 * * 4"
- cron: "0 18 * * 4"

Copilot uses AI. Check for mistakes.
permissions: {}
Comment on lines 3 to +7
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workflow is documented as a reusable workflow (README section “Update Dev Container Version” shows other repos calling it via uses:). Replacing workflow_call with only workflow_dispatch/schedule breaks that contract for consumers and contradicts the project guidance that workflows designed to be called from other repos should use workflow_call (see .github/instructions/project/instructions.md). Consider restoring workflow_call (and its inputs/secrets), and keep workflow_dispatch/schedule in addition if required.

Copilot uses AI. Check for mistakes.

jobs:
update_devcontainer_version:
update-devcontainer-version:
runs-on: ubuntu-22.04
environment: create_pull_request
permissions:
contents: read
packages: read
pull-requests: write
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
fetch-depth: 0
- name: Load config value
id: load-config
run: |
set -euo pipefail
DEVCONTAINER_IMAGE=$(jq -r '.build.args.IMAGE_NAME' .devcontainer/devcontainer.json)

DEVCONTAINER_VERSION=$(jq -r '.build.args.IMAGE_VERSION' .devcontainer/devcontainer.json)

{
echo "DEVCONTAINER_IMAGE=$DEVCONTAINER_IMAGE"
echo "DEVCONTAINER_VERSION=$DEVCONTAINER_VERSION"
} >> "$GITHUB_ENV"
- name: Resolve latest devcontainer image version from GHCR
id: resolve-version
env:
GH_TOKEN: "${{ github.token }}"
run: |
set -euo pipefail


PACKAGE_NAME="eps-devcontainers/${DEVCONTAINER_IMAGE}"

ENCODED_PACKAGE_NAME=$(python3 -c 'import sys, urllib.parse;
print(urllib.parse.quote(sys.argv[1], safe=""))' "$PACKAGE_NAME")


VERSIONS_JSON=$(gh api \
-H "Accept: application/vnd.github+json" \
"/orgs/NHSDigital/packages/container/${ENCODED_PACKAGE_NAME}/versions?per_page=100")

LATEST_VIA_LATEST_TAG=$(jq -r '
[ .[]
| select((.metadata.container.tags // []) | index("latest"))
]
| sort_by(.created_at)
| reverse
| .[0].metadata.container.tags // []
| map(select(test("^v")))
| .[0] // empty
' <<< "$VERSIONS_JSON")


LATEST_V_TAG=$(jq -r '
[ .[]
| {created_at, tags: (.metadata.container.tags // [])}
]
| sort_by(.created_at)
| reverse
| map(.tags[]? | select(test("^v")))
| .[0] // empty
' <<< "$VERSIONS_JSON")


RESOLVED_VERSION="$LATEST_VIA_LATEST_TAG"

if [[ -z "$RESOLVED_VERSION" ]]; then
RESOLVED_VERSION="$LATEST_V_TAG"
fi


if [[ -z "$RESOLVED_VERSION" ]]; then
echo "No version tag matching ^v found for package ${PACKAGE_NAME}" >&2
exit 1
fi


echo "Resolved latest version: ${RESOLVED_VERSION}"

echo "LATEST_DEVCONTAINER_VERSION=${RESOLVED_VERSION}" >> "$GITHUB_ENV"

echo "latest_version=${RESOLVED_VERSION}" >> "$GITHUB_OUTPUT"
- name: Update devcontainer version in config
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
fi


python3 - <<'PY'

import json

from pathlib import Path


config_file = Path('.devcontainer/devcontainer.json')

config = json.loads(config_file.read_text())

config['build']['args']['IMAGE_VERSION'] = '${{
steps.resolve-version.outputs.latest_version }}'

config_file.write_text(json.dumps(config, indent=2) + '\n')

PY


echo "Updated IMAGE_VERSION from ${DEVCONTAINER_VERSION} to
${LATEST_DEVCONTAINER_VERSION}"
- name: Create GitHub App Token
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859
id: generate-token
with:
app-id: "${{ secrets.CREATE_PULL_REQUEST_APP_ID }}"
private-key: "${{ secrets.CREATE_PULL_REQUEST_PEM }}"
- name: Create Pull Request
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0
steps:
- name: Update devcontainer version
uses: NHSDigital/eps-update-devcontainer@dc3a8c5f11e7226ee4f5f2bb35bd0d1265092306
with:
token: "${{ steps.generate-token.outputs.token }}"
commit-message: Update devcontainer image version to ${{ steps.resolve-version.outputs.latest_version }}
title: "Upgrade: [dependabot] - Update devcontainer image version to ${{ steps.resolve-version.outputs.latest_version }}"
body: "This PR updates the devcontainer image version to ${{ steps.resolve-version.outputs.latest_version }}."
add-paths: .devcontainer/devcontainer.json
sign-commits: true
base: "${{ inputs.base_branch }}"
delete-branch: true
branch: update-devcontainer-version
calling_repo_base_branch: main
CREATE_PULL_REQUEST_APP_ID: ${{ secrets.CREATE_PULL_REQUEST_APP_ID }}
CREATE_PULL_REQUEST_PEM: ${{ secrets.CREATE_PULL_REQUEST_PEM }}
20 changes: 20 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,26 @@ repos:
files: ^(.github)
- repo: local
hooks:
- id: check-commit-signing
name: Check commit signing
description: Ensures that commits are GPG signed
entry: bash
args:
- -c
- |
if ! git config --get commit.gpgsign | grep -q "true" > /dev/null 2>&1; then
echo "Error: Commit signing is not enabled."
echo "Please enable commit signing with:"
echo " git config commit.gpgsign true"
echo ""
echo "For more information, see: https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits"
exit 1
fi
echo "Commit signing is properly configured."
Comment on lines +21 to +35
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hook name/description says it “ensures that commits are GPG signed”, but the script only checks whether commit.gpgsign is set to true; it doesn’t verify that a commit will actually be signed (e.g., key configured/available) or that existing commits are signed. Consider rewording the name/description to reflect what’s actually enforced (e.g., “Check commit.gpgsign is enabled”) to avoid a false sense of security.

Suggested change
name: Check commit signing
description: Ensures that commits are GPG signed
entry: bash
args:
- -c
- |
if ! git config --get commit.gpgsign | grep -q "true" > /dev/null 2>&1; then
echo "Error: Commit signing is not enabled."
echo "Please enable commit signing with:"
echo " git config commit.gpgsign true"
echo ""
echo "For more information, see: https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits"
exit 1
fi
echo "Commit signing is properly configured."
name: Check commit.gpgsign is enabled
description: Checks that Git is configured to attempt GPG signing (commit.gpgsign=true)
entry: bash
args:
- -c
- |
if ! git config --get commit.gpgsign | grep -q "true" > /dev/null 2>&1; then
echo "Error: Commit signing is not configured via commit.gpgsign=true."
echo "Please enable commit signing with:"
echo " git config commit.gpgsign true"
echo ""
echo "For more information, see: https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits"
exit 1
fi
echo "Commit signing is enabled via commit.gpgsign=true."

Copilot uses AI. Check for mistakes.
language: system
pass_filenames: false
always_run: true

- 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.
Expand Down
Loading