Skip to content

Commit d79caed

Browse files
authored
Merge pull request #124 from egibs/automate-offline-test-pin
chore(update-ca-cert): also update new test fixture const
2 parents ad13e16 + 28c516e commit d79caed

1 file changed

Lines changed: 79 additions & 11 deletions

File tree

.github/workflows/update-ca-cert.yaml

Lines changed: 79 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ on:
88
- main
99
paths:
1010
- ".github/workflows/update-ca-cert.yaml"
11-
- "ssg-chainguard-gpos-ds.xml"
11+
- "gpos/xml/scap/ssg/content/ssg-chainguard-gpos-ds.xml"
12+
- "tests/e2e/fixtures/*/Dockerfile"
13+
- "tests/oscap-offline/internal/scan/fixtures_test.go"
1214
concurrency:
1315
group: update-ca-cert-${{ github.ref }}
1416
cancel-in-progress: false
@@ -29,6 +31,7 @@ jobs:
2931
DATASTREAM_PATH: gpos/xml/scap/ssg/content/ssg-chainguard-gpos-ds.xml
3032
TESTS_PATH: tests
3133
FIXTURES_GLOB: tests/e2e/fixtures/*/Dockerfile
34+
TEST_PIN_FILE: tests/oscap-offline/internal/scan/fixtures_test.go
3235
steps:
3336
- name: Checkout
3437
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
@@ -153,8 +156,9 @@ jobs:
153156
# The offline harness (tests/oscap-offline) reads its pinned base image
154157
# from tests/e2e/fixtures/baseline-clean/Dockerfile, so re-pinning that
155158
# fixture here also keeps the offline CertificateAudit pass fixture in
156-
# lockstep with the datastream hash. There is no separate offline pin to
157-
# update.
159+
# lockstep with the datastream hash. The one remaining copy of the
160+
# digest — the `pinned` constant in TestParseWolfiBaseRef — is
161+
# re-pinned by the next step.
158162
159163
fixtures_changed=false
160164
updated_files=()
@@ -203,14 +207,71 @@ jobs:
203207
else
204208
echo "- **Status**: Already up-to-date" >> "$GITHUB_STEP_SUMMARY"
205209
fi
210+
- name: Re-pin offline harness test digest
211+
id: testpin
212+
env:
213+
STEPS_IMAGE_OUTPUTS_DIGEST: ${{ steps.image.outputs.digest }}
214+
run: |
215+
set -euo pipefail
216+
217+
# TestParseWolfiBaseRef asserts the exact digest-pinned wolfi-base ref
218+
# parsed from tests/e2e/fixtures/baseline-clean/Dockerfile against a
219+
# hardcoded `pinned` constant, so that constant must move together
220+
# with the fixture re-pin above or the test breaks on every update
221+
# (see #123 for the manual fix this step replaces).
222+
#
223+
# The grep guard fails the run loudly if the constant's shape changes
224+
# (e.g. the test is refactored) so the workflow gets updated instead
225+
# of silently reintroducing drift.
226+
227+
if ! grep -qE 'wolfiBaseRepo \+ ":latest@sha256:[0-9a-f]{64}"' "${TEST_PIN_FILE}"; then
228+
echo "::error::Pinned digest constant not found in ${TEST_PIN_FILE}; update this workflow to match the test"
229+
exit 1
230+
fi
231+
232+
cp "${TEST_PIN_FILE}" "${TEST_PIN_FILE}.bak"
233+
sed -i -E "s|(wolfiBaseRepo \+ \":latest@sha256:)[0-9a-f]{64}|\1${STEPS_IMAGE_OUTPUTS_DIGEST#sha256:}|" "${TEST_PIN_FILE}"
234+
235+
if diff -q "${TEST_PIN_FILE}.bak" "${TEST_PIN_FILE}" > /dev/null; then
236+
echo "Test pin already up to date"
237+
echo "test_pin_changed=false" >> "$GITHUB_OUTPUT"
238+
testpin_status="Already up-to-date"
239+
else
240+
echo "Updated ${TEST_PIN_FILE} -> ${STEPS_IMAGE_OUTPUTS_DIGEST}"
241+
echo "test_pin_changed=true" >> "$GITHUB_OUTPUT"
242+
testpin_status="Updated"
243+
fi
244+
rm "${TEST_PIN_FILE}.bak"
245+
246+
cat >> "$GITHUB_STEP_SUMMARY" <<EOF
247+
### Test Pin Update Summary
248+
- **File**: \`${TEST_PIN_FILE}\`
249+
- **Status**: ${testpin_status}
250+
EOF
251+
- name: Setup Go
252+
uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
253+
with:
254+
go-version-file: 'tests/oscap-offline/go.mod'
255+
cache-dependency-path: 'tests/oscap-offline/go.sum'
256+
- name: Verify test pin matches fixture
257+
working-directory: tests/oscap-offline
258+
run: |
259+
set -euo pipefail
260+
261+
# Proves the re-pinned `pinned` constant agrees with the re-pinned
262+
# baseline-clean Dockerfile before any PR is opened, so a bad sed (or
263+
# drift introduced outside this workflow) fails here instead of
264+
# landing as a broken PR. Pure parse test; needs no container runtime.
265+
go test -count=1 -run 'TestParseWolfiBaseRef' ./internal/scan/
206266
- name: Aggregate change status
207267
id: changed
208268
env:
209269
DS_CHANGED: ${{ steps.update.outputs.datastream_changed }}
210270
FX_CHANGED: ${{ steps.fixtures.outputs.fixtures_changed }}
271+
TP_CHANGED: ${{ steps.testpin.outputs.test_pin_changed }}
211272
run: |
212273
set -euo pipefail
213-
if [ "${DS_CHANGED}" = "true" ] || [ "${FX_CHANGED}" = "true" ]; then
274+
if [ "${DS_CHANGED}" = "true" ] || [ "${FX_CHANGED}" = "true" ] || [ "${TP_CHANGED}" = "true" ]; then
214275
echo "changed=true" >> "$GITHUB_OUTPUT"
215276
else
216277
echo "changed=false" >> "$GITHUB_OUTPUT"
@@ -227,10 +288,12 @@ jobs:
227288
commit-message: |
228289
chore(oscap): re-pin CA bundle hash and fixture base-image digests
229290
230-
Atomically updates the CA bundle SHA in the OSCAP datastream and the
231-
digest-pinned FROM lines in tests/e2e/fixtures/*/Dockerfile so the
232-
two values can never drift out of sync (which would flake the
233-
CertificateAudit E2E assertions).
291+
Atomically updates the CA bundle SHA in the OSCAP datastream, the
292+
digest-pinned FROM lines in tests/e2e/fixtures/*/Dockerfile, and the
293+
pinned wolfi-base digest in the offline harness test
294+
(TestParseWolfiBaseRef) so the three values can never drift out of
295+
sync (which would flake the CertificateAudit E2E assertions or
296+
break the offline unit tests).
234297
235298
Image: ${{ env.IMAGE_REF }}
236299
Digest: ${{ steps.image.outputs.digest }}
@@ -243,25 +306,30 @@ jobs:
243306
body: |
244307
## CA Certificate + Fixture Base-Image Update
245308
246-
Atomically re-pins two values that must stay in lockstep:
309+
Atomically re-pins three values that must stay in lockstep:
247310
248311
1. The `<ind:hash>` under `oval:org.CABundleHash:ste:1` in the OSCAP
249312
datastream (`${{ env.DATASTREAM_PATH }}`).
250313
2. The `FROM cgr.dev/chainguard/wolfi-base:latest@sha256:...` line in
251314
every `tests/e2e/fixtures/*/Dockerfile`.
315+
3. The `pinned` wolfi-base digest constant asserted by
316+
`TestParseWolfiBaseRef` in `${{ env.TEST_PIN_FILE }}`.
252317
253318
If these drift (e.g. Dependabot bumps the fixture digest before this
254319
workflow refreshes the datastream hash, or vice versa), the
255320
`baseline-clean` / `cabundle-tampered` E2E CertificateAudit check
256321
fails because the fixture's CA bundle no longer matches the hash the
257-
datastream asserts. This workflow is now the authoritative update
258-
point for both values together.
322+
datastream asserts, and the offline harness unit tests break against
323+
the stale test pin. This workflow is the authoritative update point
324+
for all three values together; `TestParseWolfiBaseRef` was run
325+
against the updated tree before this PR was opened.
259326
260327
- **Image**: `${{ env.IMAGE_REF }}`
261328
- **Digest**: `${{ steps.image.outputs.digest }}`
262329
- **New CA SHA256**: `${{ steps.ca.outputs.sha }}`
263330
- **Datastream changed**: `${{ steps.update.outputs.datastream_changed }}`
264331
- **Fixtures changed**: `${{ steps.fixtures.outputs.fixtures_changed }}`
332+
- **Test pin changed**: `${{ steps.testpin.outputs.test_pin_changed }}`
265333
labels: |
266334
automated pr
267335
#- name: Enable auto-merge

0 commit comments

Comments
 (0)