Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/aw/actions-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,11 @@
"digest": "sha256:9fec93937dc9d3e04f3954705c2c42f58976ebb8479b10778602631b5316e1e2",
"pinned_image": "ghcr.io/github/gh-aw-firewall/api-proxy:0.27.9@sha256:9fec93937dc9d3e04f3954705c2c42f58976ebb8479b10778602631b5316e1e2"
},
"ghcr.io/github/gh-aw-firewall/build-tools:0.27.26": {
"image": "ghcr.io/github/gh-aw-firewall/build-tools:0.27.26",
"digest": "sha256:5823f6cec65210cd6e3e6320c165979fb46f78c76600f58f4189d2c89c2be8da",
"pinned_image": "ghcr.io/github/gh-aw-firewall/build-tools:0.27.26@sha256:5823f6cec65210cd6e3e6320c165979fb46f78c76600f58f4189d2c89c2be8da"
},
"ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.28": {
"image": "ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.28",
"digest": "sha256:fdf310e4678ce58d248c466b89399e9680a3003038fd19322c388559016aaac7",
Expand Down
5 changes: 5 additions & 0 deletions pkg/actionpins/data/action_pins.json
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,11 @@
"digest": "sha256:9fec93937dc9d3e04f3954705c2c42f58976ebb8479b10778602631b5316e1e2",
"pinned_image": "ghcr.io/github/gh-aw-firewall/api-proxy:0.27.9@sha256:9fec93937dc9d3e04f3954705c2c42f58976ebb8479b10778602631b5316e1e2"
},
"ghcr.io/github/gh-aw-firewall/build-tools:0.27.26": {
"image": "ghcr.io/github/gh-aw-firewall/build-tools:0.27.26",
"digest": "sha256:5823f6cec65210cd6e3e6320c165979fb46f78c76600f58f4189d2c89c2be8da",
"pinned_image": "ghcr.io/github/gh-aw-firewall/build-tools:0.27.26@sha256:5823f6cec65210cd6e3e6320c165979fb46f78c76600f58f4189d2c89c2be8da"
},
"ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.28": {
"image": "ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.28",
"digest": "sha256:fdf310e4678ce58d248c466b89399e9680a3003038fd19322c388559016aaac7",
Expand Down
7 changes: 7 additions & 0 deletions pkg/workflow/awf_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,10 @@ func GetAWFCommandPrefix(workflowData *WorkflowData) string {
//
// <tag>,squid=sha256:...,agent=sha256:...,api-proxy=sha256:...,cli-proxy=sha256:...
//
// For arc-dind topology, build-tools is also included:
//
// <tag>,squid=sha256:...,agent=sha256:...,api-proxy=sha256:...,cli-proxy=sha256:...,build-tools=sha256:...
//
// This keeps AWF sidecar configuration aligned with digest-pinned pre-download images.
func buildAWFImageTagWithDigests(imageTag string, workflowData *WorkflowData) string {
if imageTag == "" {
Expand All @@ -807,6 +811,9 @@ func buildAWFImageTagWithDigests(imageTag string, workflowData *WorkflowData) st
{name: "api-proxy", image: constants.DefaultFirewallRegistry + "/api-proxy:" + imageTag},
{name: "cli-proxy", image: constants.DefaultFirewallRegistry + "/cli-proxy:" + imageTag},
}
if isArcDindTopology(workflowData) {
specs = append(specs, digestSpec{name: "build-tools", image: constants.DefaultFirewallRegistry + "/build-tools:" + imageTag})
}

parts := []string{imageTag}
for _, spec := range specs {
Expand Down
17 changes: 17 additions & 0 deletions pkg/workflow/awf_helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2047,6 +2047,23 @@ func TestBuildAWFImageTagWithDigests(t *testing.T) {
tag := buildAWFImageTagWithDigests("0.0.1", nil)
assert.Equal(t, "0.0.1", tag, "should not append digest metadata when no pins are available")
})

t.Run("includes build-tools digest for arc-dind topology", func(t *testing.T) {
imageTag := strings.TrimPrefix(string(constants.DefaultFirewallVersion), "v")
workflowData := &WorkflowData{
RunnerConfig: &RunnerConfig{Topology: RunnerTopologyArcDind},
}
tag := buildAWFImageTagWithDigests(imageTag, workflowData)

assert.Contains(t, tag, "build-tools=sha256:", "should include build-tools digest metadata for arc-dind topology")
})

t.Run("excludes build-tools digest without arc-dind topology", func(t *testing.T) {
imageTag := strings.TrimPrefix(string(constants.DefaultFirewallVersion), "v")
tag := buildAWFImageTagWithDigests(imageTag, nil)

assert.NotContains(t, tag, "build-tools=", "should not include build-tools digest metadata without arc-dind topology")
})
}

func TestBuildAWFArgs_ImageTagIncludesDigests(t *testing.T) {
Expand Down
5 changes: 5 additions & 0 deletions pkg/workflow/data/action_pins.json
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,11 @@
"digest": "sha256:9fec93937dc9d3e04f3954705c2c42f58976ebb8479b10778602631b5316e1e2",
"pinned_image": "ghcr.io/github/gh-aw-firewall/api-proxy:0.27.9@sha256:9fec93937dc9d3e04f3954705c2c42f58976ebb8479b10778602631b5316e1e2"
},
"ghcr.io/github/gh-aw-firewall/build-tools:0.27.26": {
"image": "ghcr.io/github/gh-aw-firewall/build-tools:0.27.26",
"digest": "sha256:5823f6cec65210cd6e3e6320c165979fb46f78c76600f58f4189d2c89c2be8da",
"pinned_image": "ghcr.io/github/gh-aw-firewall/build-tools:0.27.26@sha256:5823f6cec65210cd6e3e6320c165979fb46f78c76600f58f4189d2c89c2be8da"
},
"ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.28": {
"image": "ghcr.io/github/gh-aw-firewall/cli-proxy:0.25.28",
"digest": "sha256:fdf310e4678ce58d248c466b89399e9680a3003038fd19322c388559016aaac7",
Expand Down
59 changes: 59 additions & 0 deletions pkg/workflow/docker_firewall_pin_compile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,3 +174,62 @@ Test workflow.`
}
}
}

// TestCompileWorkflow_BuildToolsImagePinnedForArcDind is a regression test for
// gh-aw#44040: when runner.topology is arc-dind, the build-tools image must be
// digest-pinned in the compiled lock file the same way the other four gh-aw-firewall
// images (agent, api-proxy, cli-proxy, squid) are.
func TestCompileWorkflow_BuildToolsImagePinnedForArcDind(t *testing.T) {
// Strip the leading "v" to get the Docker image tag (mirrors getAWFImageTag).
imageTag := strings.TrimPrefix(string(constants.DefaultFirewallVersion), "v")

frontmatter := `---
on: workflow_dispatch
engine: claude
runner:
topology: arc-dind
network:
allowed:
- defaults
---

# Test
Test workflow.`

tmpDir := testutil.TempDir(t, "docker-firewall-pins-arc-dind-test")
testFile := filepath.Join(tmpDir, "test-workflow.md")
if err := os.WriteFile(testFile, []byte(frontmatter), 0644); err != nil {
t.Fatal(err)
}

compiler := NewCompiler()
if err := compiler.CompileWorkflow(testFile); err != nil {
t.Fatalf("Failed to compile workflow: %v", err)
}

lockFile := stringutil.MarkdownToLockFile(testFile)
yaml, err := os.ReadFile(lockFile)
if err != nil {
t.Fatalf("Failed to read lock file: %v", err)
}

yamlStr := string(yaml)

buildToolsImage := "ghcr.io/github/gh-aw-firewall/build-tools:" + imageTag
buildToolsDigest := "sha256:5823f6cec65210cd6e3e6320c165979fb46f78c76600f58f4189d2c89c2be8da"
pinnedBuildTools := buildToolsImage + "@" + buildToolsDigest

if !strings.Contains(yamlStr, `"image":"`+buildToolsImage+`","digest":"`+buildToolsDigest+`","pinned_image":"`+pinnedBuildTools+`"`) {
t.Errorf("Expected manifest header to include pinned metadata for %s", buildToolsImage)
}
if !strings.Contains(yamlStr, "# - "+pinnedBuildTools) {
t.Errorf("Expected pinned container comment for %s", buildToolsImage)
}
if !strings.Contains(yamlStr, pinnedBuildTools) {
t.Errorf("Expected pinned download reference for %s", buildToolsImage)
}

if !strings.Contains(yamlStr, `build-tools=`+buildToolsDigest) {
t.Errorf("Expected AWF config JSON to include build-tools=%s", buildToolsDigest)
}
}
2 changes: 2 additions & 0 deletions pkg/workflow/testdata/TestWasmGolden_AllEngines/claude.golden
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,8 @@ jobs:
env:
AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
run: |
# Best-effort permission fix for artifact upload (AWF cleanup may not have run)
sudo -n chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || true
# Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
if command -v awf &> /dev/null; then
awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
Expand Down
2 changes: 2 additions & 0 deletions pkg/workflow/testdata/TestWasmGolden_AllEngines/codex.golden
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,8 @@ jobs:
env:
AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
run: |
# Best-effort permission fix for artifact upload (AWF cleanup may not have run)
sudo -n chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || true
# Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
if command -v awf &> /dev/null; then
awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,8 @@ jobs:
env:
AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
run: |
# Best-effort permission fix for artifact upload (AWF cleanup may not have run)
sudo -n chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || true
# Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
if command -v awf &> /dev/null; then
awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
Expand Down
2 changes: 2 additions & 0 deletions pkg/workflow/testdata/TestWasmGolden_AllEngines/gemini.golden
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,8 @@ jobs:
env:
AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
run: |
# Best-effort permission fix for artifact upload (AWF cleanup may not have run)
sudo -n chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || true
# Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
if command -v awf &> /dev/null; then
awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
Expand Down
2 changes: 2 additions & 0 deletions pkg/workflow/testdata/TestWasmGolden_AllEngines/pi.golden
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,8 @@ jobs:
env:
AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
run: |
# Best-effort permission fix for artifact upload (AWF cleanup may not have run)
sudo -n chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || true
# Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
if command -v awf &> /dev/null; then
awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,8 @@ jobs:
env:
AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
run: |
# Best-effort permission fix for artifact upload (AWF cleanup may not have run)
sudo -n chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || true
# Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
if command -v awf &> /dev/null; then
awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,8 @@ jobs:
env:
AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
run: |
# Best-effort permission fix for artifact upload (AWF cleanup may not have run)
sudo -n chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || true
# Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
if command -v awf &> /dev/null; then
awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,8 @@ jobs:
env:
AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
run: |
# Best-effort permission fix for artifact upload (AWF cleanup may not have run)
sudo -n chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || true
# Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
if command -v awf &> /dev/null; then
awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,8 @@ jobs:
env:
AWF_LOGS_DIR: /tmp/gh-aw/sandbox/firewall/logs
run: |
# Best-effort permission fix for artifact upload (AWF cleanup may not have run)
sudo -n chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || chmod -R a+rX /tmp/gh-aw/sandbox/firewall 2>/dev/null || true
# Only run awf logs summary if awf command exists (it may not be installed if workflow failed before install step)
if command -v awf &> /dev/null; then
awf logs summary | tee -a "$GITHUB_STEP_SUMMARY"
Expand Down
Loading