Skip to content

Import and merge on.bots from shared workflows - #57968

Merged
pelikhan merged 9 commits into
mainfrom
copilot/import-merge-on-bots-field
Sep 2, 2026
Merged

Import and merge on.bots from shared workflows#57968
pelikhan merged 9 commits into
mainfrom
copilot/import-merge-on-bots-field

Conversation

Copilot AI commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Shared workflows could not contribute on.bots allowlists because imports incorrectly read bots from the top level.

Changes

  • Read bot allowlists from the supported on.bots path.
  • Union imported bots with the importing workflow’s bots while preserving order and deduplicating entries.
  • Update regression coverage for imported-only, combined, and overlapping allowlists.
# Shared workflow
on:
  bots:
    - renovate[bot]

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

pelikhan commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

@copilot investigate the top level bots. If it is a legacy field, mark as error and ensure codemod upgrades to on.bot

Copilot AI and others added 2 commits September 2, 2026 15:17
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

@copilot investigate the top level bots. If it is a legacy field, mark as error and ensure codemod upgrades to on.bot

Addressed in 8678746 and 1ed23d7. Top-level bots is explicitly covered as a schema error, and gh aw fix now migrates it to on.bots, merging and deduplicating values when on.bots already exists.

@pelikhan
pelikhan marked this pull request as ready for review September 2, 2026 16:10
Copilot AI balanced review requested due to automatic review settings September 2, 2026 16:10
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check. See the comment below for the result and any generated ADR draft.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • proxy.golang.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "proxy.golang.org"

See Network Configuration for more information.

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

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

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • proxy.golang.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "proxy.golang.org"

See Network Configuration for more information.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

⚠️ Security scanning failed for Ponytail Reviewer. Review the logs for details.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • ab.chatgpt.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "ab.chatgpt.com"

See Network Configuration for more information.

Generated by Ponytail Reviewer for #57968

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel skipped because pre-fetch PR data was unavailable: unable to fetch test file diff

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

Warning

Firewall blocked 4 domains

The following domains were blocked by the firewall during workflow execution:

  • api.github.com
  • github.com
  • raw.githubusercontent.com
  • registry.npmjs.org

[!TIP]
api.github.com is blocked because GitHub API access uses the built-in GitHub tools by default. Instead of adding api.github.com to network.allowed, use tools.github.mode: gh-proxy for direct pre-authenticated GitHub CLI access without requiring network access to api.github.com:

tools:
  github:
    mode: gh-proxy

See GitHub Tools for more information on gh-proxy mode.

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "api.github.com"
    - "github.com"
    - "raw.githubusercontent.com"
    - "registry.npmjs.org"

See Network Configuration for more information.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

ADR Required

I generated a draft ADR for this PR because ADR enforcement applies here: the PR adds more than 100 lines in business-logic directories (pkg/), and no existing ADR with the required Michael Nygard sections was found in the PR body or docs/adr/ on this branch.

Evidence reviewed

  • PR title: Import and merge on.bots from shared workflows
  • PR description: shared workflows were incorrectly contributing bot allowlists from top-level bots instead of the supported on.bots path
  • Diff/files: changes in pkg/parser/import_field_extractor.go, pkg/cli/codemod_bots.go, pkg/workflow/bots_test.go, and related tests/schema coverage
  • Existing ADRs on branch: latest ADRs stop at docs/adr/57860-guard-linter-autofixes-against-comment-loss.md

Draft ADR added

  • docs/adr/57968-import-bot-allowlists-from-on-bots.md

Next action

Please review and refine the draft ADR so it accurately captures the intended long-term design, then keep it with the PR as the architectural record for this change.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • proxy.golang.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "proxy.golang.org"

See Network Configuration for more information.

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · pi · gpt54 · 13.1 AIC · ⌖ 13.1 AIC · ⊞ 9.8K ·
Comment /review to run again

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.

🟡 Changes recommended

The codemod can select nested fields, corrupt lists containing blank lines, and discard comments.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Corrects imported bot allowlists and updates legacy migration behavior.

Changes:

  • Extract and merge imported on.bots values.
  • Reject legacy top-level bots.
  • Extend regression and codemod coverage.
File summaries
File Description
pkg/parser/import_field_extractor.go Reads imported bots from on.
pkg/parser/schema_test.go Tests top-level bots rejection.
pkg/workflow/bots_test.go Covers imported bot merging.
pkg/cli/codemod_bots.go Merges legacy and current bot lists.
pkg/cli/codemod_bots_test.go Tests codemod merging.
Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 3
  • Review effort level: Balanced

Comment thread pkg/cli/codemod_bots.go Outdated
for i := start; i < end; i++ {
line := lines[i]
lineIndent := len(getIndentation(line))
if (!nested && lineIndent != indent) || (nested && lineIndent <= indent) || !strings.HasPrefix(strings.TrimSpace(line), "bots:") {
Comment thread pkg/cli/codemod_bots.go Outdated
continue
}
blockEnd := i
for j := i + 1; j < end && isNestedUnder(lines[j], getIndentation(line)); j++ {
Comment thread pkg/cli/codemod_bots.go
Comment on lines +99 to +100
if (i >= topBotsStart && i <= topBotsEnd) || (i >= onBotsStart && i <= onBotsEnd) {
continue

@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.

A couple of spots are doing more parsing and setup than the surrounding code needs; trimming them would simplify the patch without changing behavior. net: -36 lines possible.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • ab.chatgpt.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "ab.chatgpt.com"

See Network Configuration for more information.

Generated by ✂️ Ponytail Reviewer for #57968 · codex · mai10 · 8.79 AIC · ⌖ 0.589 AIC · ⊞ 12.8K
Comment /ponytail to run again

Comment thread pkg/cli/codemod_bots.go
return merged, true
}

func mergeLegacyBotsLines(lines []string, bots []string) ([]string, bool) {

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.

pkg/cli/codemod_bots.go:67-124: yagni: 60-line custom YAML block finder/rewriter for a single merge. The existing plus a tiny post-transform would avoid introducing a second parser and JSON serialization path.

Comment thread pkg/cli/codemod_bots.go
return merged, true
}

func mergeLegacyBotsLines(lines []string, bots []string) ([]string, bool) {

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.

pkg/cli/codemod_bots.go:67-124: yagni: 60-line custom YAML block finder/rewriter for a single bots merge. The existing newMoveTopLevelKeyToOnBlockCodemod plus a tiny post-transform would avoid introducing a second parser and JSON serialization path.

Comment thread pkg/workflow/bots_test.go
compiler := NewCompiler()

t.Run("imported_bots_merged_with_top_level_bots", func(t *testing.T) {
t.Run("imported_bots_merged_with_main_workflow_bots", func(t *testing.T) {

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.

pkg/workflow/bots_test.go:333-455: shrink: three subtests repeat the same tempdir/file-writing scaffolding. A single table-driven case with a tiny helper would remove most of the boilerplate.

@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 — this is a well-scoped, well-tested bug fix (union merge for on.bots from imports, plus a codemod for legacy top-level bots merging into an existing on.bots). Reused existing helpers (extractOnSectionFieldFromMap, mergeUniqueLogged) consistent with the skip-roles/skip-bots patterns already in the codebase — good architectural consistency per /codebase-design.

📋 Key Themes & Highlights

Key Themes

  • mergeLegacyBots in codemod_bots.go assumes both on.bots and top-level bots are []any; a scalar string value for either (if still schema-permitted) causes a silent no-op rather than a successful migration or explicit error.
  • Line-splicing logic in mergeLegacyBotsLines is only exercised by one scenario (bots: as the last key in on:); an additional case with bots: first under on: plus trailing sibling keys would harden confidence in the block-removal logic.

Positive Highlights

  • ✅ Fixing mergeBots to source from on.bots mirrors the established skip-roles/skip-bots merge pattern exactly — no new abstractions introduced.
  • ✅ New/updated tests (TestBotsToOnBotsCodemod_MergesWhenOnBotsExists, TestBotsImportMerge variants) clearly assert the new merged/deduped behavior.
  • ✅ Schema test addition (bots now rejected at top level) closes the gap the bug depended on.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • proxy.golang.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "proxy.golang.org"

See Network Configuration for more information.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · copilot · sonnet50 · 54.4 AIC · ⌖ 15.8 AIC · ⊞ 10.3K
Comment /matt to run again

Comment thread pkg/cli/codemod_bots.go
return baseApply(content, frontmatter)
}

mergedBots, ok := mergeLegacyBots(onBots, topBots)

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] mergeLegacyBots only handles []any bot lists; if either on.bots or top-level bots is a bare scalar string (which the schema likely still permits for single-bot shorthand), it returns ok=false and the codemod silently no-ops, leaving the legacy top-level bots field unmigrated with no error surfaced to the user.

💡 Suggested coverage

Add a case in TestBotsToOnBotsCodemod_* where on.bots or top-level bots is a scalar string (e.g. bots: renovate[bot]) to confirm the intended fallback behavior, and consider normalizing scalars to a single-element list before merging so the migration still succeeds instead of silently skipping.

@copilot please address this.

Comment thread pkg/cli/codemod_bots.go
return merged, true
}

func mergeLegacyBotsLines(lines []string, bots []string) ([]string, bool) {

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] mergeLegacyBotsLines covers the case where on: contains other keys before/after bots:, but there is no test for bots: being the first key under on: (i.e. onBotsStart == onStart+1) combined with additional sibling keys after it in on: — worth a regression test since the block-removal/reinsertion logic (topBotsStart/topBotsEnd vs onBotsStart/onBotsEnd splicing) is easy to get subtly wrong with multi-line array removal.

💡 Suggested test
content := `---
on:
  bots:
    - dependabot
  issues:
    types: [opened]
bots:
  - renovate
---
`

Verify the merged bots: line lands correctly under on: and issues: is preserved untouched.

@copilot please address this.

@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.

Reviewed the on.bots merge fix. The parser change correctly switches to extractOnSectionFieldFromMap (consistent with the existing pattern used for skip-roles/skip-bots), and the codemod now properly merges legacy top-level bots into on.bots instead of silently dropping it. The merge/line-transform helpers (mergeLegacyBots, mergeLegacyBotsLines, findBotsBlock) are type-safe and fail closed (return unmodified) on unexpected shapes. Good regression coverage for imported-only, combined, and overlapping allowlist scenarios, plus the schema test addition for rejecting top-level bots. No blocking issues found.

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • proxy.golang.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "proxy.golang.org"

See Network Configuration for more information.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · copilot · sonnet50 · 40.7 AIC · ⌖ 13.3 AIC · ⊞ 8.3K

@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-09-02T16:15:31.341+00:00
review_event: REQUEST_CHANGES
top_themes:
  - importer dropped legacy top-level bots compatibility
  - imported expression bots regress to author_association gating
files_reviewed:
  - pkg/cli/codemod_bots.go
  - pkg/cli/codemod_bots_test.go
  - pkg/parser/import_field_extractor.go
  - pkg/parser/schema_test.go
  - pkg/workflow/bots_test.go
  - pkg/workflow/role_checks_test.go
comment_count: 1

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

Warning

Firewall blocked 4 domains

The following domains were blocked by the firewall during workflow execution:

  • api.github.com
  • github.com
  • raw.githubusercontent.com
  • registry.npmjs.org

[!TIP]
api.github.com is blocked because GitHub API access uses the built-in GitHub tools by default. Instead of adding api.github.com to network.allowed, use tools.github.mode: gh-proxy for direct pre-authenticated GitHub CLI access without requiring network access to api.github.com:

tools:
  github:
    mode: gh-proxy

See GitHub Tools for more information on gh-proxy mode.

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "api.github.com"
    - "github.com"
    - "raw.githubusercontent.com"
    - "registry.npmjs.org"

See Network Configuration for more information.

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 37.7 AIC · ⌖ 7.4 AIC · ⊞ 23.5K ·
Comment /review to run again

@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.

Request changes

The import-side fix is fine, but the codemod now takes on a much riskier job: rewriting frontmatter when both legacy bots and on.bots exist. That new path is driven by indentation-sensitive line surgery rather than the parsed YAML structure, so it is easy to skip or mis-shape valid files that do not match the exact formatting this helper expects.

Blocking theme

The parser change addresses the real bug. The codemod change adds a second behavior surface that is substantially more fragile than the existing move-to-on helpers, yet the tests only cover one happy-path formatting shape. That is not enough confidence for a migration tool that rewrites user-authored workflow frontmatter.

Warning

Firewall blocked 4 domains

The following domains were blocked by the firewall during workflow execution:

  • api.github.com
  • github.com
  • raw.githubusercontent.com
  • registry.npmjs.org

[!TIP]
api.github.com is blocked because GitHub API access uses the built-in GitHub tools by default. Instead of adding api.github.com to network.allowed, use tools.github.mode: gh-proxy for direct pre-authenticated GitHub CLI access without requiring network access to api.github.com:

tools:
  github:
    mode: gh-proxy

See GitHub Tools for more information on gh-proxy mode.

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "api.github.com"
    - "github.com"
    - "raw.githubusercontent.com"
    - "registry.npmjs.org"

See Network Configuration for more information.

🔎 Code quality review by PR Code Quality Reviewer · copilot · gpt54 · 37.7 AIC · ⌖ 7.4 AIC · ⊞ 23.5K
Comment /review to run again

Comment thread pkg/parser/import_field_extractor.go Outdated
mergeJSONStringListField(fm, "bots", "[]", acc.botsSet, &acc.bots, func(m map[string]any, field string) (string, error) {
return extractFieldJSONFromMap(m, field, "[]")
})
mergeJSONStringListField(fm, "bots", "[]", acc.botsSet, &acc.bots, extractOnSectionFieldFromMap)

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.

This change breaks imported expression-based bot allowlists entirely: mergeBots now reads only on.bots, so shared workflows that still expose legacy top-level bots are ignored and the compiled guard falls back to author_association, which can reject valid bot-authored comments before membership checks ever run.

💡 Why this blocks the merge

The regression is already visible in TestCommentAuthorAssociationImportedExpressionBot: the imported "${{ vars.TRUSTED_BOT }}" bot never reaches GH_AW_ALLOWED_BOTS, so pre_activation.if keeps the static author_association gate. That changes runtime behavior, not just migration output.

A minimal fix is to keep import extraction backward-compatible for shared workflows by reading on.bots first and falling back to the legacy top-level bots field when importing, at least until old shared components have been codemodded.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot Please address the remaining blocking codemod feedback before this PR moves forward.

  • The import-side fix looks good, but the blocking review still flags the new bots + on.bots codemod rewrite path as too formatting-sensitive for user-authored frontmatter.
  • Please harden that migration path, expand coverage for non-happy-path formatting shapes, and then run the pr-finisher skill after pushing updates.

Generated by 👨‍🍳 PR Sous Chef · pi · gpt54 · 18.1 AIC · ⌖ 8.7 AIC · ⊞ 9.2K ·
Comment /souschef to run again

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>

Copilot AI commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

@copilot Please address the remaining blocking codemod feedback before this PR moves forward.

  • The import-side fix looks good, but the blocking review still flags the new bots + on.bots codemod ...

Fixed: the merge path now ignores descendant bots keys under on, preserves blank/commented YAML blocks while deduplicating and merging, and adds regressions for nested keys and formatting-sensitive lists. Validation passed with make agent-report-progress at 766b3e5.

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
@pelikhan

pelikhan commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

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

Copilot AI commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

@copilot fix https://github.com/github/gh-aw/actions/runs/33659701709/job/100349649990?pr=57968

Fixed in 32ff552: imported workflow bot allowlists now fall back to legacy top-level bots when on.bots is absent, so expression-based allowlists remain runtime-checked instead of generating a static author_association guard. Verified with go test ./pkg/workflow -run 'Test(Bots|CommentAuthorAssociationImportedExpressionBot)' -count=1.

@pelikhan

pelikhan commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

@copilot legacy top level bots is not supported anymore. Users are expected to run the codemod

@pelikhan

pelikhan commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

@copilot update teh codemod implementation to be more reliable.

Copilot AI commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

@copilot legacy top level bots is not supported anymore. Users are expected to run the codemod

Removed the import fallback for legacy top-level bots/skip-bots/skip-roles. The supported path is on.*, and the codemod remains the migration path for older frontmatter. Verified with go test ./pkg/workflow -run TestBotsImportMerge -count=1 and go test ./pkg/parser -run TestValidateMainWorkflowFrontmatter_RejectsUnsupportedTopLevelFields -count=1.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
@pelikhan
pelikhan merged commit 092d695 into main Sep 2, 2026
32 checks passed
@pelikhan
pelikhan deleted the copilot/import-merge-on-bots-field branch September 2, 2026 20:55
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.88.2

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.

4 participants