Skip to content

chore(ci): unify check-image-pins.py with deployments via the org canonical copy (JDWLABS-451) - #384

Open
jdwillmsen wants to merge 3 commits into
mainfrom
chore/JDWLABS-451-unify-check-image-pins
Open

chore(ci): unify check-image-pins.py with deployments via the org canonical copy (JDWLABS-451)#384
jdwillmsen wants to merge 3 commits into
mainfrom
chore/JDWLABS-451-unify-check-image-pins

Conversation

@jdwillmsen

Copy link
Copy Markdown
Member

Summary

Replaces this repo's fork of the image-pin checker with the org-canonical copy from jdwlabs/.github#48, byte-identical to deployments'. Scan scope (tenants/, helm-charts/, templates scanned for literal references) moves into tools/image-pin-check.yaml; check-remote-chart-image-pins.py keeps reusing the checker through the new refs_in_tree() entry point; the image-pin-check job gains a drift guard that cmps the script and test file against jdwlabs/.github at a pinned SHA.

Merge order: jdwlabs/.github#48 → this PR (and jdwlabs/deployments' sibling PR, independent of this one). CANONICAL_REF in validate.yml currently points at the branch SHA e6ea75a8 of #48 so CI can pass now; after #48 merges (squash rewrites the SHA) re-pin it to the merged commit before merging this.

Divergence classification

Divergence Classification Resolution
Discovery: this repo globs every YAML under tenants/ + helm-charts/; deployments Helm-merges charts/<chart>/values-<env>.yaml onto values.yaml and fails a chart with no overlay repo-specific by design Config-selectable source kinds (tree, helm-overlays)
Allowlist key (path, ref) here vs (path, repository, tag) in deployments accidental drift (same intent, two schemas) This repo's ref schema kept; deployments migrates
Unquoted numeric tag: here kept literal text but treated as an ordinary, allowlistable violation; deployments reported malformed accidental drift Union: literal text kept, now malformed / not allowlistable (Helm's parser makes the same lossy 1.101.1 conversion)
Digest-only tag: "@sha256:…" in a structured block composed to repo:@sha256:…, matched the digest regex and read as pinned here accidental drift (false negative here) Rejected as malformed
Truncated digest / OCI tag grammar checks deployments only Everywhere
Template regex missed any line with a trailing # comment; .tpl partials never scanned accidental drift (false negatives here) Everywhere
registry:/digest: fields, registry-only blocks, <name>Image/<name>Tag sibling keys, embedded ConfigMap manifests, URL/path/template filtering, dedup here only Kept
Full report with Digest-pinned: inventory, MALFORMED section and 0 issues line deployments only Everywhere

Test plan

  • python3 -m unittest discover -s tools/tests -t tools/tests — 228 tests OK (vendored union suite + remote-chart checker suite)
  • python3 tools/check-image-pins.py — 18 digest-pinned, 26 allowlisted, 0 unexplained, 0 malformed; exit 0 (same counts as before)
  • python3 tools/check-remote-chart-image-pins.py — 24/24 charts checked, 4 allowlisted, 0 unexplained
  • Drift guard simulated locally: both vendored files cmp clean against jdwlabs/.github@e6ea75a8
  • actionlint .github/workflows/validate.yml — only the pre-existing shellcheck warning on main
  • CI green on this PR
  • CANONICAL_REF re-pinned to the merged SHA of chore(ci): unify check-image-pins.py — add the canonical copy (JDWLABS-451) .github#48

Refs JDWLABS-451.

🤖 Generated with Claude Code

https://claude.ai/code/session_016XRddumw4ZNvFqHSd9KSf6

…guard

This repo's image-pin checker and deployments' were forks that had
diverged into different programs, each catching defects the other missed.
The script is now the canonical copy from jdwlabs/.github, byte-identical
in both repos; this repo's scan scope (tenants/ and helm-charts/, with
templates/ scanned for literal references) is declared in
tools/image-pin-check.yaml instead of in the script.

Rules gained from the deployments side, all of which were false negatives
here: a digest-only `tag: "@sha256:…"` in a structured block composed to
`repo:@sha256:…`, matched the digest regex and read as pinned; template
lines with a trailing comment never matched the literal-reference regex;
`.tpl` partials were not scanned; truncated digests and tags outside the
OCI grammar were accepted. Unquoted numeric tags keep their literal text
but are now reported as malformed and cannot be allowlisted, since Helm's
own parser applies the same lossy conversion.

check-remote-chart-image-pins.py keeps reusing the checker's loader and
walker through the new refs_in_tree() entry point and passes its allowlist
path explicitly. CI compares the vendored script and test file against
jdwlabs/.github at a pinned commit and fails on any difference.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016XRddumw4ZNvFqHSd9KSf6
jdwillmsen and others added 2 commits August 29, 2026 23:57
remote-chart-image-pin-check, gitsync-tenant-folders, and adr-numbering
all run the shared test-discovery step, which imports the vendored
check-image-pins.py at module load (test_check_image_pins.py execs it).
A tampered vendored copy would run in these three jobs concurrently
with, not after, the drift guard that's supposed to catch it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GzFwqYVWFmpgh5h1zNxuWQ
Bumps CANONICAL_REF to jdwlabs/.github@accde604 (post-merge of both
JDWLABS-451's original convergence and the digest-only sibling-tag
bypass fix found in independent review). The prior pin
(e6ea75a8f0fb33b22434fa03b9163b78c8e9c2ef) was a PR-branch head SHA
that could never become an ancestor of jdwlabs/.github main on a
rebase-merge-only repo, so the drift guard would have stayed green
against a permanently stale snapshot.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GzFwqYVWFmpgh5h1zNxuWQ
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant