From c6cd661d47c9673eb077827d8afd197d45836558 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 25 Jul 2026 16:32:35 +0000 Subject: [PATCH] Update CLI checker for Docker digests Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../workflows/cli-version-checker.lock.yml | 6 +-- .github/workflows/cli-version-checker.md | 49 ++++++++++--------- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/.github/workflows/cli-version-checker.lock.yml b/.github/workflows/cli-version-checker.lock.yml index d47350c4cad..7001deb871f 100644 --- a/.github/workflows/cli-version-checker.lock.yml +++ b/.github/workflows/cli-version-checker.lock.yml @@ -1,4 +1,4 @@ -# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"9c046ed6e494e6624bc42bb82529938e4c5851aeec4b61797be6ec9ec1e32845","body_hash":"0f9b72c3cbb87011cb2f3959f4cb961df1ff10e9558c8729ba6ed9049a92c5da","agent_id":"claude","engine_versions":{"claude":"2.1.220"}} +# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"0be09cddf13820270e1c20d826956cdc2b7ee61979cca276e0d9098624a62760","body_hash":"3d59eb45e0dcc18734f565a4cdf9daffd2106a6020a4b999e7881b8ffa020f33","agent_id":"claude","engine_versions":{"claude":"2.1.220"}} # gh-aw-manifest: {"version":1,"secrets":["ANTHROPIC_API_KEY","COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GH_AW_OTEL_GRAFANA_AUTHORIZATION","GH_AW_OTEL_GRAFANA_ENDPOINT","GH_AW_OTEL_SENTRY_AUTHORIZATION","GH_AW_OTEL_SENTRY_ENDPOINT","GITHUB_TOKEN"],"actions":[{"repo":"actions/cache/restore","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/cache/save","sha":"55cc8345863c7cc4c66a329aec7e433d2d1c52a9","version":"v6.1.0"},{"repo":"actions/checkout","sha":"3d3c42e5aac5ba805825da76410c181273ba90b1","version":"v7.0.1"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"820762786026740c76f36085b0efc47a31fe5020","version":"v7.0.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.41","digest":"sha256:e39efa0edf10c0d0bfc572b59a186dfccb1973f0f77e224bcf6e5a7d81ee95c8","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.41@sha256:e39efa0edf10c0d0bfc572b59a186dfccb1973f0f77e224bcf6e5a7d81ee95c8"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.41","digest":"sha256:6e2200dcb6a62b183cdcf7ed86e44713ba5ed8eeaf8de143319458898b6e8118","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.41@sha256:6e2200dcb6a62b183cdcf7ed86e44713ba5ed8eeaf8de143319458898b6e8118"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.41","digest":"sha256:cfadaba80ad857ecb6603727296b42d92a9e0ff2f956276c4a46bb35f6f1ac24","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.41@sha256:cfadaba80ad857ecb6603727296b42d92a9e0ff2f956276c4a46bb35f6f1ac24"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.4.5","digest":"sha256:7550c5132d007266b696d77218e8d1b01f29e6e55520875b2431ef4044df71c9","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.4.5@sha256:7550c5132d007266b696d77218e8d1b01f29e6e55520875b2431ef4044df71c9"},{"image":"ghcr.io/github/gh-aw-node","digest":"sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748","pinned_image":"ghcr.io/github/gh-aw-node@sha256:a8082161d7dceda14b68f32eb39d0eaa96b825d07f5895b096afab9d9e0c7748"},{"image":"ghcr.io/github/github-mcp-server:v1.7.0","digest":"sha256:c491ffdf6f4c85cb5397021bc655edb8ab825c6f5f568e7597d77a1bd7c4d308","pinned_image":"ghcr.io/github/github-mcp-server:v1.7.0@sha256:c491ffdf6f4c85cb5397021bc655edb8ab825c6f5f568e7597d77a1bd7c4d308"}]} # This file was automatically generated by gh-aw. DO NOT EDIT. To debug this workflow, load the skill at https://github.com/github/gh-aw/blob/main/debug.md # @@ -1708,7 +1708,7 @@ jobs: if: always() uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_EVALS_QUESTIONS: '[{"id":"cli_versions_checked","question":"Did the agent check for new versions of agentic CLI tools (Claude Code, GitHub Copilot CLI, Codex, MCP servers, etc.)?"},{"id":"docker_images_checked","question":"Did the agent check for new versions of Docker images in pkg/cli/docker_images.go (actionlint, syft, grype, grant, zizmor, poutine, runner-guard, yamllint)?"},{"id":"updates_applied_or_noop","question":"Were version updates applied and a PR created, or was noop used when all tools were already up to date?"}]' + GH_AW_EVALS_QUESTIONS: '[{"id":"cli_versions_checked","question":"Did the agent check for new versions of agentic CLI tools (Claude Code, GitHub Copilot CLI, Codex, MCP servers, etc.)?"},{"id":"docker_images_checked","question":"Did the agent check for new versions and digest changes of Docker images in pkg/cli/docker_images.go (actionlint, syft, grype, grant, zizmor, poutine, runner-guard, yamllint)?"},{"id":"updates_applied_or_noop","question":"Were version or digest updates applied and a PR created, or was noop used when all tools were already up to date?"}]' GH_AW_EVALS_MODEL: "small" GH_AW_EVALS_PHASE: setup with: @@ -1818,7 +1818,7 @@ jobs: continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 env: - GH_AW_EVALS_QUESTIONS: '[{"id":"cli_versions_checked","question":"Did the agent check for new versions of agentic CLI tools (Claude Code, GitHub Copilot CLI, Codex, MCP servers, etc.)?"},{"id":"docker_images_checked","question":"Did the agent check for new versions of Docker images in pkg/cli/docker_images.go (actionlint, syft, grype, grant, zizmor, poutine, runner-guard, yamllint)?"},{"id":"updates_applied_or_noop","question":"Were version updates applied and a PR created, or was noop used when all tools were already up to date?"}]' + GH_AW_EVALS_QUESTIONS: '[{"id":"cli_versions_checked","question":"Did the agent check for new versions of agentic CLI tools (Claude Code, GitHub Copilot CLI, Codex, MCP servers, etc.)?"},{"id":"docker_images_checked","question":"Did the agent check for new versions and digest changes of Docker images in pkg/cli/docker_images.go (actionlint, syft, grype, grant, zizmor, poutine, runner-guard, yamllint)?"},{"id":"updates_applied_or_noop","question":"Were version or digest updates applied and a PR created, or was noop used when all tools were already up to date?"}]' GH_AW_EVALS_MODEL: "small" GH_AW_EVALS_PHASE: parse GITHUB_RUN_ID: ${{ github.run_id }} diff --git a/.github/workflows/cli-version-checker.md b/.github/workflows/cli-version-checker.md index 6453d7bbd7b..41e5683214a 100644 --- a/.github/workflows/cli-version-checker.md +++ b/.github/workflows/cli-version-checker.md @@ -41,9 +41,9 @@ evals: - id: cli_versions_checked question: Did the agent check for new versions of agentic CLI tools (Claude Code, GitHub Copilot CLI, Codex, MCP servers, etc.)? - id: docker_images_checked - question: Did the agent check for new versions of Docker images in pkg/cli/docker_images.go (actionlint, syft, grype, grant, zizmor, poutine, runner-guard, yamllint)? + question: Did the agent check for new versions and digest changes of Docker images in pkg/cli/docker_images.go (actionlint, syft, grype, grant, zizmor, poutine, runner-guard, yamllint)? - id: updates_applied_or_noop - question: Were version updates applied and a PR created, or was noop used when all tools were already up to date? + question: Were version or digest updates applied and a PR created, or was noop used when all tools were already up to date? --- # CLI Version Checker @@ -57,9 +57,9 @@ Monitor and update agentic CLI tools: Claude Code, GitHub Copilot CLI, OpenAI Co **EFFICIENCY FIRST**: Before starting: 1. Check cache-memory at `/tmp/gh-aw/cache-memory/` for previous version checks and help outputs 2. If cached versions exist and are recent (< 24h), verify if updates are needed before proceeding -3. If no version changes detected, exit early with success +3. If no CLI version, Docker image version, or Docker image digest changes are detected, exit early with success -**CRITICAL**: If ANY version changes are detected, you MUST create an issue using safe-outputs.create-issue. Do not skip issue creation even for minor updates. +**CRITICAL**: If ANY version or digest changes are detected, you MUST create an issue using safe-outputs.create-issue. Do not skip issue creation even for minor updates. For each CLI/MCP server: 1. Fetch latest version from NPM registry or GitHub releases (use npm view commands for package metadata) @@ -159,7 +159,7 @@ For each CLI tool update, install (`npm install -g @`), run `- ### Update Process 1. Edit `./pkg/constants/constants.go` with new CLI version(s) -2. Edit `./pkg/cli/docker_images.go` with new Docker image version(s) and digest(s) (if any Docker images were updated) +2. Edit `./pkg/cli/docker_images.go` with new Docker image version(s) and digest(s), including digest-only changes where the tag is unchanged 3. Run `make fmt` after editing any Go files 4. **REQUIRED**: Run `make recompile` in the **foreground** — do NOT background it with `&` or follow it with `sleep`. Wait for it to finish completely before proceeding. Example: `make recompile && echo "done"`. 5. Verify changes with `git status` @@ -200,7 +200,7 @@ For each updated CLI, include: version old → new, release timeline, changes ca ## Docker Image Version Checking -After checking CLI tools, also check the Docker images defined in `./pkg/cli/docker_images.go` for updates. +After checking CLI tools, also check the Docker images defined in `./pkg/cli/docker_images.go` for version and digest updates. Resolve the registry digest for every image on every run and compare it with the digest pinned in the Go constant. A changed digest is an update even when the image tag is unchanged. ### Docker Image Sources @@ -208,29 +208,29 @@ Fetch the latest release for each image from its GitHub repository: | Constant | Current image | GitHub releases URL | |---|---|---| -| `ActionlintImage` | `rhysd/actionlint:` | `https://api.github.com/repos/rhysd/actionlint/releases/latest` | +| `ActionlintImage` | `rhysd/actionlint:@sha256:` | `https://api.github.com/repos/rhysd/actionlint/releases/latest` | | `SyftImage` | `anchore/syft:@sha256:` | `https://api.github.com/repos/anchore/syft/releases/latest` | | `GrypeImage` | `anchore/grype:@sha256:` | `https://api.github.com/repos/anchore/grype/releases/latest` | | `GrantImage` | `anchore/grant:@sha256:` | `https://api.github.com/repos/anchore/grant/releases/latest` | -| `ZizmorImage` | `ghcr.io/zizmorcore/zizmor:latest` | `https://api.github.com/repos/zizmorcore/zizmor/releases/latest` | -| `PoutineImage` | `ghcr.io/boostsecurityio/poutine:latest` | `https://api.github.com/repos/boostsecurityio/poutine/releases/latest` | -| `RunnerGuardImage` | `ghcr.io/vigilant-llc/runner-guard:latest` | `https://api.github.com/repos/vigilant-llc/runner-guard/releases/latest` | -| `YamllintImage` | `pipelinecomponents/yamllint:latest` | `https://api.github.com/repos/PipelineComponents/yamllint/releases/latest` | +| `ZizmorImage` | `ghcr.io/zizmorcore/zizmor:@sha256:` | `https://api.github.com/repos/zizmorcore/zizmor/releases/latest` | +| `PoutineImage` | `ghcr.io/boostsecurityio/poutine:@sha256:` | `https://api.github.com/repos/boostsecurityio/poutine/releases/latest` | +| `RunnerGuardImage` | `ghcr.io/vigilant-llc/runner-guard:@sha256:` | `https://api.github.com/repos/vigilant-llc/runner-guard/releases/latest` | +| `YamllintImage` | `pipelinecomponents/yamllint:@sha256:` | `https://api.github.com/repos/PipelineComponents/yamllint/releases/latest` | **Optimization**: Fetch all GitHub release endpoints in parallel in a single turn. ### 3-Day Cooldown -Before considering any Docker image update, check that the release is **at least 3 days old**: +Before considering any Docker image version update, check that the release is **at least 3 days old**: 1. Parse the `published_at` field from the GitHub releases API response. 2. Compute `(current date) - published_at`. If less than 3 days, **skip** that image — do not update it or include it in the issue. 3. Only proceed with images whose latest release is ≥ 3 days old. -This avoids picking up immature or quickly-retracted releases. +This avoids picking up immature or quickly-retracted releases. Digest-only updates for an already-pinned version are not subject to the release cooldown. ### Fetching the Container SHA -For each Docker image that has a newer version (and passed the 3-day cooldown), fetch its digest: +For every Docker image, fetch the registry digest for the target tag. For a newer version, apply the 3-day cooldown first. Also fetch and compare the digest when the version is unchanged so mutable or republished tags are reflected in `docker_images.go`. **Docker Hub images** (actionlint, syft, grype, grant, yamllint): ```bash @@ -265,19 +265,19 @@ curl -sI \ **CRITICAL**: Always record the digest as `sha256:`. This is the value that goes after `@` in the image reference. -### Updating docker_images.go +### Comparing and Updating docker_images.go -After fetching the new version and digest, edit `./pkg/cli/docker_images.go`: +Compare each fetched digest with the `@sha256:...` value in `./pkg/cli/docker_images.go`. If the constant has no digest, treat it as needing an update. Edit the file whenever the version or digest differs: -- **Versioned images with existing digest** (syft, grype, grant): update both the version tag and the `@sha256:...` digest in the existing string format, e.g.: +- **All images**: pin the selected version tag and registry digest in the existing string format, e.g.: ``` SyftImage = "anchore/syft:v1.49.0@sha256:" ``` -- **Versioned images without digest** (actionlint): update only the version tag, e.g.: +- **Digest-only changes**: preserve the current version tag and replace only the digest, e.g.: ``` - ActionlintImage = "rhysd/actionlint:1.7.13" + ActionlintImage = "rhysd/actionlint:1.7.13@sha256:" ``` -- **Images currently tagged `:latest`** (zizmor, poutine, runner-guard, yamllint): **pin** them to the new versioned tag with digest, e.g.: +- **Images currently tagged `:latest`**: replace `latest` with the latest stable release tag that passed the cooldown and pin its digest, e.g.: ``` ZizmorImage = "ghcr.io/zizmorcore/zizmor:v1.0.0@sha256:" ``` @@ -285,9 +285,9 @@ After fetching the new version and digest, edit `./pkg/cli/docker_images.go`: ### Docker Image Update Process 1. Fetch all latest releases in parallel via `api.github.com`. -2. Apply the 3-day cooldown — skip any image whose release is < 3 days old. -3. For images with a passing release, fetch the container digest (see "Fetching the Container SHA" above). -4. Edit `./pkg/cli/docker_images.go` with the new version(s) and digest(s). +2. Apply the 3-day cooldown to version updates — skip a newer release if it is < 3 days old. +3. Fetch the container digest for every selected tag, including unchanged versions (see "Fetching the Container SHA" above). +4. Compare each fetched digest with `./pkg/cli/docker_images.go` and edit the constant for version changes, digest changes, or missing digests. 5. Run `make fmt` to format any changed Go files. 6. Include Docker image update details in the issue created by safe-outputs. @@ -295,8 +295,9 @@ After fetching the new version and digest, edit `./pkg/cli/docker_images.go`: For each updated Docker image, include: - Image name and constant (e.g., `SyftImage`) -- Version change: old → new +- Version change: old → new (or "unchanged" for a digest-only update) - Release date and cooldown confirmation (e.g., "Released 2026-07-20 — 5 days ago, cooldown passed") +- Digest change: old digest → new digest (or "missing → new digest") - Container digest (e.g., `sha256:abc123...`) - Full image reference: `anchore/syft:v1.49.0@sha256:abc123...` - Link to the GitHub release