Skip to content

Reduce actionlint SC2086 noise in generated AWF run scripts#40620

Merged
pelikhan merged 4 commits into
mainfrom
copilot/static-analysis-report-2026-06-21
Jun 21, 2026
Merged

Reduce actionlint SC2086 noise in generated AWF run scripts#40620
pelikhan merged 4 commits into
mainfrom
copilot/static-analysis-report-2026-06-21

Conversation

Copilot AI commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Daily static-analysis reported SC2086 as the dominant actionlint finding, concentrated in generated .lock.yml run: blocks. The issue came from intentional shell argument expansion in the AWF invocation path, which shellcheck flags when not explicitly scoped.

  • Scope of fix (generator-level)

    • Updated AWF command templates in pkg/workflow/awf_helpers.go to use scoped suppression where word-splitting is intentional:
      • # shellcheck disable=SC1003# shellcheck disable=SC1003,SC2086
    • Applied consistently across all AWF command assembly branches so the change propagates to compiled workflows.
  • Coverage for behavior contract

    • Extended TestBuildAWFCommand_AddsToolCacheMountProbe in pkg/workflow/awf_config_test.go to assert the scoped suppression marker is present in generated command content.
  • Generated artifacts updated

    • Recompiled workflow lock files and refreshed affected wasm golden outputs to align with generator output.
# shellcheck disable=SC1003,SC2086
sudo -E awf ... ${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"} \
  ${GH_AW_DOCKER_HOST:+--docker-host "$GH_AW_DOCKER_HOST"} \
  ${GH_AW_DOCKER_HOST_PATH_PREFIX_ARGS} -- ...

… workflows

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Update static analysis report for 2026-06-21 Reduce actionlint SC2086 noise in generated AWF run scripts Jun 21, 2026
Copilot AI requested a review from pelikhan June 21, 2026 13:53
@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot include extensive documentation on why these warnings are disabled in the compiler go code that introduces them.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Jun 21, 2026

Copy link
Copy Markdown
Contributor Author

@copilot include extensive documentation on why these warnings are disabled in the compiler go code that introduces them.

Updated in f7e3ad5. I added extensive inline documentation in pkg/workflow/awf_helpers.go explaining exactly why SC1003 and SC2086 are intentionally scoped to the generated AWF invocation line, which expansions are expected, and why the remaining arguments stay safely quoted.

@pelikhan pelikhan marked this pull request as ready for review June 21, 2026 14:50
Copilot AI review requested due to automatic review settings June 21, 2026 14:50
@github-actions

github-actions Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

@github-actions

github-actions Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

@github-actions

github-actions Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

⚠️ PR Code Quality Reviewer failed during code quality review.

@github-actions

github-actions Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

No ADR enforcement needed: PR #40620 does not have the 'implementation' label and has only 31 new lines of code in business logic directories (≤100 threshold).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR reduces ShellCheck SC2086 warnings reported by actionlint in generated workflow run: blocks by adding a scoped ShellCheck suppression directive to the generated AWF invocation line, where intentional word-splitting/argument expansion is required for templated arguments.

Changes:

  • Update AWF command generation to emit # shellcheck disable=SC1003,SC2086 immediately before the AWF invocation line in all command-assembly branches.
  • Extend TestBuildAWFCommand_AddsToolCacheMountProbe to assert the new suppression marker is present.
  • Regenerate affected compiled workflow lock files and wasm golden outputs to match the new generator output.
Show a summary per file
File Description
pkg/workflow/awf_helpers.go Emits a combined ShellCheck suppression directive (SC1003, SC2086) directly before the generated AWF invocation line.
pkg/workflow/awf_config_test.go Adds an assertion ensuring the new ShellCheck suppression directive is included in generated AWF command output.
pkg/workflow/testdata/TestWasmGolden_CompileFixtures/with-imports.golden Updates golden output to reflect the new combined ShellCheck suppression directive.
pkg/workflow/testdata/TestWasmGolden_CompileFixtures/smoke-copilot.golden Updates golden output to reflect the new combined ShellCheck suppression directive.
pkg/workflow/testdata/TestWasmGolden_CompileFixtures/playwright-cli-mode.golden Updates golden output to reflect the new combined ShellCheck suppression directive.
pkg/workflow/testdata/TestWasmGolden_CompileFixtures/basic-copilot.golden Updates golden output to reflect the new combined ShellCheck suppression directive.
pkg/workflow/testdata/TestWasmGolden_AllEngines/pi.golden Updates golden output to reflect the new combined ShellCheck suppression directive.
pkg/workflow/testdata/TestWasmGolden_AllEngines/gemini.golden Updates golden output to reflect the new combined ShellCheck suppression directive.
pkg/workflow/testdata/TestWasmGolden_AllEngines/copilot.golden Updates golden output to reflect the new combined ShellCheck suppression directive.
pkg/workflow/testdata/TestWasmGolden_AllEngines/codex.golden Updates golden output to reflect the new combined ShellCheck suppression directive.
pkg/workflow/testdata/TestWasmGolden_AllEngines/claude.golden Updates golden output to reflect the new combined ShellCheck suppression directive.
.github/workflows/workflow-normalizer.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/video-analyzer.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/update-astro.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/unbloat-docs.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/test-workflow.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/test-project-url-default.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/test-dispatcher.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/spec-enforcer.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-workflow-call.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-workflow-call-with-inputs.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-update-cross-repo-pr.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-test-tools.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-temporary-id.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-service-ports.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-project.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-pi.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-otel-backends.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-opencode.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-multi-pr.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-gemini.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-crush.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-create-cross-repo-pr.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-copilot.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-copilot-sdk.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-copilot-arm.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-copilot-aoai-entra.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-copilot-aoai-apikey.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-codex.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-ci.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-call-workflow.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/smoke-antigravity.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/security-review.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/schema-consistency-checker.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/research.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/repo-tree-map.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/release.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/poem-bot.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/pdf-summary.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/notion-issue-summary.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/lint-monster.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/issue-monster.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/hippo-embed.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/github-remote-mcp-auth-test.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/firewall.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/example-permissions-warning.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/example-failure-category-filter.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/docs-noob-tester.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/daily-testify-uber-super-expert.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/daily-team-status.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/daily-news.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/daily-multi-device-docs-tester.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/daily-max-ai-credits-test.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/daily-malicious-code-scan.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/daily-hippo-learn.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/daily-function-namer.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/daily-doc-updater.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/daily-credit-limit-test.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/daily-cli-tools-tester.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/daily-byok-ollama-test.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/daily-awf-spec-compiler-surfacing.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/daily-architecture-diagram.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/daily-ambient-context-optimizer.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/daily-agent-of-the-day-blog-writer.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/commit-changes-analyzer.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/codex-github-remote-mcp-test.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/chaos-pr-bundle-fuzzer.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/changeset.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/brave.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/bot-detection.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/auto-triage-issues.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/ai-moderator.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/agentic-token-optimizer.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/agent-persona-explorer.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/ace-editor.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.
.github/workflows/ab-testing-advisor.lock.yml Regenerated lock output with the new combined ShellCheck suppression directive.

Copilot's findings

Tip

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

  • Files reviewed: 227/260 changed files
  • Comments generated: 0

@github-actions github-actions Bot mentioned this pull request Jun 21, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🧪 Test Quality Sentinel Report

⚠️ Test Quality Score: 70/100 — Acceptable

Analyzed 1 test (1 modified): 1 design, 0 implementation, 0 guideline violations.

📊 Metrics & Test Classification (1 test analyzed)
Metric Value
New/modified tests analyzed 1
✅ Design tests (behavioral contracts) 1 (100%)
⚠️ Implementation tests (low value) 0 (0%)
Tests with error/edge cases 0 (0%)
Duplicate test clusters 0
Test inflation detected No (1 test line added vs 21 production lines; ratio ≈ 0.05:1)
🚨 Coding-guideline violations 0
Test File Classification Issues Detected
TestBuildAWFCommand_AddsToolCacheMountProbe pkg/workflow/awf_config_test.go:1378 ✅ Design No error/edge cases

Go: 1 (*_test.go); JavaScript: 0 (*.test.cjs, *.test.js). Other languages detected but not scored.

Verdict

Check passed. 0% implementation tests (threshold: 30%). The single added assertion verifies the observable output of the command generator — that # shellcheck disable=SC1003,SC2086 appears in the generated shell command — which is the behavioral contract this PR introduces. No error path coverage was added (−30 pts), but for a focused, single-directive change that is acceptable.

References:

🧪 Test quality analysis by Test Quality Sentinel · 83.3 AIC · ⊞ 8.3K ·

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ Test Quality Sentinel: 70/100. Test quality is acceptable — 0% of new tests are implementation tests (threshold: 30%).

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Skills-Based Review 🧠

Applied /tdd and /zoom-out — approving with two minor suggestions (test breadth and constant scoping).

📋 Key Themes & Highlights

Key Themes

  • Test branch coverage: The new shellcheck assertion verifies only the configFileSetup-only branch. The remaining three branches all use the same shellcheckDirective variable so they're safe today, but a future fifth branch would lack a guard. See the inline comment on awf_config_test.go:1378.
  • Constant scoping: shellcheckDirective as a local var is fine; a package-level const would improve discoverability and allow tests to reference it symbolically. See awf_helpers.go:399.

Positive Highlights

  • Generator-level fix is exactly the right approach — 258 lock files update mechanically with zero behavioral change
  • Excellent rationale comment precisely documents the security reasoning: trusted compiler-owned fragments vs user-provided shell input
  • DRY extraction of shellcheckDirective from four identical format-string literals eliminates split-brain risk on future directive updates
  • Regression guard added — the contract that the directive appears in generated output is now tested

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · 93.1 AIC · ⌖ 9.66 AIC · ⊞ 6.9K

Comment thread pkg/workflow/awf_config_test.go Outdated
@@ -1375,6 +1375,7 @@ func TestBuildAWFCommand_AddsToolCacheMountProbe(t *testing.T) {
assert.NotContains(t, command, `/home/runner/work/_tool`, "should not assume a self-hosted runner tool-cache path")
assert.NotContains(t, command, `:-/opt/hostedtoolcache`, "should not fall back to /opt/hostedtoolcache")
assert.Contains(t, command, `${GH_AW_TOOL_CACHE_MOUNT:+--mount "$GH_AW_TOOL_CACHE_MOUNT"}`, "should inject tool-cache mount args into awf invocation")
assert.Contains(t, command, "# shellcheck disable=SC1003,SC2086", "should suppress intentional argument splitting in awf invocation")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[/tdd] The assertion covers only one of the four BuildAWFCommand branches (the configFileSetup-only path). All four branches use the same shellcheckDirective variable today, so correctness is safe — but a future developer adding a fifth branch and forgetting the directive would slip past undetected.

💡 Suggested coverage extension

Consider adding the assertion to TestBuildAWFCommand_ConfigFileWithPathSetup (branch 1: PathSetup + configFileSetup) and to TestBuildAWFCommand_WritesAgentCLIStartTimestamp (already table-driven, covers two variants). Alternatively, a focused parameterized test:

func TestBuildAWFCommand_ContainsShellcheckDirective(t *testing.T) {
    // exercise all four if/else branches in BuildAWFCommand
    configs := []struct {
        name string
        cfg  AWFCommandConfig
    }{
        {"PathSetup+configFileSetup", ...},
        {"PathSetup only",           ...},
        {"configFileSetup only",     ...},
        {"neither",                  ...},
    }
    for _, tc := range configs {
        t.Run(tc.name, func(t *testing.T) {
            assert.Contains(t, BuildAWFCommand(tc.cfg), "# shellcheck disable=SC1003,SC2086")
        })
    }
}

This makes the suppression contract explicit across every generation path.

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.

Addressed in 5b3217e. I added directive assertions in additional tests (TestBuildAWFCommand_ConfigFileWithPathSetup and TestBuildAWFCommand_WritesAgentCLIStartTimestamp) so this contract is now checked beyond the original single test path.

Comment thread pkg/workflow/awf_helpers.go Outdated
//
// We keep normal quoting for all user-controlled values via shellEscapeArg/shellJoinArgs
// and scope this suppression to the generated AWF invocation line only.
shellcheckDirective := "# shellcheck disable=SC1003,SC2086"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[/zoom-out] Extracting shellcheckDirective from four identical string literals in the format templates into a single named variable is a clean DRY win — great call. One small follow-up: because this is currently a local var, tests must duplicate the string literal to assert against it (as in awf_config_test.go:1378). Promoting it to a package-level unexported constant would let tests reference it symbolically and would make this suppression easier to find when auditing all shellcheck directives in the package.

💡 Package-level const example
// awfShellcheckDirective suppresses SC1003 (GitHub expression literals with single
// quotes) and SC2086 (intentional unquoted expansion of compiler-owned AWF argument
// fragments). It is scoped to the generated AWF invocation line only.
const awfShellcheckDirective = "# shellcheck disable=SC1003,SC2086"

Tests could then use the exported or unexported constant instead of the raw string, making the coupling explicit.

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.

Addressed in 5b3217e. The suppression marker is now a package-level constant (awfShellcheckDirective) in pkg/workflow/awf_helpers.go, and tests now reference that constant instead of duplicating the literal.

@pelikhan

Copy link
Copy Markdown
Collaborator

@copilot Run pr-finisher skill

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Jun 21, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Run pr-finisher skill

Ran pr-finisher and completed the actionable in-scope review follow-ups in 5b3217e. Local validation passed (make fmt, make lint, make test-unit, make test, make recompile, and make agent-report-progress). CI on this new head still needs a maintainer re-trigger.

@pelikhan pelikhan merged commit 6be5b76 into main Jun 21, 2026
29 checks passed
@pelikhan pelikhan deleted the copilot/static-analysis-report-2026-06-21 branch June 21, 2026 15:56
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.

3 participants