Skip to content

feat: container image digest pinning in actions-lock.json with update/upgrade integration#25619

Closed
Copilot wants to merge 7 commits intomainfrom
copilot/fix-container-image-digest-pinning-again
Closed

feat: container image digest pinning in actions-lock.json with update/upgrade integration#25619
Copilot wants to merge 7 commits intomainfrom
copilot/fix-container-image-digest-pinning-again

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 10, 2026

All MCP container images (node:lts-alpine, ghcr.io/github/gh-aw-firewall/*, ghcr.io/github/gh-aw-mcpg, ghcr.io/github/github-mcp-server) were pulled by mutable tag with no SHA-256 pinning — node:lts-alpine is additionally floating across LTS generations. This extends the existing action-pin infrastructure to cover Docker images.

Storage — actions-lock.json

New containers section alongside entries, keyed by image tag:

{
  "entries": { ... },
  "containers": {
    "node:lts-alpine": {
      "image": "node:lts-alpine",
      "digest": "sha256:abc123...",
      "pinned_image": "node:lts-alpine@sha256:abc123..."
    }
  }
}

ActionCache gains GetContainerPin / SetContainerPin / DeleteContainerPin. Loading a legacy file (no containers) is fully backward-compatible.

Compilation

  • collectDockerImages applies cached pins, substituting tag@sha256:… for any image with a stored entry.
  • WorkflowData.DockerImages accumulates the resolved (possibly pinned) refs so they can be surfaced in the lock file.
  • WorkflowData.DockerImagePins accumulates full GHAWManifestContainer entries (image, digest, pinned_image) for the manifest.
  • Lock file headers now emit a # Container images used: comment section.
  • gh-aw-manifest JSON gains a "containers":[…] field with full structured container info including SHA-256 digest when available:
    "containers":[{"image":"ghcr.io/github/gh-aw-mcpg:v0.2.17"},{"image":"node:lts-alpine","digest":"sha256:abc...","pinned_image":"node:lts-alpine@sha256:abc..."}]

Update/Upgrade integration — pkg/cli/update_container_pins.go

UpdateContainerPins() is called from both gh aw update and gh aw upgrade (after action pins, before compile):

  1. Scans existing .lock.yml files for download_docker_images.sh invocations to discover in-use image tags.
  2. Resolves each tag's digest via docker buildx imagetools inspect (no pull required); falls back to docker pull + docker inspect.
  3. Saves pins to actions-lock.json; next compile embeds the @sha256:… suffix.
  4. Docker unavailability is non-fatal — the update/upgrade continues without pinning.

- Extend ActionCache with ContainerPins map (stored in actions-lock.json)
- Add ContainerPin type with image, digest, and pinned_image fields
- Modify collectDockerImages to apply cached digest pins and store images in WorkflowData
- Add DockerImages field to WorkflowData for header/manifest tracking
- Extend GHAWManifest with containers field (in gh-aw-manifest JSON)
- Add Container images used: section to lock file header comments
- Create UpdateContainerPins CLI function that resolves digests via Docker
- Integrate container pin update into upgrade command (step 3b)
- Recompile all lock files with updated manifest and header format

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/688c5141-cf5f-4a69-9935-1dad34a50e18

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix container image pull with SHA-256 digest pinning feat: container image digest pinning in actions-lock.json with upgrade integration Apr 10, 2026
Copilot AI requested a review from pelikhan April 10, 2026 12:12
@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot

  • rename container_pins to containers
  • resolve current used containers
  • store containers full info in gh-aw-manifest (including sha)

…o manifest, add update command integration

- Rename ActionCache JSON key from container_pins to containers
- Add GHAWManifestContainer type with image/digest/pinned_image fields
- Change GHAWManifest.Containers from []string to []GHAWManifestContainer
- Track DockerImagePins []GHAWManifestContainer in WorkflowData for manifest
- Add UpdateContainerPins to update command (not just upgrade)
- Recompile all lock files

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/0d5cf327-a467-40fa-8347-f0e797db7dd4

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 10, 2026

@copilot

  • rename container_pins to containers...

Done in 88fe858:

  1. Renamed container_pinscontainers — the JSON key in actions-lock.json is now "containers" (both the struct tag and the marshalSorted output).

  2. Resolve containers in update commandUpdateContainerPins is now also called from RunUpdateWorkflows (the gh aw update flow), not just from upgrade.

  3. Full container info in gh-aw-manifest — added a new GHAWManifestContainer type (image, digest, pinned_image) and changed GHAWManifest.Containers from []string to []GHAWManifestContainer. The manifest now embeds structured objects like:

    "containers":[{"image":"ghcr.io/github/gh-aw-mcpg:v0.2.17"},{"image":"node:lts-alpine","digest":"sha256:abc...","pinned_image":"node:lts-alpine@sha256:abc..."}]

    Images without a cached pin emit only image; pinned images include digest and pinned_image.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw GOMOD GOMODCACHE go env ck &#39;**/*.cjs&#39; &#39;*GOINSECURE GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw GOMOD GOMODCACHE go env ck &#39;**/*.cjs&#39; &#39;*GOINSECURE GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/xGO111MODULE (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw GOMOD GOMODCACHE ortcfg env d/gh-aw/main.go d/gh-aw/capitaliGOMOD 64/bin/go GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/xGO111MODULE (http block)
  • https://api.github.com/repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b
    • Triggering command: /usr/bin/gh gh api /repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b --jq .object.sha ck &#39;scripts/**/*GOINSECURE GO111MODULE $name) { hasDiscussionsEnabled } } GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE node (http block)
    • Triggering command: /usr/bin/gh gh api /repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b --jq .object.sha ck &#39;scripts/**/*GOINSECURE GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE sh (http block)
  • https://api.github.com/repos/github/gh-aw
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw --jq .visibility -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env iew.lock.yml GO111MODULE r: $owner, name: $name) { hasDiscussionsEnabled } } GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/githubnext/agentics/git/ref/tags/-
    • Triggering command: /usr/bin/gh gh api /repos/githubnext/agentics/git/ref/tags/- --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE sh -c &#34;prettier&#34; --che-f GOPROXY 64/bin/go GOSUMDB GOWORK 64/bin/go go (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI changed the title feat: container image digest pinning in actions-lock.json with upgrade integration feat: container image digest pinning in actions-lock.json with update/upgrade integration Apr 10, 2026
@pelikhan pelikhan marked this pull request as ready for review April 10, 2026 14:38
Copilot AI review requested due to automatic review settings April 10, 2026 14:38
@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot merge main, recompile

Copilot AI and others added 2 commits April 10, 2026 14:43
…-image-digest-pinning-again

# Conflicts:
#	.github/workflows/smoke-gemini.lock.yml

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 10, 2026

@copilot merge main, recompile

Done in 8c6572d. Merged origin/main (resolved one conflict in smoke-gemini.lock.yml by keeping our version which includes the containers manifest field), built the binary, and recompiled all 187 workflow lock files.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw -embedcfg /tmp/go-build2972085743/b063/embedcfg -pack (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw gjaW63C/SPpIQ-6Prev-parse (http block)
  • https://api.github.com/repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b
    • Triggering command: /usr/bin/gh gh api /repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b --jq .object.sha (http block)
  • https://api.github.com/repos/github/gh-aw
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw --jq .visibility (http block)
  • https://api.github.com/repos/githubnext/agentics/git/ref/tags/-
    • Triggering command: /usr/bin/gh gh api /repos/githubnext/agentics/git/ref/tags/- --jq .object.sha (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Extends the existing action pinning/locking system to also support Docker image digest pinning and surfaces container usage in generated workflow lock headers and the embedded gh-aw-manifest.

Changes:

  • Add container pin storage to actions-lock.json via ActionCache container pin CRUD + (de)serialization.
  • Collect workflow container images during compilation, emit them in lock header comments, and include structured container info in gh-aw-manifest.
  • Integrate UpdateContainerPins() into gh aw update and gh aw upgrade to discover images from .lock.yml files and resolve digests via Docker.
Show a summary per file
File Description
pkg/workflow/action_cache.go Adds container pin data model + load/save support in the action cache.
pkg/workflow/docker.go Collects container images at compile-time and applies cached digest pins.
pkg/workflow/compiler_types.go Extends WorkflowData with DockerImages/DockerImagePins for header + manifest output.
pkg/workflow/compiler_yaml.go Embeds containers into gh-aw-manifest and adds a “Container images used” header section.
pkg/workflow/safe_update_manifest.go Extends manifest schema to include container image entries.
pkg/workflow/safe_update_manifest_test.go Updates manifest tests for the new constructor signature.
pkg/workflow/action_cache_container_pin_test.go Adds unit tests for container pin CRUD and JSON round-tripping.
pkg/workflow/docker_pin_test.go Adds unit tests for container pin application/merging and WorkflowData population.
pkg/cli/update_container_pins.go Adds discovery of container images from .lock.yml and digest resolution via Docker CLI.
pkg/cli/update_container_pins_test.go Adds tests for extracting container images from lock files.
pkg/cli/update_command.go Runs container pin updates during gh aw update.
pkg/cli/upgrade_command.go Runs container pin updates during gh aw upgrade before compilation.
.github/workflows/ace-editor.lock.yml Manifest/header regenerated to include container list.
.github/workflows/approach-validator.lock.yml Manifest/header regenerated to include container list.
.github/workflows/archie.lock.yml Manifest/header regenerated to include container list.
.github/workflows/architecture-guardian.lock.yml Manifest/header regenerated to include container list.
.github/workflows/artifacts-summary.lock.yml Manifest/header regenerated to include container list.
.github/workflows/auto-triage-issues.lock.yml Manifest/header regenerated to include container list.
.github/workflows/blog-auditor.lock.yml Manifest/header regenerated to include container list.
.github/workflows/bot-detection.lock.yml Manifest/header regenerated to include container list.
.github/workflows/brave.lock.yml Manifest/header regenerated to include container list.
.github/workflows/breaking-change-checker.lock.yml Manifest/header regenerated to include container list.
.github/workflows/changeset.lock.yml Manifest/header regenerated to include container list.
.github/workflows/cli-consistency-checker.lock.yml Manifest/header regenerated to include container list.
.github/workflows/code-simplifier.lock.yml Manifest/header regenerated to include container list.
.github/workflows/codex-github-remote-mcp-test.lock.yml Manifest/header regenerated to include container list.
.github/workflows/commit-changes-analyzer.lock.yml Manifest/header regenerated to include container list.
.github/workflows/contribution-check.lock.yml Manifest/header regenerated to include container list.
.github/workflows/copilot-cli-deep-research.lock.yml Manifest/header regenerated to include container list.
.github/workflows/craft.lock.yml Manifest/header regenerated to include container list.
.github/workflows/daily-assign-issue-to-user.lock.yml Manifest/header regenerated to include container list.
.github/workflows/daily-choice-test.lock.yml Manifest/header regenerated to include container list.
.github/workflows/daily-cli-performance.lock.yml Manifest/header regenerated to include container list.
.github/workflows/daily-community-attribution.lock.yml Manifest/header regenerated to include container list.
.github/workflows/daily-fact.lock.yml Manifest/header regenerated to include container list.
.github/workflows/daily-file-diet.lock.yml Manifest/header regenerated to include container list.
.github/workflows/daily-malicious-code-scan.lock.yml Manifest/header regenerated to include container list.
.github/workflows/daily-regulatory.lock.yml Manifest/header regenerated to include container list.
.github/workflows/daily-safe-output-integrator.lock.yml Manifest/header regenerated to include container list.
.github/workflows/daily-safe-outputs-conformance.lock.yml Manifest/header regenerated to include container list.
.github/workflows/daily-secrets-analysis.lock.yml Manifest/header regenerated to include container list.
.github/workflows/daily-security-red-team.lock.yml Manifest/header regenerated to include container list.
.github/workflows/daily-syntax-error-quality.lock.yml Manifest/header regenerated to include container list.
.github/workflows/daily-team-evolution-insights.lock.yml Manifest/header regenerated to include container list.
.github/workflows/daily-team-status.lock.yml Manifest/header regenerated to include container list.
.github/workflows/daily-testify-uber-super-expert.lock.yml Manifest/header regenerated to include container list.
.github/workflows/daily-workflow-updater.lock.yml Manifest/header regenerated to include container list.
.github/workflows/delight.lock.yml Manifest/header regenerated to include container list.
.github/workflows/dependabot-burner.lock.yml Manifest/header regenerated to include container list.
.github/workflows/dependabot-go-checker.lock.yml Manifest/header regenerated to include container list.
.github/workflows/design-decision-gate.lock.yml Manifest/header regenerated to include container list.
.github/workflows/dev.lock.yml Manifest/header regenerated to include container list.
.github/workflows/dictation-prompt.lock.yml Manifest/header regenerated to include container list.
.github/workflows/discussion-task-miner.lock.yml Manifest/header regenerated to include container list.
.github/workflows/docs-noob-tester.lock.yml Manifest/header regenerated to include container list.
.github/workflows/draft-pr-cleanup.lock.yml Manifest/header regenerated to include container list.
.github/workflows/duplicate-code-detector.lock.yml Manifest/header regenerated to include container list.
.github/workflows/example-permissions-warning.lock.yml Manifest/header regenerated to include container list.
.github/workflows/firewall.lock.yml Manifest/header regenerated to include container list.
.github/workflows/functional-pragmatist.lock.yml Manifest/header regenerated to include container list.
.github/workflows/github-remote-mcp-auth-test.lock.yml Manifest/header regenerated to include container list.
.github/workflows/go-pattern-detector.lock.yml Manifest/header regenerated to include container list.
.github/workflows/issue-arborist.lock.yml Manifest/header regenerated to include container list.
.github/workflows/issue-monster.lock.yml Manifest/header regenerated to include container list.
.github/workflows/issue-triage-agent.lock.yml Manifest/header regenerated to include container list.
.github/workflows/layout-spec-maintainer.lock.yml Manifest/header regenerated to include container list.
.github/workflows/mergefest.lock.yml Manifest/header regenerated to include container list.
.github/workflows/notion-issue-summary.lock.yml Manifest/header regenerated to include container list.
.github/workflows/plan.lock.yml Manifest/header regenerated to include container list.
.github/workflows/pr-triage-agent.lock.yml Manifest/header regenerated to include container list.
.github/workflows/refiner.lock.yml Manifest/header regenerated to include container list.
.github/workflows/repo-tree-map.lock.yml Manifest/header regenerated to include container list.
.github/workflows/research.lock.yml Manifest/header regenerated to include container list.
.github/workflows/schema-feature-coverage.lock.yml Manifest/header regenerated to include container list.
.github/workflows/security-compliance.lock.yml Manifest/header regenerated to include container list.
.github/workflows/semantic-function-refactor.lock.yml Manifest/header regenerated to include container list.
.github/workflows/smoke-agent-all-merged.lock.yml Manifest/header regenerated to include container list.
.github/workflows/smoke-agent-all-none.lock.yml Manifest/header regenerated to include container list.
.github/workflows/smoke-agent-public-approved.lock.yml Manifest/header regenerated to include container list.
.github/workflows/smoke-agent-public-none.lock.yml Manifest/header regenerated to include container list.
.github/workflows/smoke-agent-scoped-approved.lock.yml Manifest/header regenerated to include container list.
.github/workflows/smoke-call-workflow.lock.yml Manifest/header regenerated to include container list.
.github/workflows/smoke-create-cross-repo-pr.lock.yml Manifest/header regenerated to include container list.
.github/workflows/smoke-multi-pr.lock.yml Manifest/header regenerated to include container list.
.github/workflows/smoke-project.lock.yml Manifest/header regenerated to include container list.
.github/workflows/smoke-service-ports.lock.yml Manifest/header regenerated to include container list.
.github/workflows/smoke-temporary-id.lock.yml Manifest/header regenerated to include container list.
.github/workflows/smoke-workflow-call-with-inputs.lock.yml Manifest/header regenerated to include container list.
.github/workflows/smoke-workflow-call.lock.yml Manifest/header regenerated to include container list.
.github/workflows/sub-issue-closer.lock.yml Manifest/header regenerated to include container list.
.github/workflows/terminal-stylist.lock.yml Manifest/header regenerated to include container list.
.github/workflows/test-dispatcher.lock.yml Manifest/header regenerated to include container list.
.github/workflows/test-project-url-default.lock.yml Manifest/header regenerated to include container list.
.github/workflows/test-quality-sentinel.lock.yml Manifest/header regenerated to include container list.
.github/workflows/test-workflow.lock.yml Manifest/header regenerated to include container list.
.github/workflows/typist.lock.yml Manifest/header regenerated to include container list.
.github/workflows/ubuntu-image-analyzer.lock.yml Manifest/header regenerated to include container list.
.github/workflows/update-astro.lock.yml Manifest/header regenerated to include container list.
.github/workflows/video-analyzer.lock.yml Manifest/header regenerated to include container list.
.github/workflows/weekly-editors-health-check.lock.yml Manifest/header regenerated to include container list.
.github/workflows/weekly-safe-outputs-spec-review.lock.yml Manifest/header regenerated to include container list.
.github/workflows/workflow-generator.lock.yml Manifest/header regenerated to include container list.
.github/workflows/workflow-health-manager.lock.yml Manifest/header regenerated to include container list.
.github/workflows/workflow-skill-extractor.lock.yml Manifest/header regenerated to include container list.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 200/200 changed files
  • Comments generated: 3

Comment on lines +228 to +233
result = append(result, []byte(" }")...)

// Add container_pins section if non-empty
if len(c.ContainerPins) > 0 {
pinKeys := make([]string, 0, len(c.ContainerPins))
for k := range c.ContainerPins {
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

marshalSorted now supports emitting a non-empty "containers" section, but ActionCache.Save still appears to treat the cache as “empty” based only on Entries. If Entries is empty but ContainerPins is non-empty, Save may skip writing/deleting the file, dropping container pins. Consider updating Save’s emptiness check to keep/write the file when ContainerPins has data (even if Entries is empty).

Copilot uses AI. Check for mistakes.
Comment on lines +208 to +214
for i, img := range images {
if cache != nil {
if pin, ok := cache.GetContainerPin(img); ok {
result[i] = pin.PinnedImage
pins[i] = GHAWManifestContainer(pin)
dockerLog.Printf("Pinned container image: %s -> %s", img, pin.PinnedImage)
continue
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

The conversion GHAWManifestContainer(pin) is not valid unless ContainerPin and GHAWManifestContainer have identical underlying struct types (including identical field tags). These structs currently have different JSON tags (omitempty vs not), so this will not compile. Suggest mapping fields explicitly (Image/Digest/PinnedImage) and also only substituting when pin.PinnedImage is non-empty to avoid emitting an empty image ref if the cache entry is malformed.

Copilot uses AI. Check for mistakes.
Comment on lines +221 to +229
// resolveDigestViaBuildx uses "docker buildx imagetools inspect" to get the content
// digest without pulling the image layers.
func resolveDigestViaBuildx(image string) (string, error) {
// docker buildx imagetools inspect IMAGE --format '{{.Manifest.Digest}}'
// outputs a single line like: sha256:abc123...
out, err := exec.Command("docker", "buildx", "imagetools", "inspect",
image, "--format", "{{.Manifest.Digest}}").Output()
if err != nil {
return "", err
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

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

resolveDigestViaBuildx/resolveDigestViaPull invoke Docker commands without a context/timeout. Since UpdateContainerPins runs as part of update/upgrade flows, a hung Docker daemon/network operation could block the entire CLI indefinitely. Consider using exec.CommandContext with a reasonable timeout (and capturing stderr via CombinedOutput) so failures are bounded and diagnosable.

Copilot uses AI. Check for mistakes.
@pelikhan
Copy link
Copy Markdown
Collaborator

@copilot review comments

…d, Docker command timeouts

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/2d94cf18-69a0-44f6-ab35-057ebb9b9ca4

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
…se tests for SetContainerPin

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/2d94cf18-69a0-44f6-ab35-057ebb9b9ca4

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 10, 2026

@copilot review comments

Addressed all three review comments in b2ab7df (and the prior 47274e4):

  1. action_cache.go Save emptiness check — changed if len(c.Entries) == 0 to if len(c.Entries) == 0 && len(c.ContainerPins) == 0 so a cache with only container pins still gets written. Added TestActionCacheSaveWithContainerPinsOnly to cover this case.

  2. docker.go type conversion — kept GHAWManifestContainer(pin) (which Go 1.8+ allows when struct tags differ) but added a pin.PinnedImage != "" guard so a malformed cache entry with an empty PinnedImage is skipped rather than substituted.

  3. update_container_pins.go Docker timeouts — switched all three Docker exec calls (buildx imagetools inspect, docker pull, docker inspect) to exec.CommandContext with a 60-second dockerCmdTimeout constant; both resolveDigestViaBuildx and resolveDigestViaPull now use CombinedOutput() and include stderr in error messages; added a comment explaining the 60-second rationale; also added edge-case tests for SetContainerPin.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw GO111MODULE /opt/hostedtoolc--show-toplevel git rev-�� --show-toplevel /opt/hostedtoolcache/go/1.25.8/x64/pkg/tool/linux_amd64/link /usr/bin/gh ithub-script/gitgit tmain.go /usr/bin/git gh (http block)
  • https://api.github.com/orgs/test-owner/actions/secrets
    • Triggering command: /usr/bin/gh gh api /orgs/test-owner/actions/secrets --jq .secrets[].name ck &#39;**/*.cjs&#39; &#39;*GOINSECURE GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE tcbQ_Ihm_uaw env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE ache/go/1.25.8/x--show-toplevel git rev-�� --show-toplevel go /usr/bin/git -json GO111MODULE ache/go/1.25.8/x--package-lock-only git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha GOMODCACHE l ache/node/24.14.1/x64/bin/node -t security 64/bin/go git t-39�� k/gh-aw/gh-aw/.github/workflows/architecture-guardian.md remote.origin.url /opt/hostedtoolcache/node/24.14.1/x64/bin/node npx prettier --cgit 53 64/bin/go node (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha -json GO111MODULE x_amd64/vet GOINSECURE GOMOD GOMODCACHE x_amd64/vet env Onlymin-integrity_with_explicit_repo3902949550/001 GO111MODULE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel x_amd64/compile /usr/bin/git 1rfMVZiro GO111MODULE ache/go/1.25.8/x--show-toplevel git rev-�� --show-toplevel go /usr/bin/git -json tmain.go erutil.test git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go /usr/bin/git conf�� --get-regexp ^remote\..*\.gh-resolved$ /usr/bin/git y_with_repos=pubgit GO111MODULE 64/pkg/tool/linu--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha GOMODCACHE go /usr/bin/git -json GO111MODULE 64/bin/go git rev-�� --show-toplevel go /usr/bin/git ithout_min-integgit GO111MODULE 64/pkg/tool/linu--show-toplevel git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha --show-toplevel 1/x64/bin/node /usr/bin/git ow-with-reactiongit go ache/node/24.14.--show-toplevel git rev-�� --show-toplevel git /usr/bin/git k/gh-aw/gh-aw/.ggit go /opt/hostedtoolc--show-toplevel git (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v9
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq .object.sha GOSUMDB GOWORK 64/bin/go GOINSECURE GOMOD GOMODCACHE go k/gh�� -json GO111MODULE 64/bin/go GOINSECURE GOMOD erignore go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE sh (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v9 --jq .object.sha latted/flatted.go GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE node (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go /usr/bin/git conf�� --get-regexp ^remote\..*\.gh-resolved$ /usr/bin/git y_with_repos_arrgit GO111MODULE 64/pkg/tool/linu--show-toplevel git (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha --show-toplevel go /usr/bin/git mLsRemoteWithReagit mLsRemoteWithRearev-parse 64/bin/go /usr/bin/git conf�� --get-regexp ^remote\..*\.gh-resolved$ /usr/bin/git -json GO111MODULE 64/pkg/tool/linu--show-toplevel git (http block)
  • https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha . go ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet heck &#39;**/*.cjs&#39; git GO111MODULE 64/bin/go ache/go/1.25.8/x64/pkg/tool/linux_amd64/vet (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v0.1.2
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v0.1.2 --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go /usr/bin/git conf�� --get-regexp ^remote\..*\.gh-resolved$ /usr/bin/git y-test.md GO111MODULE 64/bin/go git (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq .object.sha /tmp/go-build460661685/b421/_pkg_.a -trimpath e/git -p github.com/githurev-parse -lang=go1.25 e/git -C /tmp/TestGuardPolicyBlockedUsersApprovalLabelsCompiledOutput68827437/001 config clusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle remote.origin.urgit -nolocalimports -importcfg git (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq .object.sha uA93qbjr3M16rfeHkmQQ/uA93qbjr3M16rfeHkmQQ -goversion /usr/bin/git -c=4 -nolocalimports -importcfg git rev-�� --show-toplevel erignore ache/node/24.14.1/x64/bin/node -json GO111MODULE 64/bin/go git (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/1/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/1/artifacts --jq .artifacts[].name GO111MODULE 1/x64/bin/bash GOINSECURE GOMOD GOMODCACHE go env 1839510617 GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 1 --dir test-logs/run-1 GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linuTest User env -json GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12345/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/12345/artifacts --jq .artifacts[].name GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 12345 --dir test-logs/run-12345 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE k GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/12346/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/12346/artifacts --jq .artifacts[].name GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 12346 --dir test-logs/run-12346 GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env 3347120507 GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/2/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/2/artifacts --jq .artifacts[].name GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env 1839510617 GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 2 --dir test-logs/run-2 GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linutest@example.com env -json cfg ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/3/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/3/artifacts --jq .artifacts[].name GO111MODULE ache/go/1.25.8/x-nolocalimports GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 3 --dir test-logs/run-3 GO111MODULE 64/pkg/tool/linux_amd64/compile GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/compile env _.a GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE setup/js/node_morev-parse GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/4/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/4/artifacts --jq .artifacts[].name GO111MODULE de/node/bin/bash GOINSECURE GOMOD GOMODCACHE go env 1839510617 GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 4 --dir test-logs/run-4 GO111MODULE 64/pkg/tool/linux_amd64/vet GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env -json GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/actions/runs/5/artifacts
    • Triggering command: /usr/bin/gh gh api --paginate repos/{owner}/{repo}/actions/runs/5/artifacts --jq .artifacts[].name GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env 1839510617 GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run download 5 --dir test-logs/run-5 GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path -c=4 -nolocalimports -importcfg /tmp/go-build460661685/b414/importcfg -pack /home/REDACTED/work/gh-aw/gh-aw/pkg/gitutil/gitutil.go /home/REDACTED/work/gh-aw/gh-aw/pkg/gitutil/gitutil_test.go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 100 GOMOD GOMODCACHE sh -c &#34;prettier&#34; --chego1.25.8 GOPROXY 64/bin/go GOSUMDB GOWORK 64/bin/go /opt/hostedtoolcremote (http block)
    • Triggering command: /usr/bin/gh gh run list --json databaseId,number,url,status,conclusion,workflowName,createdAt,startedAt,updatedAt,event,headBranch,headSha,displayTitle --workflow nonexistent-workflow-12345 --limit 6 GOMOD GOMODCACHE go env -json GO111MODULE 64/pkg/tool/linux_amd64/compile GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/compile (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v0.47.4
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v0.47.4 --jq .object.sha --show-toplevel Po/5GniUk8RBwwF8S8eKncR/xY8IG6Crtest@example.com /usr/bin/git /ref/tags/v9 GO111MODULE 64/pkg/tool/linu--show-toplevel git rev-�� --show-toplevel 64/pkg/tool/linux_amd64/link /usr/bin/git ngutil.test GO111MODULE rtcfg.link git (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha til.go o 64/pkg/tool/linux_amd64/compile GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/compile env _.a GO111MODULE x_amd64/compile GOINSECURE til GOMODCACHE x_amd64/compile (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.2.3 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE sh -c &#34;prettier&#34; --check &#39;**/*.cjs&#39; &#39;*GOINSECURE GOPROXY 64/bin/go GOSUMDB GOWORK 64/bin/go go (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v2.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE sh -c &#34;prettier&#34; --che--repo GOPROXY 64/bin/go GOSUMDB GOWORK 64/bin/go go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v2.0.0 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE node /hom�� --check **/*.cjs 64/bin/go **/*.json --ignore-path ../../../.pretti--show-toplevel go (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v3.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v3.0.0 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE sh -c &#34;prettier&#34; --check &#39;**/*.cjs&#39; &#39;*GOINSECURE GOPROXY 64/bin/go GOSUMDB GOWORK run-script/lib/n--show-toplevel go (http block)
  • https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha -json GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE x_amd64/compile GOINSECURE GOMOD GOMODCACHE x_amd64/compile (http block)
  • https://api.github.com/repos/nonexistent/repo/actions/runs/12345
    • Triggering command: /usr/bin/gh gh run view 12345 --repo nonexistent/repo --json status,conclusion GOINSECURE GOMOD GOMODCACHE 64/pkg/tool/linux_amd64/vet env -json GO111MODULE ache/go/1.25.8/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/owner/repo/actions/workflows
    • Triggering command: /usr/bin/gh gh workflow list --json name,state,path --repo owner/repo 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/owner/repo/contents/file.md
    • Triggering command: /tmp/go-build460661685/b397/cli.test /tmp/go-build460661685/b397/cli.test -test.testlogfile=/tmp/go-build460661685/b397/testlog.txt -test.paniconexit0 -test.v=true -test.parallel=4 -test.timeout=10m0s -test.run=^Test -test.short=true GOINSECURE GOMOD GOMODCACHE go env ck &#39;**/*.cjs&#39; &#39;*GOINSECURE GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/test-owner/test-repo/actions/secrets
    • Triggering command: /usr/bin/gh gh api /repos/test-owner/test-repo/actions/secrets --jq .secrets[].name 67799610/001&#39; 67799610/001&#39; -nolocalimports -importcfg /tmp/go-build460661685/b397/importcfg -pack /tmp/go-build460661685/b397/_testmain.go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI added a commit that referenced this pull request Apr 10, 2026
- Add ContainerPin type and Get/Set/Delete methods to ActionCache
- Add GHAWManifestContainer type to safe_update_manifest
- Update NewGHAWManifest to accept container entries
- Update collectDockerImages to apply cached digest pins and populate WorkflowData
- Add mergeDockerImages and mergeDockerImagePins helper functions
- Add DockerImages and DockerImagePins fields to WorkflowData
- Embed container image list in compiled lock file headers
- Add UpdateContainerPins CLI function using docker buildx imagetools inspect
- Call UpdateContainerPins from update and upgrade commands
- Recompile all lock files to include container image sections

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@pelikhan pelikhan closed this Apr 10, 2026
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.

MCP container images pulled without SHA-256 digest pinning; node:lts-alpine uses floating LTS tag

3 participants