Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Fix local scanner version detection and test isolation
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
  • Loading branch information
Copilot and gh-aw-bot authored Oct 8, 2026
commit 6270c641a4cdb05128a4302dd66cb93068d9d177
2 changes: 1 addition & 1 deletion docs/src/content/docs/setup/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ gh aw compile --dependabot # Generate dependency manifests
gh aw compile --purge # Remove orphaned .lock.yml files
```

For `--zizmor` and `--poutine`, compilation automatically uses a binary on `PATH` when its `--version` is at least 1.30.1 or 1.1.6, respectively. If the binary is missing, too old, or its version cannot be determined, the scanner uses the pinned Docker image instead. Other Docker-based checks still require Docker.
For `--zizmor` and `--poutine`, compilation automatically uses a binary on `PATH` when its version is at least 1.30.1 or 1.1.6, respectively. The version is checked with `zizmor --version` or `poutine version --disable-version-check`. If the binary is missing, too old, or its version cannot be determined, the scanner uses the pinned Docker image instead. Other Docker-based checks still require Docker.

If the repository root contains an [`aw.yml` manifest](/gh-aw/reference/aw-yml-package-manifest/), `gh aw compile` validates it before compiling workflows.

Expand Down
13 changes: 13 additions & 0 deletions pkg/cli/docker_images_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import (
"time"
)

func useDockerFallback(t *testing.T) {
t.Helper()
t.Setenv("PATH", t.TempDir())
}

func TestCheckAndPrepareDockerImages_NoToolsRequested(t *testing.T) {
// Reset state before test
ResetDockerPullState()
Expand All @@ -22,6 +27,7 @@ func TestCheckAndPrepareDockerImages_NoToolsRequested(t *testing.T) {
}

func TestCheckAndPrepareDockerImages_ImageAlreadyDownloading(t *testing.T) {
useDockerFallback(t)
// Reset state before test
ResetDockerPullState()

Expand Down Expand Up @@ -138,6 +144,7 @@ func TestDockerImageConstants(t *testing.T) {
}

func TestCheckAndPrepareDockerImages_MultipleImages(t *testing.T) {
useDockerFallback(t)
// Reset state before test
ResetDockerPullState()

Expand Down Expand Up @@ -169,6 +176,7 @@ func TestCheckAndPrepareDockerImages_MultipleImages(t *testing.T) {
}

func TestCheckAndPrepareDockerImages_RetryMessageFormat(t *testing.T) {
useDockerFallback(t)
// Reset state before test
ResetDockerPullState()

Expand Down Expand Up @@ -203,6 +211,7 @@ func TestCheckAndPrepareDockerImages_RetryMessageFormat(t *testing.T) {
}

func TestCheckAndPrepareDockerImages_StartedDownloadingMessage(t *testing.T) {
useDockerFallback(t)
// Reset state before test
ResetDockerPullState()

Expand All @@ -229,6 +238,7 @@ func TestCheckAndPrepareDockerImages_StartedDownloadingMessage(t *testing.T) {
}

func TestCheckAndPrepareDockerImages_ImageAlreadyAvailable(t *testing.T) {
useDockerFallback(t)
// Reset state before test
ResetDockerPullState()

Expand Down Expand Up @@ -618,6 +628,7 @@ func TestStartDockerImageDownload_NilContext(t *testing.T) {
}

func TestCheckAndPrepareDockerImages_DockerUnavailable(t *testing.T) {
useDockerFallback(t)
// Reset state before test
ResetDockerPullState()

Expand Down Expand Up @@ -656,6 +667,7 @@ func TestCheckAndPrepareDockerImages_DockerUnavailable(t *testing.T) {
}

func TestCheckAndPrepareDockerImages_DockerUnavailable_MultipleTools(t *testing.T) {
useDockerFallback(t)
// Reset state before test
ResetDockerPullState()

Expand Down Expand Up @@ -751,6 +763,7 @@ func TestCheckAndPrepareDockerImages_DockerUnavailable_ReturnsTypedError(t *test
}

func TestCheckAndPrepareDockerImages_RunnerGuardImageDownloading(t *testing.T) {
useDockerFallback(t)
// Reset state before test
ResetDockerPullState()

Expand Down
6 changes: 5 additions & 1 deletion pkg/cli/scanner_local.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ func localScannerPath(ctx context.Context, name string) string {
}
versionCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
output, err := exec.CommandContext(versionCtx, path, "--version").CombinedOutput()
versionArgs := []string{"--version"}
if name == "poutine" {
versionArgs = []string{"version", "--disable-version-check"}
}
output, err := exec.CommandContext(versionCtx, path, versionArgs...).CombinedOutput()
if err != nil {
return ""
}
Expand Down
17 changes: 15 additions & 2 deletions pkg/cli/scanner_local_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,20 @@ import (
func installTestScanner(t *testing.T, dir, name, version string) string {
t.Helper()
path := filepath.Join(dir, name)
if err := os.WriteFile(path, []byte("#!/bin/sh\necho '"+version+"'\n"), 0o755); err != nil {
script := "#!/bin/sh\n" +
"case \"${0##*/}\" in\n" +
" zizmor) [ \"$#\" -eq 1 ] && [ \"$1\" = \"--version\" ] || exit 2 ;;\n" +
" poutine) [ \"$#\" -eq 2 ] && [ \"$1\" = \"version\" ] && [ \"$2\" = \"--disable-version-check\" ] || exit 2 ;;\n" +
"esac\n" +
"printf '%s\\n' '" + version + "'\n"
if err := os.WriteFile(path, []byte(script), 0o755); err != nil {
t.Fatal(err)
}
return path
resolvedPath, err := filepath.EvalSymlinks(path)
if err != nil {
t.Fatal(err)
}
return resolvedPath
}

func TestLocalScannerPathVersionSelection(t *testing.T) {
Expand Down Expand Up @@ -88,7 +98,10 @@ func TestLocalScannerCommandsAndDockerFallback(t *testing.T) {
if err := os.Remove(poutine); err != nil {
t.Fatal(err)
}
path := os.Getenv("PATH")
t.Setenv("PATH", dir)
cmd, args, err = buildPoutineCommand(root)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The fallback assertion now temporarily restricts PATH to the fixture directory, then restores the original PATH before the test continues. Commit: 6270c641.

t.Setenv("PATH", path)
if err != nil || cmd.Path != docker || cmd.Dir != root || !strings.Contains(strings.Join(args, " "), PoutineImage) {
t.Fatalf("docker poutine command: %v, %v, %v", cmd, args, err)
}
Expand Down
Loading