Skip to content

Commit 2a08351

Browse files
Chore: [AEA-0000] - Combines get_config_values and verify_attestation into a single workflow (#73)
## Summary - Routine Change ### Details Combines get_config_values and verify_attestation into a single workflow to reduce repeated attestation verification
1 parent d215f84 commit 2a08351

File tree

6 files changed

+161
-179
lines changed

6 files changed

+161
-179
lines changed
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
name: Get Repo Config and Image
2+
on:
3+
workflow_call:
4+
inputs:
5+
registry:
6+
required: false
7+
type: string
8+
default: ghcr.io
9+
namespace:
10+
required: false
11+
type: string
12+
default: nhsdigital/eps-devcontainers
13+
owner:
14+
required: false
15+
type: string
16+
default: NHSDigital
17+
verify_published_from_main_image:
18+
required: false
19+
type: boolean
20+
default: true
21+
predicate_type:
22+
required: false
23+
type: string
24+
default: https://slsa.dev/provenance/v1
25+
outputs:
26+
tag_format:
27+
description: The tag format to be used for releases, as defined in .github/config/settings.yml
28+
value: ${{ jobs.get_config_values.outputs.tag_format }}
29+
devcontainer_image:
30+
description: The devcontainer image name as defined in .devcontainer/devcontainer.json
31+
value: ${{ jobs.get_config_values.outputs.devcontainer_image }}
32+
devcontainer_version:
33+
description: The devcontainer image version as defined in .devcontainer/devcontainer.json
34+
value: ${{ jobs.get_config_values.outputs.devcontainer_version }}
35+
pinned_image:
36+
description: Fully-qualified digest-pinned image reference
37+
value: ${{ jobs.verify_attestation.outputs.pinned_image }}
38+
resolved_digest:
39+
description: Resolved digest for the supplied image reference
40+
value: ${{ jobs.verify_attestation.outputs.resolved_digest }}
41+
42+
jobs:
43+
get_config_values:
44+
runs-on: ubuntu-22.04
45+
outputs:
46+
tag_format: ${{ steps.load-config.outputs.TAG_FORMAT }}
47+
devcontainer_version: ${{ steps.load-config.outputs.DEVCONTAINER_VERSION }}
48+
devcontainer_image: ${{ steps.load-config.outputs.DEVCONTAINER_IMAGE }}
49+
runtime_docker_image: ${{ steps.load-config.outputs.RUNTIME_DOCKER_IMAGE }}
50+
steps:
51+
- name: Checkout code
52+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
53+
with:
54+
ref: ${{ env.BRANCH_NAME }}
55+
fetch-depth: 0
56+
57+
- name: Load config value
58+
id: load-config
59+
run: |
60+
TAG_FORMAT=$(yq '.TAG_FORMAT' .github/config/settings.yml)
61+
DEVCONTAINER_IMAGE=$(jq -r '.build.args.IMAGE_NAME' .devcontainer/devcontainer.json)
62+
DEVCONTAINER_VERSION=$(jq -r '.build.args.IMAGE_VERSION' .devcontainer/devcontainer.json)
63+
RUNTIME_DOCKER_IMAGE="${DEVCONTAINER_IMAGE}:githubactions-${DEVCONTAINER_VERSION}"
64+
{
65+
echo "TAG_FORMAT=$TAG_FORMAT"
66+
echo "DEVCONTAINER_IMAGE=$DEVCONTAINER_IMAGE"
67+
echo "DEVCONTAINER_VERSION=$DEVCONTAINER_VERSION"
68+
echo "RUNTIME_DOCKER_IMAGE=$RUNTIME_DOCKER_IMAGE"
69+
} >> "$GITHUB_OUTPUT"
70+
71+
verify_attestation:
72+
runs-on: ubuntu-22.04
73+
needs: get_config_values
74+
permissions:
75+
contents: read
76+
packages: read
77+
attestations: read
78+
outputs:
79+
pinned_image: ${{ steps.resolve.outputs.pinned_image }}
80+
resolved_digest: ${{ steps.resolve.outputs.resolved_digest }}
81+
steps:
82+
- name: Login to github container registry
83+
if: startsWith(inputs.registry, 'ghcr.io')
84+
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9
85+
with:
86+
registry: ghcr.io
87+
username: ${{ github.actor }}
88+
password: ${{ secrets.GITHUB_TOKEN }}
89+
90+
- name: Resolve digest
91+
id: resolve
92+
shell: bash
93+
env:
94+
RUNTIME_DOCKER_IMAGE: ${{ needs.get_config_values.outputs.runtime_docker_image }}
95+
REGISTRY: ${{ inputs.registry }}
96+
NAMESPACE: ${{ inputs.namespace }}
97+
run: |
98+
set -euo pipefail
99+
100+
if [[ "$RUNTIME_DOCKER_IMAGE" == *"/"* ]]; then
101+
IMAGE_REF="$RUNTIME_DOCKER_IMAGE"
102+
else
103+
IMAGE_REF="${REGISTRY}/${NAMESPACE}/${RUNTIME_DOCKER_IMAGE}"
104+
fi
105+
106+
if [[ "$IMAGE_REF" == *@sha256:* ]]; then
107+
IMAGE_BASE="${IMAGE_REF%@*}"
108+
RESOLVED_DIGEST="${IMAGE_REF#*@}"
109+
else
110+
RESOLVED_DIGEST="$(docker buildx imagetools inspect "$IMAGE_REF" | awk '/^Digest:/ {print $2; exit}')"
111+
IMAGE_BASE="${IMAGE_REF%:*}"
112+
fi
113+
114+
if [[ -z "$RESOLVED_DIGEST" ]]; then
115+
echo "Could not resolve digest for image: $IMAGE_REF" >&2
116+
exit 1
117+
fi
118+
119+
PINNED_IMAGE="${IMAGE_BASE}@${RESOLVED_DIGEST}"
120+
echo "resolved_digest=${RESOLVED_DIGEST}" >> "$GITHUB_OUTPUT"
121+
echo "pinned_image=${PINNED_IMAGE}" >> "$GITHUB_OUTPUT"
122+
echo "Resolved image reference: ${IMAGE_REF}"
123+
echo "Resolved digest: ${RESOLVED_DIGEST}"
124+
echo "Resolved image reference: ${PINNED_IMAGE}"
125+
126+
- name: Verify attestation
127+
shell: bash
128+
env:
129+
GH_TOKEN: ${{ github.token }}
130+
OWNER: ${{ inputs.owner }}
131+
VERIFY_PUBLISHED_FROM_MAIN_IMAGE: ${{ inputs.verify_published_from_main_image }}
132+
PREDICATE_TYPE: ${{ inputs.predicate_type }}
133+
PINNED_IMAGE: ${{ steps.resolve.outputs.pinned_image }}
134+
run: |
135+
set -euo pipefail
136+
137+
args=("oci://${PINNED_IMAGE}" "--owner" "$OWNER" "--predicate-type" "$PREDICATE_TYPE")
138+
139+
if [[ "$VERIFY_PUBLISHED_FROM_MAIN_IMAGE" == "true" ]]; then
140+
args+=("--source-ref" "refs/heads/main")
141+
fi
142+
143+
144+
GH_FORCE_TTY=120 gh attestation verify "${args[@]}" 2>&1
145+
echo "Verified attestation for ${PINNED_IMAGE}"

.github/workflows/pull_request.yml

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: pr
1+
name: Pull Request
22

33
on:
44
pull_request:
@@ -17,43 +17,24 @@ jobs:
1717
pr_title_format_check:
1818
uses: ./.github/workflows/pr_title_check.yml
1919
get_config_values:
20-
runs-on: ubuntu-22.04
21-
outputs:
22-
tag_format: ${{ steps.load-config.outputs.TAG_FORMAT }}
23-
devcontainer_version: ${{ steps.load-config.outputs.DEVCONTAINER_VERSION }}
24-
devcontainer_image: ${{ steps.load-config.outputs.DEVCONTAINER_IMAGE }}
25-
steps:
26-
- name: Checkout code
27-
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
28-
29-
- name: Load config value
30-
id: load-config
31-
run: |
32-
TAG_FORMAT=$(yq '.TAG_FORMAT' .github/config/settings.yml)
33-
DEVCONTAINER_IMAGE=$(jq -r '.build.args.IMAGE_NAME' .devcontainer/devcontainer.json)
34-
DEVCONTAINER_VERSION=$(jq -r '.build.args.IMAGE_VERSION' .devcontainer/devcontainer.json)
35-
{
36-
echo "TAG_FORMAT=$TAG_FORMAT"
37-
echo "DEVCONTAINER_IMAGE=$DEVCONTAINER_IMAGE"
38-
echo "DEVCONTAINER_VERSION=$DEVCONTAINER_VERSION"
39-
} >> "$GITHUB_OUTPUT"
20+
uses: ./.github/workflows/get-repo-config.yml
4021
quality_checks:
4122
uses: ./.github/workflows/quality-checks-devcontainer.yml
4223
needs: [get_config_values]
4324
with:
44-
runtime_docker_image: "${{ needs.get_config_values.outputs.devcontainer_image }}:githubactions-${{ needs.get_config_values.outputs.devcontainer_version }}"
25+
pinned_image: ${{ needs.get_config_values.outputs.pinned_image }}
4526
secrets:
4627
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
4728
tag_release:
48-
needs: [quality_checks, get_config_values]
29+
needs: get_config_values
4930
uses: ./.github/workflows/tag-release-devcontainer.yml
5031
permissions:
5132
contents: read
5233
packages: read
5334
attestations: read
5435
with:
5536
dry_run: true
56-
runtime_docker_image: "${{ needs.get_config_values.outputs.devcontainer_image }}:githubactions-${{ needs.get_config_values.outputs.devcontainer_version }}"
37+
pinned_image: ${{ needs.get_config_values.outputs.pinned_image }}
5738
branch_name: ${{ github.event.pull_request.head.ref }}
5839
tag_format: ${{ needs.get_config_values.outputs.tag_format }}
5940
verify_published_from_main_image: false

.github/workflows/quality-checks-devcontainer.yml

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,15 @@ on:
2121
description: comma separated list of docker image references to scan when docker scanning is enabled.
2222
default: ""
2323
required: false
24-
runtime_docker_image:
24+
pinned_image:
2525
type: string
2626
required: true
2727

2828
jobs:
29-
verify_attestation:
30-
uses: ./.github/workflows/verify-attestation.yml
31-
with:
32-
runtime_docker_image: "${{ inputs.runtime_docker_image }}"
33-
verify_published_from_main_image: false
3429
quality_checks:
3530
runs-on: ubuntu-22.04
36-
needs: verify_attestation
3731
container:
38-
image: ${{ needs.verify_attestation.outputs.pinned_image }}
32+
image: ${{ inputs.pinned_image }}
3933
options: --user 1001:1001 --group-add 128
4034
defaults:
4135
run:
@@ -213,9 +207,8 @@ jobs:
213207

214208
get_docker_images_to_scan:
215209
runs-on: ubuntu-22.04
216-
needs: verify_attestation
217210
container:
218-
image: ${{ needs.verify_attestation.outputs.pinned_image }}
211+
image: ${{ inputs.pinned_image }}
219212
options: --user 1001:1001 --group-add 128
220213
defaults:
221214
run:
@@ -283,9 +276,9 @@ jobs:
283276
284277
docker_vulnerability_scan:
285278
runs-on: ubuntu-22.04
286-
needs: [get_docker_images_to_scan, verify_attestation]
279+
needs: get_docker_images_to_scan
287280
container:
288-
image: ${{ needs.verify_attestation.outputs.pinned_image }}
281+
image: ${{ inputs.pinned_image }}
289282
options: --user 1001:1001 --group-add 128
290283
defaults:
291284
run:
@@ -326,9 +319,8 @@ jobs:
326319
327320
IaC-validation:
328321
runs-on: ubuntu-22.04
329-
needs: verify_attestation
330322
container:
331-
image: ${{ needs.verify_attestation.outputs.pinned_image }}
323+
image: ${{ inputs.pinned_image }}
332324
options: --user 1001:1001 --group-add 128
333325
defaults:
334326
run:

.github/workflows/release.yml

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,39 +9,20 @@ env:
99

1010
jobs:
1111
get_config_values:
12-
runs-on: ubuntu-22.04
13-
outputs:
14-
tag_format: ${{ steps.load-config.outputs.TAG_FORMAT }}
15-
devcontainer_version: ${{ steps.load-config.outputs.DEVCONTAINER_VERSION }}
16-
devcontainer_image: ${{ steps.load-config.outputs.DEVCONTAINER_IMAGE }}
17-
steps:
18-
- name: Checkout code
19-
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
20-
21-
- name: Load config value
22-
id: load-config
23-
run: |
24-
TAG_FORMAT=$(yq '.TAG_FORMAT' .github/config/settings.yml)
25-
DEVCONTAINER_IMAGE=$(jq -r '.build.args.IMAGE_NAME' .devcontainer/devcontainer.json)
26-
DEVCONTAINER_VERSION=$(jq -r '.build.args.IMAGE_VERSION' .devcontainer/devcontainer.json)
27-
{
28-
echo "TAG_FORMAT=$TAG_FORMAT"
29-
echo "DEVCONTAINER_IMAGE=$DEVCONTAINER_IMAGE"
30-
echo "DEVCONTAINER_VERSION=$DEVCONTAINER_VERSION"
31-
} >> "$GITHUB_OUTPUT"
12+
uses: ./.github/workflows/get-repo-config.yml
3213
quality_checks:
3314
needs: [get_config_values]
3415
uses: ./.github/workflows/quality-checks-devcontainer.yml
3516
with:
36-
runtime_docker_image: "${{ needs.get_config_values.outputs.devcontainer_image }}:githubactions-${{ needs.get_config_values.outputs.devcontainer_version }}"
17+
pinned_image: ${{ needs.get_config_values.outputs.pinned_image }}
3718
secrets:
3819
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
3920
tag_release:
4021
needs: [quality_checks, get_config_values]
4122
uses: ./.github/workflows/tag-release-devcontainer.yml
4223
with:
4324
dry_run: false
44-
runtime_docker_image: "${{ needs.get_config_values.outputs.devcontainer_image }}:githubactions-${{ needs.get_config_values.outputs.devcontainer_version }}"
25+
pinned_image: ${{ needs.get_config_values.outputs.pinned_image }}
4526
branch_name: main
4627
tag_format: ${{ needs.get_config_values.outputs.tag_format }}
4728
verify_published_from_main_image: true

.github/workflows/tag-release-devcontainer.yml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ on:
1111
description: "The branch name to base the release on"
1212
required: true
1313
type: string
14-
runtime_docker_image:
14+
pinned_image:
1515
type: string
1616
required: true
1717
publish_packages:
@@ -62,16 +62,10 @@ on:
6262
required: false
6363
description: "NPM token to publish packages"
6464
jobs:
65-
verify_attestation:
66-
uses: ./.github/workflows/verify-attestation.yml
67-
with:
68-
runtime_docker_image: "${{ inputs.runtime_docker_image }}"
69-
verify_published_from_main_image: ${{ inputs.verify_published_from_main_image }}
7065
tag_release:
7166
runs-on: ubuntu-22.04
72-
needs: verify_attestation
7367
container:
74-
image: ${{ needs.verify_attestation.outputs.pinned_image }}
68+
image: ${{ inputs.pinned_image }}
7569
options: --user 1001:1001 --group-add 128
7670
defaults:
7771
run:

0 commit comments

Comments
 (0)