From 9f00d9183a81b7a94863554551f2d550d682846a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Aug 2026 12:19:06 +0000 Subject: [PATCH 1/5] Initial plan From 1a17efae595a23e9ebc66975784c7f2f10e291f5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Aug 2026 12:24:56 +0000 Subject: [PATCH 2/5] Fix generatedyamlheredoc: recognize bare (( )) arithmetic Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/linters/generatedyamlheredoc/generatedyamlheredoc.go | 3 ++- .../testdata/src/generatedyamlheredoc/generatedyamlheredoc.go | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/linters/generatedyamlheredoc/generatedyamlheredoc.go b/pkg/linters/generatedyamlheredoc/generatedyamlheredoc.go index c6fd744cd77..61c1e0d98bc 100644 --- a/pkg/linters/generatedyamlheredoc/generatedyamlheredoc.go +++ b/pkg/linters/generatedyamlheredoc/generatedyamlheredoc.go @@ -86,7 +86,8 @@ func lineContainsShellHeredoc(line string) bool { line = line[afterIndex+1:] continue } - if strings.LastIndex(line[:operatorIndex], "$((") > strings.LastIndex(line[:operatorIndex], "))") { + lastOpen := max(strings.LastIndex(line[:operatorIndex], "$(("), strings.LastIndex(line[:operatorIndex], "((")) + if lastOpen > strings.LastIndex(line[:operatorIndex], "))") { line = line[afterIndex:] continue } diff --git a/pkg/linters/generatedyamlheredoc/testdata/src/generatedyamlheredoc/generatedyamlheredoc.go b/pkg/linters/generatedyamlheredoc/testdata/src/generatedyamlheredoc/generatedyamlheredoc.go index 6a5585cb56e..19baaefa881 100644 --- a/pkg/linters/generatedyamlheredoc/testdata/src/generatedyamlheredoc/generatedyamlheredoc.go +++ b/pkg/linters/generatedyamlheredoc/testdata/src/generatedyamlheredoc/generatedyamlheredoc.go @@ -11,6 +11,8 @@ func generatedWorkflowFragments() []string { "< Date: Wed, 19 Aug 2026 12:26:00 +0000 Subject: [PATCH 3/5] Simplify arithmetic guard per review feedback Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/linters/generatedyamlheredoc/generatedyamlheredoc.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/linters/generatedyamlheredoc/generatedyamlheredoc.go b/pkg/linters/generatedyamlheredoc/generatedyamlheredoc.go index 61c1e0d98bc..4b167e21a75 100644 --- a/pkg/linters/generatedyamlheredoc/generatedyamlheredoc.go +++ b/pkg/linters/generatedyamlheredoc/generatedyamlheredoc.go @@ -86,8 +86,8 @@ func lineContainsShellHeredoc(line string) bool { line = line[afterIndex+1:] continue } - lastOpen := max(strings.LastIndex(line[:operatorIndex], "$(("), strings.LastIndex(line[:operatorIndex], "((")) - if lastOpen > strings.LastIndex(line[:operatorIndex], "))") { + // "$((" is also matched here, since it contains "((" as a suffix. + if strings.LastIndex(line[:operatorIndex], "((") > strings.LastIndex(line[:operatorIndex], "))") { line = line[afterIndex:] continue } From 80a38f4059a6642ac4c60c28136dd8fc58120b30 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 19 Aug 2026 17:05:09 +0000 Subject: [PATCH 4/5] Fix quoted arithmetic heredoc detection Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- .../generatedyamlheredoc.go | 52 ++++++++++++++++++- .../generatedyamlheredoc.go | 1 + 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/pkg/linters/generatedyamlheredoc/generatedyamlheredoc.go b/pkg/linters/generatedyamlheredoc/generatedyamlheredoc.go index 4b167e21a75..6d6f9cb00d3 100644 --- a/pkg/linters/generatedyamlheredoc/generatedyamlheredoc.go +++ b/pkg/linters/generatedyamlheredoc/generatedyamlheredoc.go @@ -86,8 +86,7 @@ func lineContainsShellHeredoc(line string) bool { line = line[afterIndex+1:] continue } - // "$((" is also matched here, since it contains "((" as a suffix. - if strings.LastIndex(line[:operatorIndex], "((") > strings.LastIndex(line[:operatorIndex], "))") { + if hasOpenShellArithmeticExpression(line[:operatorIndex]) { line = line[afterIndex:] continue } @@ -103,6 +102,55 @@ func lineContainsShellHeredoc(line string) bool { } } +func hasOpenShellArithmeticExpression(line string) bool { + arithmeticDepth := 0 + inSingleQuote := false + inDoubleQuote := false + + for index := 0; index < len(line); index++ { + switch line[index] { + case '\\': + if !inSingleQuote { + index++ + } + case '\'': + if !inDoubleQuote { + inSingleQuote = !inSingleQuote + } + case '"': + if !inSingleQuote { + inDoubleQuote = !inDoubleQuote + } + case '(': + if !inSingleQuote && index+1 < len(line) && line[index+1] == '(' && + ((index > 0 && line[index-1] == '$') || (!inDoubleQuote && isShellTokenBoundary(line, index))) { + arithmeticDepth++ + index++ + } + case ')': + if !inSingleQuote && arithmeticDepth > 0 && index+1 < len(line) && line[index+1] == ')' { + arithmeticDepth-- + index++ + } + } + } + + return arithmeticDepth > 0 +} + +func isShellTokenBoundary(line string, index int) bool { + if index == 0 { + return true + } + + switch line[index-1] { + case ' ', '\t', ';', '&', '|', '(': + return true + default: + return false + } +} + func isShellWordByte(value byte) bool { return value == '_' || value >= 'a' && value <= 'z' || diff --git a/pkg/linters/generatedyamlheredoc/testdata/src/generatedyamlheredoc/generatedyamlheredoc.go b/pkg/linters/generatedyamlheredoc/testdata/src/generatedyamlheredoc/generatedyamlheredoc.go index 19baaefa881..903882f8251 100644 --- a/pkg/linters/generatedyamlheredoc/testdata/src/generatedyamlheredoc/generatedyamlheredoc.go +++ b/pkg/linters/generatedyamlheredoc/testdata/src/generatedyamlheredoc/generatedyamlheredoc.go @@ -13,6 +13,7 @@ func generatedWorkflowFragments() []string { "echo $((1 << 2))\n", "(( count << 1 ))\n", "if (( a << 2 )); then\n", + "printf '%s\n' '((' && cat < Date: Thu, 20 Aug 2026 02:07:14 +0000 Subject: [PATCH 5/5] Plan CI failure investigation Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- .github/skills/agentic-workflows/SKILL.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/skills/agentic-workflows/SKILL.md b/.github/skills/agentic-workflows/SKILL.md index d0c9af823a8..3af44da06f2 100644 --- a/.github/skills/agentic-workflows/SKILL.md +++ b/.github/skills/agentic-workflows/SKILL.md @@ -41,6 +41,7 @@ Load these files from `github/gh-aw` (they are not available locally). - `.github/aw/github-mcp-server-pagination.md` - `.github/aw/github-mcp-server.md` - `.github/aw/instructions.md` +- `.github/aw/jobs.md` - `.github/aw/linter-workflows.md` - `.github/aw/llms.md` - `.github/aw/loop.md`