From 2f72d74774e46c9c0b47b7856432adc5d811ba5f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 01:01:39 +0000 Subject: [PATCH 01/20] Initial plan From 59e1d8db5958ab3f411cb21ae854347104b06af9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 01:50:17 +0000 Subject: [PATCH 02/20] fix: scope activation permissions to relevant trigger events Agent-Logs-Url: https://github.com/github/gh-aw/sessions/edcc6cac-38c8-4ee5-ae47-94cc8b1fbcd0 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../activation_permissions_scope_test.go | 79 +++++++++++++++++ pkg/workflow/compiler_activation_job.go | 87 +++++++++++++++---- .../task_and_reaction_permissions_test.go | 10 +-- 3 files changed, 152 insertions(+), 24 deletions(-) create mode 100644 pkg/workflow/activation_permissions_scope_test.go diff --git a/pkg/workflow/activation_permissions_scope_test.go b/pkg/workflow/activation_permissions_scope_test.go new file mode 100644 index 00000000000..2e42be8f46a --- /dev/null +++ b/pkg/workflow/activation_permissions_scope_test.go @@ -0,0 +1,79 @@ +//go:build !integration + +package workflow + +import ( + "os" + "path/filepath" + "testing" + + "github.com/github/gh-aw/pkg/constants" + "github.com/github/gh-aw/pkg/stringutil" + "github.com/github/gh-aw/pkg/testutil" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestActivationPermissionsIssueOnlyReactionAndStatusComment(t *testing.T) { + tmpDir := testutil.TempDir(t, "activation-perms-issues-only") + testFile := filepath.Join(tmpDir, "issue-only.md") + testContent := `--- +on: + reaction: eyes + status-comment: true + issues: + types: [opened] +engine: copilot +safe-outputs: + add-comment: +--- + +# Issue-only activation permissions +` + + err := os.WriteFile(testFile, []byte(testContent), 0644) + require.NoError(t, err, "failed to write test workflow") + + compiler := NewCompiler() + err = compiler.CompileWorkflow(testFile) + require.NoError(t, err, "failed to compile workflow") + + lockContent, err := os.ReadFile(stringutil.MarkdownToLockFile(testFile)) + require.NoError(t, err, "failed to read generated lock file") + + activationJobSection := extractJobSection(string(lockContent), string(constants.ActivationJobName)) + assert.Contains(t, activationJobSection, "issues: write", "activation job should include issues: write for issue trigger reactions/comments") + assert.NotContains(t, activationJobSection, "pull-requests: write", "activation job should not include pull-requests: write for issue-only triggers") + assert.NotContains(t, activationJobSection, "discussions: write", "activation job should not include discussions: write for issue-only triggers") +} + +func TestActivationPermissionsPRReviewReactionOnly(t *testing.T) { + tmpDir := testutil.TempDir(t, "activation-perms-pr-review") + testFile := filepath.Join(tmpDir, "pr-review-reaction.md") + testContent := `--- +on: + reaction: eyes + status-comment: false + pull_request_review_comment: + types: [created] +engine: copilot +--- + +# PR review reaction permissions +` + + err := os.WriteFile(testFile, []byte(testContent), 0644) + require.NoError(t, err, "failed to write test workflow") + + compiler := NewCompiler() + err = compiler.CompileWorkflow(testFile) + require.NoError(t, err, "failed to compile workflow") + + lockContent, err := os.ReadFile(stringutil.MarkdownToLockFile(testFile)) + require.NoError(t, err, "failed to read generated lock file") + + activationJobSection := extractJobSection(string(lockContent), string(constants.ActivationJobName)) + assert.Contains(t, activationJobSection, "pull-requests: write", "activation job should include pull-requests: write for PR review comment reactions") + assert.NotContains(t, activationJobSection, "issues: write", "activation job should not include issues: write for PR review comment reactions without status comments") + assert.NotContains(t, activationJobSection, "discussions: write", "activation job should not include discussions: write for PR review comment reactions") +} diff --git a/pkg/workflow/compiler_activation_job.go b/pkg/workflow/compiler_activation_job.go index 03158d6a8d6..61e2824ae56 100644 --- a/pkg/workflow/compiler_activation_job.go +++ b/pkg/workflow/compiler_activation_job.go @@ -125,11 +125,7 @@ func (c *Compiler) buildActivationJob(data *WorkflowData, preActivationJobCreate // Build the combined permissions needed for all activation steps. // For label removal we only add the scopes required by the enabled events. appPerms := NewPermissions() - if hasReaction || hasStatusComment { - appPerms.Set(PermissionIssues, PermissionWrite) - appPerms.Set(PermissionPullRequests, PermissionWrite) - appPerms.Set(PermissionDiscussions, PermissionWrite) - } + addActivationInteractionPermissions(appPerms, data.On, hasReaction, hasStatusComment) if shouldRemoveLabel { if slices.Contains(filteredLabelEvents, "issues") || slices.Contains(filteredLabelEvents, "pull_request") { appPerms.Set(PermissionIssues, PermissionWrite) @@ -554,20 +550,7 @@ func (c *Compiler) buildActivationJob(data *WorkflowData, preActivationJobCreate permsMap[PermissionActions] = PermissionRead } - if hasReaction { - permsMap[PermissionDiscussions] = PermissionWrite - permsMap[PermissionIssues] = PermissionWrite - permsMap[PermissionPullRequests] = PermissionWrite - } - - // Add write permissions if status comments are enabled (even without a reaction). - // Status comments post to issues, PRs, and discussions, so write access is required. - // Assigning write to the map is safe here - it does not downgrade existing permissions. - if hasStatusComment { - permsMap[PermissionDiscussions] = PermissionWrite - permsMap[PermissionIssues] = PermissionWrite - permsMap[PermissionPullRequests] = PermissionWrite - } + addActivationInteractionPermissionsMap(permsMap, data.On, hasReaction, hasStatusComment) // Add issues:write permission if lock-for-agent is enabled (even without reaction) if data.LockForAgent { @@ -621,6 +604,72 @@ func (c *Compiler) buildActivationJob(data *WorkflowData, preActivationJobCreate return job, nil } +func addActivationInteractionPermissions(perms *Permissions, onSection string, hasReaction bool, hasStatusComment bool) { + if perms == nil { + return + } + permsMap := make(map[PermissionScope]PermissionLevel) + addActivationInteractionPermissionsMap(permsMap, onSection, hasReaction, hasStatusComment) + for scope, level := range permsMap { + perms.Set(scope, level) + } +} + +func addActivationInteractionPermissionsMap( + permsMap map[PermissionScope]PermissionLevel, + onSection string, + hasReaction bool, + hasStatusComment bool, +) { + if !hasReaction && !hasStatusComment { + return + } + + // Fallback for unit tests or synthetic WorkflowData instances that do not populate the "on" section. + // Real compiled workflows always have a populated trigger section. + if onSection == "" { + if hasReaction || hasStatusComment { + permsMap[PermissionIssues] = PermissionWrite + permsMap[PermissionPullRequests] = PermissionWrite + permsMap[PermissionDiscussions] = PermissionWrite + } + return + } + + hasIssuesEvent := strings.Contains(onSection, "issues:") + hasIssueCommentEvent := strings.Contains(onSection, "issue_comment:") + hasPullRequestEvent := strings.Contains(onSection, "pull_request:") + hasPullRequestReviewCommentEvent := strings.Contains(onSection, "pull_request_review_comment:") + hasDiscussionEvent := strings.Contains(onSection, "discussion:") + hasDiscussionCommentEvent := strings.Contains(onSection, "discussion_comment:") + + if hasReaction { + // Reactions on issues, issue comments, and pull requests use issues endpoints. + if hasIssuesEvent || hasIssueCommentEvent || hasPullRequestEvent { + permsMap[PermissionIssues] = PermissionWrite + } + // Reactions on PR review comments use pull request review comment endpoints. + if hasPullRequestReviewCommentEvent { + permsMap[PermissionPullRequests] = PermissionWrite + } + // Reactions on discussions use GraphQL discussion APIs. + if hasDiscussionEvent || hasDiscussionCommentEvent { + permsMap[PermissionDiscussions] = PermissionWrite + } + } + + if hasStatusComment { + // Status comments for issue and pull request related events use issue comment endpoints. + if hasIssuesEvent || hasIssueCommentEvent || hasPullRequestEvent || hasPullRequestReviewCommentEvent { + permsMap[PermissionIssues] = PermissionWrite + } + // Status comments for discussions use discussion comment APIs. + if hasDiscussionEvent || hasDiscussionCommentEvent { + permsMap[PermissionDiscussions] = PermissionWrite + } + } +} + // generatePromptInActivationJob generates the prompt creation steps and adds them to the activation job // This creates the prompt.txt file that will be uploaded as an artifact and downloaded by the agent job // beforeActivationJobs is the list of custom job names that run before (i.e., are dependencies of) activation. diff --git a/pkg/workflow/task_and_reaction_permissions_test.go b/pkg/workflow/task_and_reaction_permissions_test.go index afd12488147..4be471fb5f1 100644 --- a/pkg/workflow/task_and_reaction_permissions_test.go +++ b/pkg/workflow/task_and_reaction_permissions_test.go @@ -98,14 +98,14 @@ The activation job references text output: "${{ steps.sanitized.outputs.text }}" } // Test 5: Verify activation job has required permissions for reactions - if !strings.Contains(activationJobSection, "discussions: write") { - t.Error("Activation job should have discussions: write permission") - } if !strings.Contains(activationJobSection, "issues: write") { t.Error("Activation job should have issues: write permission") } - if !strings.Contains(activationJobSection, "pull-requests: write") { - t.Error("Activation job should have pull-requests: write permission") + if strings.Contains(activationJobSection, "pull-requests: write") { + t.Error("Activation job should not have pull-requests: write permission for issues-only trigger") + } + if strings.Contains(activationJobSection, "discussions: write") { + t.Error("Activation job should not have discussions: write permission for issues-only trigger") } // Test 6: Verify reaction step is in activation job (moved from pre-activation) From 08292708b7d71a9966080a177c05cff943b3c230 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 01:51:39 +0000 Subject: [PATCH 03/20] fix: parse activation trigger events for precise permission scoping Agent-Logs-Url: https://github.com/github/gh-aw/sessions/edcc6cac-38c8-4ee5-ae47-94cc8b1fbcd0 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/workflow/compiler_activation_job.go | 58 ++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 7 deletions(-) diff --git a/pkg/workflow/compiler_activation_job.go b/pkg/workflow/compiler_activation_job.go index 61e2824ae56..b8e08d903c4 100644 --- a/pkg/workflow/compiler_activation_job.go +++ b/pkg/workflow/compiler_activation_job.go @@ -10,6 +10,7 @@ import ( "github.com/github/gh-aw/pkg/constants" "github.com/github/gh-aw/pkg/logger" "github.com/github/gh-aw/pkg/stringutil" + "github.com/goccy/go-yaml" ) var compilerActivationJobLog = logger.New("workflow:compiler_activation_job") @@ -636,15 +637,16 @@ func addActivationInteractionPermissionsMap( return } - hasIssuesEvent := strings.Contains(onSection, "issues:") - hasIssueCommentEvent := strings.Contains(onSection, "issue_comment:") - hasPullRequestEvent := strings.Contains(onSection, "pull_request:") - hasPullRequestReviewCommentEvent := strings.Contains(onSection, "pull_request_review_comment:") - hasDiscussionEvent := strings.Contains(onSection, "discussion:") - hasDiscussionCommentEvent := strings.Contains(onSection, "discussion_comment:") + eventSet := activationEventSet(onSection) + hasIssuesEvent := eventSet["issues"] + hasIssueCommentEvent := eventSet["issue_comment"] + hasPullRequestEvent := eventSet["pull_request"] + hasPullRequestReviewCommentEvent := eventSet["pull_request_review_comment"] + hasDiscussionEvent := eventSet["discussion"] + hasDiscussionCommentEvent := eventSet["discussion_comment"] if hasReaction { - // Reactions on issues, issue comments, and pull requests use issues endpoints. + // Reactions on issues, issue comments, and pull requests all use issues endpoints. if hasIssuesEvent || hasIssueCommentEvent || hasPullRequestEvent { permsMap[PermissionIssues] = PermissionWrite } @@ -670,6 +672,48 @@ func addActivationInteractionPermissionsMap( } } +func activationEventSet(onSection string) map[string]bool { + events := make(map[string]bool) + var onData map[string]any + if err := yaml.Unmarshal([]byte(onSection), &onData); err != nil { + return events + } + + onValue, hasOn := onData["on"] + if !hasOn { + return events + } + + switch v := onValue.(type) { + case string: + events[v] = true + case []any: + for _, item := range v { + if eventName, ok := item.(string); ok { + events[eventName] = true + } + } + case map[string]any: + for eventName := range v { + if isActivationMetadataTriggerField(eventName) { + continue + } + events[eventName] = true + } + } + + return events +} + +func isActivationMetadataTriggerField(eventName string) bool { + switch eventName { + case "reaction", "status-comment", "command", "slash_command", "label_command", "stop-after", "github-token", "github-app": + return true + default: + return false + } +} + // generatePromptInActivationJob generates the prompt creation steps and adds them to the activation job // This creates the prompt.txt file that will be uploaded as an artifact and downloaded by the agent job // beforeActivationJobs is the list of custom job names that run before (i.e., are dependencies of) activation. From 1c7edbfa39f0ba5a34b48827ec261ad1ccd1e55d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 01:52:44 +0000 Subject: [PATCH 04/20] chore: harden activation trigger parsing diagnostics Agent-Logs-Url: https://github.com/github/gh-aw/sessions/edcc6cac-38c8-4ee5-ae47-94cc8b1fbcd0 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/workflow/compiler_activation_job.go | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/pkg/workflow/compiler_activation_job.go b/pkg/workflow/compiler_activation_job.go index b8e08d903c4..336b0ee239e 100644 --- a/pkg/workflow/compiler_activation_job.go +++ b/pkg/workflow/compiler_activation_job.go @@ -15,6 +15,17 @@ import ( var compilerActivationJobLog = logger.New("workflow:compiler_activation_job") +var activationMetadataTriggerFields = map[string]struct{}{ + "reaction": {}, + "status-comment": {}, + "command": {}, + "slash_command": {}, + "label_command": {}, + "stop-after": {}, + "github-token": {}, + "github-app": {}, +} + // buildActivationJob creates the activation job that handles timestamp checking, reactions, and locking. // This job depends on the pre-activation job if it exists, and runs before the main agent job. func (c *Compiler) buildActivationJob(data *WorkflowData, preActivationJobCreated bool, workflowRunRepoSafety string, lockFilename string) (*Job, error) { @@ -629,6 +640,7 @@ func addActivationInteractionPermissionsMap( // Fallback for unit tests or synthetic WorkflowData instances that do not populate the "on" section. // Real compiled workflows always have a populated trigger section. if onSection == "" { + compilerActivationJobLog.Print("Empty on section while computing activation permissions; using broad fallback permissions") if hasReaction || hasStatusComment { permsMap[PermissionIssues] = PermissionWrite permsMap[PermissionPullRequests] = PermissionWrite @@ -676,6 +688,7 @@ func activationEventSet(onSection string) map[string]bool { events := make(map[string]bool) var onData map[string]any if err := yaml.Unmarshal([]byte(onSection), &onData); err != nil { + compilerActivationJobLog.Printf("Failed to parse on section for activation permission scoping: %v", err) return events } @@ -706,12 +719,8 @@ func activationEventSet(onSection string) map[string]bool { } func isActivationMetadataTriggerField(eventName string) bool { - switch eventName { - case "reaction", "status-comment", "command", "slash_command", "label_command", "stop-after", "github-token", "github-app": - return true - default: - return false - } + _, isMetadataField := activationMetadataTriggerFields[eventName] + return isMetadataField } // generatePromptInActivationJob generates the prompt creation steps and adds them to the activation job From f40e8dfd242cf97180c8929e6e04fc8f3850af12 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 16 Apr 2026 02:38:34 +0000 Subject: [PATCH 05/20] docs(adr): add draft ADR-26535 for event-scoped activation permission derivation Generated by the Design Decision Gate workflow. Records the architectural decision to derive activation job permissions from parsed trigger events rather than granting broad write scopes unconditionally. Co-Authored-By: Claude Sonnet 4.6 --- ...scoped-activation-permission-derivation.md | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 docs/adr/26535-event-scoped-activation-permission-derivation.md diff --git a/docs/adr/26535-event-scoped-activation-permission-derivation.md b/docs/adr/26535-event-scoped-activation-permission-derivation.md new file mode 100644 index 00000000000..49fdbdf33e7 --- /dev/null +++ b/docs/adr/26535-event-scoped-activation-permission-derivation.md @@ -0,0 +1,79 @@ +# ADR-26535: Event-Scoped Activation Permission Derivation + +**Date**: 2026-04-16 +**Status**: Draft +**Deciders**: pelikhan, Copilot + +--- + +## Part 1 — Narrative (Human-Friendly) + +### Context + +The `gh aw compile` command generates a lock file that includes an activation job with a `permissions` block and a GitHub App token minting step. Before this change, whenever a compiled workflow configured `reaction` or `status-comment` triggers, the compiler unconditionally granted `issues: write`, `pull-requests: write`, and `discussions: write` — even if the workflow only triggers on `issues` events and never touches pull requests or discussions. This violated the principle of least privilege and caused compiled lock files to request far broader scopes than any workflow operation actually required. The `on:` section in gh-aw workflow frontmatter is a superset of real GitHub event names: it also contains metadata trigger fields (`reaction`, `status-comment`, `command`, etc.) that are interpreted by the framework, not forwarded to GitHub. Distinguishing real event names from metadata fields is therefore a prerequisite to computing accurate permissions. + +### Decision + +We will derive activation job permissions by parsing the `on:` section YAML at compile time, filtering out known metadata trigger fields, and granting only the write scopes required by the real GitHub event types that are configured. `issues: write` is granted only when `issues`, `issue_comment`, or `pull_request` events are present (since reactions and status comments on issues/PRs use the Issues REST API). `pull-requests: write` is granted only when `pull_request_review_comment` events are present. `discussions: write` is granted only when `discussion` or `discussion_comment` events are present. A fallback to the previous broad-grant behavior is preserved for synthetic or test `WorkflowData` instances where the `on:` section is empty. + +### Alternatives Considered + +#### Alternative 1: Retain Broad Permission Grants + +Always grant `issues: write`, `pull-requests: write`, and `discussions: write` whenever reactions or status comments are configured. This is the pre-existing behavior and is trivially correct (it never under-grants). It was rejected because it violates the principle of least privilege: a workflow that only triggers on issues should not carry `pull-requests: write` or `discussions: write` in its lock file, as those scopes could be exploited or trigger unexpected behavior. + +#### Alternative 2: Explicit Permission Declaration in Workflow Frontmatter + +Require workflow authors to declare which GitHub API scopes they need (e.g., `permissions: issues: write`) directly in the workflow markdown. This would be explicit and flexible, but it places the burden of correct permission reasoning on workflow authors — who are often non-engineers — and creates a class of misconfiguration bugs where a workflow runs with too few permissions because the author forgot to declare a scope. Automated derivation at compile time is more reliable. + +#### Alternative 3: Runtime Permission Escalation + +Request a minimal token at activation time and escalate permissions lazily when an operation fails due to insufficient scope. This approach is more dynamic but requires network round-trips to detect permission failures and complicates error handling and auditability. Compile-time derivation is simpler to reason about and does not require runtime infrastructure changes. + +### Consequences + +#### Positive +- Compiled lock files satisfy least-privilege: a workflow that only reacts to issues will no longer carry `pull-requests: write` or `discussions: write` scopes. +- The permission derivation logic is centralized in two new functions (`addActivationInteractionPermissionsMap`, `activationEventSet`), making future changes to permission rules easier to locate and audit. +- The metadata field allowlist (`activationMetadataTriggerFields`) is explicit and visible, replacing implicit substring-matching heuristics. +- Regression tests directly verify least-privilege behavior for issue-only and PR-review-comment-only trigger configurations. + +#### Negative +- The compiler now has a dependency on YAML parsing of the `on:` section at permission-derivation time, which adds a new failure mode: a malformed `on:` section will silently fall back to an empty event set and grant no permissions for reactions/status comments (though this is unlikely in practice since the same section is validated earlier in the compile pipeline). +- The fallback to broad permissions for empty `on:` sections means unit tests that use synthetic `WorkflowData` without a populated `on:` field will continue to get over-broad permissions, masking potential regressions in tests that don't exercise the full compile pipeline. + +#### Neutral +- The `activationMetadataTriggerFields` allowlist must be kept in sync with the set of metadata keys that gh-aw recognizes in the `on:` block. Adding a new metadata key without updating this list will cause it to be treated as a real GitHub event and potentially produce incorrect permission grants. +- The change affects both the activation job `permissions` block and the GitHub App token minting permissions — both call-sites now share the same derivation logic, which is a desirable consistency improvement. + +--- + +## Part 2 — Normative Specification (RFC 2119) + +> The key words **MUST**, **MUST NOT**, **REQUIRED**, **SHALL**, **SHALL NOT**, **SHOULD**, **SHOULD NOT**, **RECOMMENDED**, **MAY**, and **OPTIONAL** in this section are to be interpreted as described in [RFC 2119](https://www.rfc-editor.org/rfc/rfc2119). + +### Activation Permission Derivation + +1. Implementations **MUST** derive activation job write permissions from the set of real GitHub event types present in the `on:` section, not from the presence of `reaction` or `status-comment` configuration alone. +2. Implementations **MUST NOT** grant `pull-requests: write` in the activation job unless `pull_request_review_comment` is among the configured trigger events. +3. Implementations **MUST NOT** grant `discussions: write` in the activation job unless `discussion` or `discussion_comment` is among the configured trigger events. +4. Implementations **MUST NOT** grant `issues: write` solely for reaction/status-comment purposes unless `issues`, `issue_comment`, or `pull_request` is among the configured trigger events. +5. Implementations **MUST** apply the same permission derivation logic to both the activation job `permissions` block and the GitHub App token minting permissions. + +### Metadata Field Filtering + +1. Implementations **MUST** maintain an explicit allowlist of gh-aw metadata trigger fields (e.g., `reaction`, `status-comment`, `command`, `slash_command`, `label_command`, `stop-after`, `github-token`, `github-app`) and **MUST** exclude them from the derived event set. +2. Implementations **MUST NOT** treat an unrecognized key in the `on:` map as a metadata field; unknown keys **SHOULD** be treated as real GitHub event names to avoid silent under-granting. + +### Fallback Behavior + +1. When the `on:` section is absent or empty at permission derivation time, implementations **SHOULD** fall back to granting the full set of broad permissions (`issues: write`, `pull-requests: write`, `discussions: write`) and **MUST** emit a diagnostic log message explaining that the broad fallback is in use. +2. Implementations **MUST NOT** silently grant zero permissions for reactions or status comments when the `on:` section is malformed; a parse failure **SHOULD** be logged and the empty event set **SHOULD** result in no reaction/status-comment-related permissions being added. + +### Conformance + +An implementation is considered conformant with this ADR if it satisfies all **MUST** and **MUST NOT** requirements above. Failure to meet any **MUST** or **MUST NOT** requirement constitutes non-conformance. + +--- + +*This is a DRAFT ADR generated by the [Design Decision Gate](https://github.com/github/gh-aw/actions/runs/24488870005) workflow. The PR author must review, complete, and finalize this document before the PR can merge.* From 5e6d9c7b62ded19663f9d44bd8ffe695c9d41671 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 02:48:21 +0000 Subject: [PATCH 06/20] chore: plan status-comment discussions option Agent-Logs-Url: https://github.com/github/gh-aw/sessions/17dee383-88fc-4612-a885-b768f0497ffd Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/ace-editor.lock.yml | 2 -- .github/workflows/archie.lock.yml | 2 -- .github/workflows/brave.lock.yml | 2 -- .github/workflows/changeset.lock.yml | 2 -- .github/workflows/ci-doctor.lock.yml | 2 -- .github/workflows/craft.lock.yml | 2 -- .github/workflows/dev.lock.yml | 1 - .github/workflows/grumpy-reviewer.lock.yml | 1 - .github/workflows/mergefest.lock.yml | 2 -- .github/workflows/pdf-summary.lock.yml | 2 -- .github/workflows/plan.lock.yml | 1 - .github/workflows/poem-bot.lock.yml | 2 -- .github/workflows/pr-nitpick-reviewer.lock.yml | 1 - .github/workflows/security-review.lock.yml | 1 - .github/workflows/smoke-agent-all-merged.lock.yml | 2 -- .github/workflows/smoke-agent-all-none.lock.yml | 2 -- .github/workflows/smoke-agent-public-approved.lock.yml | 2 -- .github/workflows/smoke-agent-public-none.lock.yml | 2 -- .github/workflows/smoke-agent-scoped-approved.lock.yml | 2 -- .github/workflows/smoke-claude.lock.yml | 2 -- .github/workflows/smoke-codex.lock.yml | 2 -- .github/workflows/smoke-copilot-arm.lock.yml | 2 -- .github/workflows/smoke-copilot.lock.yml | 2 -- .github/workflows/smoke-create-cross-repo-pr.lock.yml | 2 -- .github/workflows/smoke-gemini.lock.yml | 2 -- .github/workflows/smoke-multi-pr.lock.yml | 2 -- .github/workflows/smoke-project.lock.yml | 2 -- .github/workflows/smoke-service-ports.lock.yml | 3 --- .github/workflows/smoke-temporary-id.lock.yml | 2 -- .github/workflows/smoke-test-tools.lock.yml | 2 -- .github/workflows/smoke-update-cross-repo-pr.lock.yml | 2 -- .github/workflows/tidy.lock.yml | 2 -- .github/workflows/unbloat-docs.lock.yml | 2 -- .github/workflows/workflow-generator.lock.yml | 2 -- 34 files changed, 64 deletions(-) diff --git a/.github/workflows/ace-editor.lock.yml b/.github/workflows/ace-editor.lock.yml index 6756c8705d0..90b6f9ff116 100644 --- a/.github/workflows/ace-editor.lock.yml +++ b/.github/workflows/ace-editor.lock.yml @@ -65,9 +65,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/archie.lock.yml b/.github/workflows/archie.lock.yml index 051c4e6d598..fb80cdc6f71 100644 --- a/.github/workflows/archie.lock.yml +++ b/.github/workflows/archie.lock.yml @@ -81,9 +81,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/brave.lock.yml b/.github/workflows/brave.lock.yml index afa23f63b8e..1358334ff2d 100644 --- a/.github/workflows/brave.lock.yml +++ b/.github/workflows/brave.lock.yml @@ -71,9 +71,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/changeset.lock.yml b/.github/workflows/changeset.lock.yml index f1ab8c1feb3..eb1cca9aac4 100644 --- a/.github/workflows/changeset.lock.yml +++ b/.github/workflows/changeset.lock.yml @@ -88,9 +88,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: "" diff --git a/.github/workflows/ci-doctor.lock.yml b/.github/workflows/ci-doctor.lock.yml index e44b6c121f5..d688d2b3396 100644 --- a/.github/workflows/ci-doctor.lock.yml +++ b/.github/workflows/ci-doctor.lock.yml @@ -83,9 +83,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/craft.lock.yml b/.github/workflows/craft.lock.yml index 13ed115bfa7..55119e07c96 100644 --- a/.github/workflows/craft.lock.yml +++ b/.github/workflows/craft.lock.yml @@ -67,9 +67,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/dev.lock.yml b/.github/workflows/dev.lock.yml index ee4cdc65463..59725d5efe4 100644 --- a/.github/workflows/dev.lock.yml +++ b/.github/workflows/dev.lock.yml @@ -89,7 +89,6 @@ jobs: contents: read discussions: write issues: write - pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/grumpy-reviewer.lock.yml b/.github/workflows/grumpy-reviewer.lock.yml index e5217f41456..2a6286cc75a 100644 --- a/.github/workflows/grumpy-reviewer.lock.yml +++ b/.github/workflows/grumpy-reviewer.lock.yml @@ -82,7 +82,6 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write pull-requests: write outputs: diff --git a/.github/workflows/mergefest.lock.yml b/.github/workflows/mergefest.lock.yml index 3a14bd5dd0d..a8b65568c4f 100644 --- a/.github/workflows/mergefest.lock.yml +++ b/.github/workflows/mergefest.lock.yml @@ -67,9 +67,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/pdf-summary.lock.yml b/.github/workflows/pdf-summary.lock.yml index 7eb3ec2ecdd..ec0e5ddfffb 100644 --- a/.github/workflows/pdf-summary.lock.yml +++ b/.github/workflows/pdf-summary.lock.yml @@ -95,9 +95,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/plan.lock.yml b/.github/workflows/plan.lock.yml index 2d06e4e8559..de09ed34c01 100644 --- a/.github/workflows/plan.lock.yml +++ b/.github/workflows/plan.lock.yml @@ -72,7 +72,6 @@ jobs: contents: read discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/poem-bot.lock.yml b/.github/workflows/poem-bot.lock.yml index 40d3095a64e..e401f410ac9 100644 --- a/.github/workflows/poem-bot.lock.yml +++ b/.github/workflows/poem-bot.lock.yml @@ -88,9 +88,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/pr-nitpick-reviewer.lock.yml b/.github/workflows/pr-nitpick-reviewer.lock.yml index 86c4be38f31..19041c249d8 100644 --- a/.github/workflows/pr-nitpick-reviewer.lock.yml +++ b/.github/workflows/pr-nitpick-reviewer.lock.yml @@ -77,7 +77,6 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write pull-requests: write outputs: diff --git a/.github/workflows/security-review.lock.yml b/.github/workflows/security-review.lock.yml index 2f84086ec36..6e1d1291998 100644 --- a/.github/workflows/security-review.lock.yml +++ b/.github/workflows/security-review.lock.yml @@ -79,7 +79,6 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write pull-requests: write outputs: diff --git a/.github/workflows/smoke-agent-all-merged.lock.yml b/.github/workflows/smoke-agent-all-merged.lock.yml index 7743805dd3e..81249bd4825 100644 --- a/.github/workflows/smoke-agent-all-merged.lock.yml +++ b/.github/workflows/smoke-agent-all-merged.lock.yml @@ -89,9 +89,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-all-none.lock.yml b/.github/workflows/smoke-agent-all-none.lock.yml index 0aad235151f..13b9da636ad 100644 --- a/.github/workflows/smoke-agent-all-none.lock.yml +++ b/.github/workflows/smoke-agent-all-none.lock.yml @@ -89,9 +89,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-public-approved.lock.yml b/.github/workflows/smoke-agent-public-approved.lock.yml index f3551c138e3..025042bea67 100644 --- a/.github/workflows/smoke-agent-public-approved.lock.yml +++ b/.github/workflows/smoke-agent-public-approved.lock.yml @@ -91,9 +91,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-public-none.lock.yml b/.github/workflows/smoke-agent-public-none.lock.yml index 5e40aa1d6c7..b9607f24825 100644 --- a/.github/workflows/smoke-agent-public-none.lock.yml +++ b/.github/workflows/smoke-agent-public-none.lock.yml @@ -89,9 +89,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-scoped-approved.lock.yml b/.github/workflows/smoke-agent-scoped-approved.lock.yml index acb01dd34d2..5dc8a665d01 100644 --- a/.github/workflows/smoke-agent-scoped-approved.lock.yml +++ b/.github/workflows/smoke-agent-scoped-approved.lock.yml @@ -90,9 +90,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 9720c5a6ff2..66c79d80107 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -104,9 +104,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index e7d0d80289b..b7392818a52 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -100,9 +100,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-copilot-arm.lock.yml b/.github/workflows/smoke-copilot-arm.lock.yml index 57a0f01e5f2..bb182a5a6d7 100644 --- a/.github/workflows/smoke-copilot-arm.lock.yml +++ b/.github/workflows/smoke-copilot-arm.lock.yml @@ -100,9 +100,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index cca41299cb9..9be54f8d768 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -95,9 +95,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/smoke-create-cross-repo-pr.lock.yml b/.github/workflows/smoke-create-cross-repo-pr.lock.yml index 78b8877bcbc..e8a001e528c 100644 --- a/.github/workflows/smoke-create-cross-repo-pr.lock.yml +++ b/.github/workflows/smoke-create-cross-repo-pr.lock.yml @@ -89,9 +89,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-gemini.lock.yml b/.github/workflows/smoke-gemini.lock.yml index 27cfdc9571f..00c87c7c336 100644 --- a/.github/workflows/smoke-gemini.lock.yml +++ b/.github/workflows/smoke-gemini.lock.yml @@ -93,9 +93,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-multi-pr.lock.yml b/.github/workflows/smoke-multi-pr.lock.yml index b99c1b4140f..22c205bc806 100644 --- a/.github/workflows/smoke-multi-pr.lock.yml +++ b/.github/workflows/smoke-multi-pr.lock.yml @@ -89,9 +89,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-project.lock.yml b/.github/workflows/smoke-project.lock.yml index 6a99e4cc23e..f48bf7928a3 100644 --- a/.github/workflows/smoke-project.lock.yml +++ b/.github/workflows/smoke-project.lock.yml @@ -90,9 +90,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-service-ports.lock.yml b/.github/workflows/smoke-service-ports.lock.yml index 4565acb0813..929c7d1ca37 100644 --- a/.github/workflows/smoke-service-ports.lock.yml +++ b/.github/workflows/smoke-service-ports.lock.yml @@ -80,9 +80,6 @@ jobs: permissions: actions: read contents: read - discussions: write - issues: write - pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/smoke-temporary-id.lock.yml b/.github/workflows/smoke-temporary-id.lock.yml index e43cb991678..883a749f99a 100644 --- a/.github/workflows/smoke-temporary-id.lock.yml +++ b/.github/workflows/smoke-temporary-id.lock.yml @@ -88,9 +88,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-test-tools.lock.yml b/.github/workflows/smoke-test-tools.lock.yml index 3f5bb05600e..45cf8d7c230 100644 --- a/.github/workflows/smoke-test-tools.lock.yml +++ b/.github/workflows/smoke-test-tools.lock.yml @@ -93,9 +93,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-update-cross-repo-pr.lock.yml b/.github/workflows/smoke-update-cross-repo-pr.lock.yml index 5bb15df20c4..d63bc681d5c 100644 --- a/.github/workflows/smoke-update-cross-repo-pr.lock.yml +++ b/.github/workflows/smoke-update-cross-repo-pr.lock.yml @@ -91,9 +91,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/tidy.lock.yml b/.github/workflows/tidy.lock.yml index c398b18b37c..7dd56871208 100644 --- a/.github/workflows/tidy.lock.yml +++ b/.github/workflows/tidy.lock.yml @@ -87,9 +87,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/unbloat-docs.lock.yml b/.github/workflows/unbloat-docs.lock.yml index 00c3bd2263e..cec7056366e 100644 --- a/.github/workflows/unbloat-docs.lock.yml +++ b/.github/workflows/unbloat-docs.lock.yml @@ -86,9 +86,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/workflow-generator.lock.yml b/.github/workflows/workflow-generator.lock.yml index 7601d35e006..d1cb46b664b 100644 --- a/.github/workflows/workflow-generator.lock.yml +++ b/.github/workflows/workflow-generator.lock.yml @@ -71,9 +71,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: "" From 840f735ce2032ce0c64273d070ec31601d533563 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 02:48:39 +0000 Subject: [PATCH 07/20] chore: restore lock files after accidental plan commit Agent-Logs-Url: https://github.com/github/gh-aw/sessions/17dee383-88fc-4612-a885-b768f0497ffd Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/ace-editor.lock.yml | 2 ++ .github/workflows/archie.lock.yml | 2 ++ .github/workflows/brave.lock.yml | 2 ++ .github/workflows/changeset.lock.yml | 2 ++ .github/workflows/ci-doctor.lock.yml | 2 ++ .github/workflows/craft.lock.yml | 2 ++ .github/workflows/dev.lock.yml | 1 + .github/workflows/grumpy-reviewer.lock.yml | 1 + .github/workflows/mergefest.lock.yml | 2 ++ .github/workflows/pdf-summary.lock.yml | 2 ++ .github/workflows/plan.lock.yml | 1 + .github/workflows/poem-bot.lock.yml | 2 ++ .github/workflows/pr-nitpick-reviewer.lock.yml | 1 + .github/workflows/security-review.lock.yml | 1 + .github/workflows/smoke-agent-all-merged.lock.yml | 2 ++ .github/workflows/smoke-agent-all-none.lock.yml | 2 ++ .github/workflows/smoke-agent-public-approved.lock.yml | 2 ++ .github/workflows/smoke-agent-public-none.lock.yml | 2 ++ .github/workflows/smoke-agent-scoped-approved.lock.yml | 2 ++ .github/workflows/smoke-claude.lock.yml | 2 ++ .github/workflows/smoke-codex.lock.yml | 2 ++ .github/workflows/smoke-copilot-arm.lock.yml | 2 ++ .github/workflows/smoke-copilot.lock.yml | 2 ++ .github/workflows/smoke-create-cross-repo-pr.lock.yml | 2 ++ .github/workflows/smoke-gemini.lock.yml | 2 ++ .github/workflows/smoke-multi-pr.lock.yml | 2 ++ .github/workflows/smoke-project.lock.yml | 2 ++ .github/workflows/smoke-service-ports.lock.yml | 3 +++ .github/workflows/smoke-temporary-id.lock.yml | 2 ++ .github/workflows/smoke-test-tools.lock.yml | 2 ++ .github/workflows/smoke-update-cross-repo-pr.lock.yml | 2 ++ .github/workflows/tidy.lock.yml | 2 ++ .github/workflows/unbloat-docs.lock.yml | 2 ++ .github/workflows/workflow-generator.lock.yml | 2 ++ 34 files changed, 64 insertions(+) diff --git a/.github/workflows/ace-editor.lock.yml b/.github/workflows/ace-editor.lock.yml index 90b6f9ff116..6756c8705d0 100644 --- a/.github/workflows/ace-editor.lock.yml +++ b/.github/workflows/ace-editor.lock.yml @@ -65,7 +65,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/archie.lock.yml b/.github/workflows/archie.lock.yml index fb80cdc6f71..051c4e6d598 100644 --- a/.github/workflows/archie.lock.yml +++ b/.github/workflows/archie.lock.yml @@ -81,7 +81,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/brave.lock.yml b/.github/workflows/brave.lock.yml index 1358334ff2d..afa23f63b8e 100644 --- a/.github/workflows/brave.lock.yml +++ b/.github/workflows/brave.lock.yml @@ -71,7 +71,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/changeset.lock.yml b/.github/workflows/changeset.lock.yml index eb1cca9aac4..f1ab8c1feb3 100644 --- a/.github/workflows/changeset.lock.yml +++ b/.github/workflows/changeset.lock.yml @@ -88,7 +88,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: "" diff --git a/.github/workflows/ci-doctor.lock.yml b/.github/workflows/ci-doctor.lock.yml index d688d2b3396..e44b6c121f5 100644 --- a/.github/workflows/ci-doctor.lock.yml +++ b/.github/workflows/ci-doctor.lock.yml @@ -83,7 +83,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/craft.lock.yml b/.github/workflows/craft.lock.yml index 55119e07c96..13ed115bfa7 100644 --- a/.github/workflows/craft.lock.yml +++ b/.github/workflows/craft.lock.yml @@ -67,7 +67,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/dev.lock.yml b/.github/workflows/dev.lock.yml index 59725d5efe4..ee4cdc65463 100644 --- a/.github/workflows/dev.lock.yml +++ b/.github/workflows/dev.lock.yml @@ -89,6 +89,7 @@ jobs: contents: read discussions: write issues: write + pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/grumpy-reviewer.lock.yml b/.github/workflows/grumpy-reviewer.lock.yml index 2a6286cc75a..e5217f41456 100644 --- a/.github/workflows/grumpy-reviewer.lock.yml +++ b/.github/workflows/grumpy-reviewer.lock.yml @@ -82,6 +82,7 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write pull-requests: write outputs: diff --git a/.github/workflows/mergefest.lock.yml b/.github/workflows/mergefest.lock.yml index a8b65568c4f..3a14bd5dd0d 100644 --- a/.github/workflows/mergefest.lock.yml +++ b/.github/workflows/mergefest.lock.yml @@ -67,7 +67,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/pdf-summary.lock.yml b/.github/workflows/pdf-summary.lock.yml index ec0e5ddfffb..7eb3ec2ecdd 100644 --- a/.github/workflows/pdf-summary.lock.yml +++ b/.github/workflows/pdf-summary.lock.yml @@ -95,7 +95,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/plan.lock.yml b/.github/workflows/plan.lock.yml index de09ed34c01..2d06e4e8559 100644 --- a/.github/workflows/plan.lock.yml +++ b/.github/workflows/plan.lock.yml @@ -72,6 +72,7 @@ jobs: contents: read discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/poem-bot.lock.yml b/.github/workflows/poem-bot.lock.yml index e401f410ac9..40d3095a64e 100644 --- a/.github/workflows/poem-bot.lock.yml +++ b/.github/workflows/poem-bot.lock.yml @@ -88,7 +88,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/pr-nitpick-reviewer.lock.yml b/.github/workflows/pr-nitpick-reviewer.lock.yml index 19041c249d8..86c4be38f31 100644 --- a/.github/workflows/pr-nitpick-reviewer.lock.yml +++ b/.github/workflows/pr-nitpick-reviewer.lock.yml @@ -77,6 +77,7 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write pull-requests: write outputs: diff --git a/.github/workflows/security-review.lock.yml b/.github/workflows/security-review.lock.yml index 6e1d1291998..2f84086ec36 100644 --- a/.github/workflows/security-review.lock.yml +++ b/.github/workflows/security-review.lock.yml @@ -79,6 +79,7 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write pull-requests: write outputs: diff --git a/.github/workflows/smoke-agent-all-merged.lock.yml b/.github/workflows/smoke-agent-all-merged.lock.yml index 81249bd4825..7743805dd3e 100644 --- a/.github/workflows/smoke-agent-all-merged.lock.yml +++ b/.github/workflows/smoke-agent-all-merged.lock.yml @@ -89,7 +89,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-all-none.lock.yml b/.github/workflows/smoke-agent-all-none.lock.yml index 13b9da636ad..0aad235151f 100644 --- a/.github/workflows/smoke-agent-all-none.lock.yml +++ b/.github/workflows/smoke-agent-all-none.lock.yml @@ -89,7 +89,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-public-approved.lock.yml b/.github/workflows/smoke-agent-public-approved.lock.yml index 025042bea67..f3551c138e3 100644 --- a/.github/workflows/smoke-agent-public-approved.lock.yml +++ b/.github/workflows/smoke-agent-public-approved.lock.yml @@ -91,7 +91,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-public-none.lock.yml b/.github/workflows/smoke-agent-public-none.lock.yml index b9607f24825..5e40aa1d6c7 100644 --- a/.github/workflows/smoke-agent-public-none.lock.yml +++ b/.github/workflows/smoke-agent-public-none.lock.yml @@ -89,7 +89,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-scoped-approved.lock.yml b/.github/workflows/smoke-agent-scoped-approved.lock.yml index 5dc8a665d01..acb01dd34d2 100644 --- a/.github/workflows/smoke-agent-scoped-approved.lock.yml +++ b/.github/workflows/smoke-agent-scoped-approved.lock.yml @@ -90,7 +90,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 66c79d80107..9720c5a6ff2 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -104,7 +104,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index b7392818a52..e7d0d80289b 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -100,7 +100,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-copilot-arm.lock.yml b/.github/workflows/smoke-copilot-arm.lock.yml index bb182a5a6d7..57a0f01e5f2 100644 --- a/.github/workflows/smoke-copilot-arm.lock.yml +++ b/.github/workflows/smoke-copilot-arm.lock.yml @@ -100,7 +100,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index 9be54f8d768..cca41299cb9 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -95,7 +95,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/smoke-create-cross-repo-pr.lock.yml b/.github/workflows/smoke-create-cross-repo-pr.lock.yml index e8a001e528c..78b8877bcbc 100644 --- a/.github/workflows/smoke-create-cross-repo-pr.lock.yml +++ b/.github/workflows/smoke-create-cross-repo-pr.lock.yml @@ -89,7 +89,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-gemini.lock.yml b/.github/workflows/smoke-gemini.lock.yml index 00c87c7c336..27cfdc9571f 100644 --- a/.github/workflows/smoke-gemini.lock.yml +++ b/.github/workflows/smoke-gemini.lock.yml @@ -93,7 +93,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-multi-pr.lock.yml b/.github/workflows/smoke-multi-pr.lock.yml index 22c205bc806..b99c1b4140f 100644 --- a/.github/workflows/smoke-multi-pr.lock.yml +++ b/.github/workflows/smoke-multi-pr.lock.yml @@ -89,7 +89,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-project.lock.yml b/.github/workflows/smoke-project.lock.yml index f48bf7928a3..6a99e4cc23e 100644 --- a/.github/workflows/smoke-project.lock.yml +++ b/.github/workflows/smoke-project.lock.yml @@ -90,7 +90,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-service-ports.lock.yml b/.github/workflows/smoke-service-ports.lock.yml index 929c7d1ca37..4565acb0813 100644 --- a/.github/workflows/smoke-service-ports.lock.yml +++ b/.github/workflows/smoke-service-ports.lock.yml @@ -80,6 +80,9 @@ jobs: permissions: actions: read contents: read + discussions: write + issues: write + pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/smoke-temporary-id.lock.yml b/.github/workflows/smoke-temporary-id.lock.yml index 883a749f99a..e43cb991678 100644 --- a/.github/workflows/smoke-temporary-id.lock.yml +++ b/.github/workflows/smoke-temporary-id.lock.yml @@ -88,7 +88,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-test-tools.lock.yml b/.github/workflows/smoke-test-tools.lock.yml index 45cf8d7c230..3f5bb05600e 100644 --- a/.github/workflows/smoke-test-tools.lock.yml +++ b/.github/workflows/smoke-test-tools.lock.yml @@ -93,7 +93,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-update-cross-repo-pr.lock.yml b/.github/workflows/smoke-update-cross-repo-pr.lock.yml index d63bc681d5c..5bb15df20c4 100644 --- a/.github/workflows/smoke-update-cross-repo-pr.lock.yml +++ b/.github/workflows/smoke-update-cross-repo-pr.lock.yml @@ -91,7 +91,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/tidy.lock.yml b/.github/workflows/tidy.lock.yml index 7dd56871208..c398b18b37c 100644 --- a/.github/workflows/tidy.lock.yml +++ b/.github/workflows/tidy.lock.yml @@ -87,7 +87,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/unbloat-docs.lock.yml b/.github/workflows/unbloat-docs.lock.yml index cec7056366e..00c3bd2263e 100644 --- a/.github/workflows/unbloat-docs.lock.yml +++ b/.github/workflows/unbloat-docs.lock.yml @@ -86,7 +86,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/workflow-generator.lock.yml b/.github/workflows/workflow-generator.lock.yml index d1cb46b664b..7601d35e006 100644 --- a/.github/workflows/workflow-generator.lock.yml +++ b/.github/workflows/workflow-generator.lock.yml @@ -71,7 +71,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: "" From 6bc10d9dff3acc2a642bc80c00a9179568011e0e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 02:50:54 +0000 Subject: [PATCH 08/20] feat: add status-comment discussions toggle in frontmatter Agent-Logs-Url: https://github.com/github/gh-aw/sessions/17dee383-88fc-4612-a885-b768f0497ffd Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/parser/schemas/main_workflow_schema.json | 24 +++++++++++-- .../activation_permissions_scope_test.go | 34 ++++++++++++++++++ pkg/workflow/compiler_activation_job.go | 35 ++++++++++++++----- pkg/workflow/compiler_safe_outputs.go | 24 ++++++++++++- pkg/workflow/compiler_types.go | 1 + pkg/workflow/expression_builder.go | 19 ++++++++-- 6 files changed, 121 insertions(+), 16 deletions(-) diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index 0f4d83fdf80..b6d3ec452ea 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -1886,9 +1886,27 @@ "examples": ["eyes", "rocket", "+1", 1, -1, "none"] }, "status-comment": { - "type": "boolean", - "description": "Whether to post status comments (started/completed) on the triggering item. When true, adds a comment with workflow run link and updates it on completion. When false or not specified, no status comments are posted. Automatically enabled for slash_command and label_command triggers \u2014 manual configuration is only needed for other trigger types.", - "examples": [true, false] + "oneOf": [ + { + "type": "boolean" + }, + { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "type": "boolean", + "description": "Whether status comments are enabled." + }, + "discussions": { + "type": "boolean", + "description": "Whether status comments are allowed for discussion and discussion_comment triggers." + } + } + } + ], + "description": "Whether to post status comments (started/completed) on the triggering item. Boolean form enables/disables status comments globally. Object form supports fine-grained control with `enabled` and `discussions` fields. Automatically enabled for slash_command and label_command triggers when not explicitly configured.", + "examples": [true, false, { "enabled": true, "discussions": false }] }, "github-token": { "type": "string", diff --git a/pkg/workflow/activation_permissions_scope_test.go b/pkg/workflow/activation_permissions_scope_test.go index 2e42be8f46a..d355dc11203 100644 --- a/pkg/workflow/activation_permissions_scope_test.go +++ b/pkg/workflow/activation_permissions_scope_test.go @@ -77,3 +77,37 @@ engine: copilot assert.NotContains(t, activationJobSection, "issues: write", "activation job should not include issues: write for PR review comment reactions without status comments") assert.NotContains(t, activationJobSection, "discussions: write", "activation job should not include discussions: write for PR review comment reactions") } + +func TestActivationPermissionsStatusCommentDiscussionsDisabled(t *testing.T) { + tmpDir := testutil.TempDir(t, "activation-perms-status-comment-discussions-disabled") + testFile := filepath.Join(tmpDir, "status-comment-discussions-disabled.md") + testContent := `--- +on: + reaction: none + status-comment: + enabled: true + discussions: false + discussion: + types: [created] +engine: copilot +--- + +# Status comment discussions disabled +` + + err := os.WriteFile(testFile, []byte(testContent), 0644) + require.NoError(t, err, "failed to write test workflow") + + compiler := NewCompiler() + err = compiler.CompileWorkflow(testFile) + require.NoError(t, err, "failed to compile workflow") + + lockContent, err := os.ReadFile(stringutil.MarkdownToLockFile(testFile)) + require.NoError(t, err, "failed to read generated lock file") + + activationJobSection := extractJobSection(string(lockContent), string(constants.ActivationJobName)) + assert.NotContains(t, activationJobSection, "discussions: write", "activation job should not include discussions: write when status-comment.discussions is false") + assert.Contains(t, activationJobSection, "Add comment with workflow run link", "activation job should still include status comment step when enabled") + assert.NotContains(t, activationJobSection, "github.event_name == 'discussion'", "status comment condition should not include discussion events when status-comment.discussions is false") + assert.NotContains(t, activationJobSection, "github.event_name == 'discussion_comment'", "status comment condition should not include discussion_comment events when status-comment.discussions is false") +} diff --git a/pkg/workflow/compiler_activation_job.go b/pkg/workflow/compiler_activation_job.go index 336b0ee239e..b7d2e4956de 100644 --- a/pkg/workflow/compiler_activation_job.go +++ b/pkg/workflow/compiler_activation_job.go @@ -118,6 +118,7 @@ func (c *Compiler) buildActivationJob(data *WorkflowData, preActivationJobCreate // inserted right after generate_aw_info for fast user feedback. hasReaction := data.AIReaction != "" && data.AIReaction != "none" hasStatusComment := data.StatusComment != nil && *data.StatusComment + statusCommentIncludesDiscussions := shouldIncludeDiscussionStatusComments(data) hasLabelCommand := len(data.LabelCommand) > 0 // shouldRemoveLabel is true when label-command is active AND remove_label is not disabled shouldRemoveLabel := hasLabelCommand && data.LabelCommandRemoveLabel @@ -137,7 +138,7 @@ func (c *Compiler) buildActivationJob(data *WorkflowData, preActivationJobCreate // Build the combined permissions needed for all activation steps. // For label removal we only add the scopes required by the enabled events. appPerms := NewPermissions() - addActivationInteractionPermissions(appPerms, data.On, hasReaction, hasStatusComment) + addActivationInteractionPermissions(appPerms, data.On, hasReaction, hasStatusComment, statusCommentIncludesDiscussions) if shouldRemoveLabel { if slices.Contains(filteredLabelEvents, "issues") || slices.Contains(filteredLabelEvents, "pull_request") { appPerms.Set(PermissionIssues, PermissionWrite) @@ -299,11 +300,11 @@ func (c *Compiler) buildActivationJob(data *WorkflowData, preActivationJobCreate // Add comment with workflow run link if status comments are explicitly enabled if data.StatusComment != nil && *data.StatusComment { - reactionCondition := BuildReactionCondition() + statusCommentCondition := BuildStatusCommentCondition(statusCommentIncludesDiscussions) steps = append(steps, " - name: Add comment with workflow run link\n") steps = append(steps, " id: add-comment\n") - steps = append(steps, fmt.Sprintf(" if: %s\n", RenderCondition(reactionCondition))) + steps = append(steps, fmt.Sprintf(" if: %s\n", RenderCondition(statusCommentCondition))) steps = append(steps, fmt.Sprintf(" uses: %s\n", getCachedActionPin("actions/github-script", data))) // Add environment variables @@ -562,7 +563,7 @@ func (c *Compiler) buildActivationJob(data *WorkflowData, preActivationJobCreate permsMap[PermissionActions] = PermissionRead } - addActivationInteractionPermissionsMap(permsMap, data.On, hasReaction, hasStatusComment) + addActivationInteractionPermissionsMap(permsMap, data.On, hasReaction, hasStatusComment, statusCommentIncludesDiscussions) // Add issues:write permission if lock-for-agent is enabled (even without reaction) if data.LockForAgent { @@ -616,12 +617,18 @@ func (c *Compiler) buildActivationJob(data *WorkflowData, preActivationJobCreate return job, nil } -func addActivationInteractionPermissions(perms *Permissions, onSection string, hasReaction bool, hasStatusComment bool) { +func addActivationInteractionPermissions( + perms *Permissions, + onSection string, + hasReaction bool, + hasStatusComment bool, + statusCommentIncludesDiscussions bool, +) { if perms == nil { return } permsMap := make(map[PermissionScope]PermissionLevel) - addActivationInteractionPermissionsMap(permsMap, onSection, hasReaction, hasStatusComment) + addActivationInteractionPermissionsMap(permsMap, onSection, hasReaction, hasStatusComment, statusCommentIncludesDiscussions) for scope, level := range permsMap { perms.Set(scope, level) } @@ -632,6 +639,7 @@ func addActivationInteractionPermissionsMap( onSection string, hasReaction bool, hasStatusComment bool, + statusCommentIncludesDiscussions bool, ) { if !hasReaction && !hasStatusComment { return @@ -644,7 +652,9 @@ func addActivationInteractionPermissionsMap( if hasReaction || hasStatusComment { permsMap[PermissionIssues] = PermissionWrite permsMap[PermissionPullRequests] = PermissionWrite - permsMap[PermissionDiscussions] = PermissionWrite + if hasReaction || statusCommentIncludesDiscussions { + permsMap[PermissionDiscussions] = PermissionWrite + } } return } @@ -677,13 +687,20 @@ func addActivationInteractionPermissionsMap( if hasIssuesEvent || hasIssueCommentEvent || hasPullRequestEvent || hasPullRequestReviewCommentEvent { permsMap[PermissionIssues] = PermissionWrite } - // Status comments for discussions use discussion comment APIs. - if hasDiscussionEvent || hasDiscussionCommentEvent { + // Status comments for discussions use discussion comment APIs and can be disabled via frontmatter. + if statusCommentIncludesDiscussions && (hasDiscussionEvent || hasDiscussionCommentEvent) { permsMap[PermissionDiscussions] = PermissionWrite } } } +func shouldIncludeDiscussionStatusComments(data *WorkflowData) bool { + if data == nil || data.StatusCommentDiscussions == nil { + return true + } + return *data.StatusCommentDiscussions +} + func activationEventSet(onSection string) map[string]bool { events := make(map[string]bool) var onData map[string]any diff --git a/pkg/workflow/compiler_safe_outputs.go b/pkg/workflow/compiler_safe_outputs.go index 40f549d0930..ae5daff242f 100644 --- a/pkg/workflow/compiler_safe_outputs.go +++ b/pkg/workflow/compiler_safe_outputs.go @@ -67,8 +67,30 @@ func (c *Compiler) parseOnSection(frontmatter map[string]any, workflowData *Work if statusCommentBool, ok := statusCommentValue.(bool); ok { workflowData.StatusComment = &statusCommentBool compilerSafeOutputsLog.Printf("status-comment set to: %v", statusCommentBool) + } else if statusCommentMap, ok := statusCommentValue.(map[string]any); ok { + statusCommentEnabled := true + if enabledValue, hasEnabled := statusCommentMap["enabled"]; hasEnabled { + enabledBool, ok := enabledValue.(bool) + if !ok { + return fmt.Errorf("status-comment.enabled must be a boolean value, got %T", enabledValue) + } + statusCommentEnabled = enabledBool + } + + statusCommentDiscussions := true + if discussionsValue, hasDiscussions := statusCommentMap["discussions"]; hasDiscussions { + discussionsBool, ok := discussionsValue.(bool) + if !ok { + return fmt.Errorf("status-comment.discussions must be a boolean value, got %T", discussionsValue) + } + statusCommentDiscussions = discussionsBool + } + + workflowData.StatusComment = &statusCommentEnabled + workflowData.StatusCommentDiscussions = &statusCommentDiscussions + compilerSafeOutputsLog.Printf("status-comment object set: enabled=%v discussions=%v", statusCommentEnabled, statusCommentDiscussions) } else { - return fmt.Errorf("status-comment must be a boolean value, got %T", statusCommentValue) + return fmt.Errorf("status-comment must be a boolean or object value, got %T", statusCommentValue) } } diff --git a/pkg/workflow/compiler_types.go b/pkg/workflow/compiler_types.go index 9dbc2a0b68d..97d0cc3e074 100644 --- a/pkg/workflow/compiler_types.go +++ b/pkg/workflow/compiler_types.go @@ -436,6 +436,7 @@ type WorkflowData struct { LabelCommandRemoveLabel bool // whether to automatically remove the triggering label (default: true) AIReaction string // AI reaction type like "eyes", "heart", etc. StatusComment *bool // whether to post status comments (default: true when ai-reaction is set, false otherwise) + StatusCommentDiscussions *bool // whether status comments are allowed on discussion/discussion_comment triggers (default: true) ActivationGitHubToken string // custom github token from on.github-token for reactions/comments ActivationGitHubApp *GitHubAppConfig // github app config from on.github-app for minting activation tokens TopLevelGitHubApp *GitHubAppConfig // top-level github-app fallback for all nested github-app token minting operations diff --git a/pkg/workflow/expression_builder.go b/pkg/workflow/expression_builder.go index f293deed838..849f82c361a 100644 --- a/pkg/workflow/expression_builder.go +++ b/pkg/workflow/expression_builder.go @@ -65,14 +65,27 @@ func BuildAnd(left ConditionNode, right ConditionNode) ConditionNode { // BuildReactionCondition creates a condition tree for the add_reaction job func BuildReactionCondition() ConditionNode { expressionBuilderLog.Print("Building reaction condition for multiple event types") - // Build a list of event types that should trigger reactions using the new expression nodes + return buildReactionLikeCondition(true) +} + +// BuildStatusCommentCondition creates a condition tree for activation status comments. +// When includeDiscussions is false, discussion and discussion_comment events are excluded. +func BuildStatusCommentCondition(includeDiscussions bool) ConditionNode { + expressionBuilderLog.Printf("Building status comment condition: includeDiscussions=%t", includeDiscussions) + return buildReactionLikeCondition(includeDiscussions) +} + +func buildReactionLikeCondition(includeDiscussions bool) ConditionNode { + // Build a list of event types that should trigger reactions/status-comments using expression nodes. var terms []ConditionNode terms = append(terms, BuildEventTypeEquals("issues")) terms = append(terms, BuildEventTypeEquals("issue_comment")) terms = append(terms, BuildEventTypeEquals("pull_request_review_comment")) - terms = append(terms, BuildEventTypeEquals("discussion")) - terms = append(terms, BuildEventTypeEquals("discussion_comment")) + if includeDiscussions { + terms = append(terms, BuildEventTypeEquals("discussion")) + terms = append(terms, BuildEventTypeEquals("discussion_comment")) + } // For pull_request events, we need to ensure it's not from a forked repository // since forked repositories have read-only permissions and cannot add reactions From 9b9fe1ad632438a3d7b97401d2e99e2f57e4a92b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 02:51:53 +0000 Subject: [PATCH 09/20] test: strengthen assertions for status-comment discussions toggle Agent-Logs-Url: https://github.com/github/gh-aw/sessions/17dee383-88fc-4612-a885-b768f0497ffd Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/workflow/activation_permissions_scope_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/workflow/activation_permissions_scope_test.go b/pkg/workflow/activation_permissions_scope_test.go index d355dc11203..66a229aff1e 100644 --- a/pkg/workflow/activation_permissions_scope_test.go +++ b/pkg/workflow/activation_permissions_scope_test.go @@ -108,6 +108,8 @@ engine: copilot activationJobSection := extractJobSection(string(lockContent), string(constants.ActivationJobName)) assert.NotContains(t, activationJobSection, "discussions: write", "activation job should not include discussions: write when status-comment.discussions is false") assert.Contains(t, activationJobSection, "Add comment with workflow run link", "activation job should still include status comment step when enabled") + assert.Contains(t, activationJobSection, "github.event_name == 'issues'", "status comment condition should still include issue events") + assert.Contains(t, activationJobSection, "github.event_name == 'issue_comment'", "status comment condition should still include issue_comment events") assert.NotContains(t, activationJobSection, "github.event_name == 'discussion'", "status comment condition should not include discussion events when status-comment.discussions is false") assert.NotContains(t, activationJobSection, "github.event_name == 'discussion_comment'", "status comment condition should not include discussion_comment events when status-comment.discussions is false") } From f74962d76541f075023976a2f06784d813eb0af2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 02:56:57 +0000 Subject: [PATCH 10/20] chore: plan comment review follow-up Agent-Logs-Url: https://github.com/github/gh-aw/sessions/80610c4f-24d3-427a-be56-0be0e5db7106 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/ace-editor.lock.yml | 2 -- .github/workflows/archie.lock.yml | 2 -- .github/workflows/brave.lock.yml | 2 -- .github/workflows/changeset.lock.yml | 2 -- .github/workflows/ci-doctor.lock.yml | 2 -- .github/workflows/craft.lock.yml | 2 -- .github/workflows/dev.lock.yml | 1 - .github/workflows/grumpy-reviewer.lock.yml | 1 - .github/workflows/mergefest.lock.yml | 2 -- .github/workflows/pdf-summary.lock.yml | 2 -- .github/workflows/plan.lock.yml | 1 - .github/workflows/poem-bot.lock.yml | 2 -- .github/workflows/pr-nitpick-reviewer.lock.yml | 1 - .github/workflows/security-review.lock.yml | 1 - .github/workflows/smoke-agent-all-merged.lock.yml | 2 -- .github/workflows/smoke-agent-all-none.lock.yml | 2 -- .github/workflows/smoke-agent-public-approved.lock.yml | 2 -- .github/workflows/smoke-agent-public-none.lock.yml | 2 -- .github/workflows/smoke-agent-scoped-approved.lock.yml | 2 -- .github/workflows/smoke-claude.lock.yml | 2 -- .github/workflows/smoke-codex.lock.yml | 2 -- .github/workflows/smoke-copilot-arm.lock.yml | 2 -- .github/workflows/smoke-copilot.lock.yml | 2 -- .github/workflows/smoke-create-cross-repo-pr.lock.yml | 2 -- .github/workflows/smoke-gemini.lock.yml | 2 -- .github/workflows/smoke-multi-pr.lock.yml | 2 -- .github/workflows/smoke-project.lock.yml | 2 -- .github/workflows/smoke-service-ports.lock.yml | 3 --- .github/workflows/smoke-temporary-id.lock.yml | 2 -- .github/workflows/smoke-test-tools.lock.yml | 2 -- .github/workflows/smoke-update-cross-repo-pr.lock.yml | 2 -- .github/workflows/tidy.lock.yml | 2 -- .github/workflows/unbloat-docs.lock.yml | 2 -- .github/workflows/workflow-generator.lock.yml | 2 -- 34 files changed, 64 deletions(-) diff --git a/.github/workflows/ace-editor.lock.yml b/.github/workflows/ace-editor.lock.yml index 6756c8705d0..90b6f9ff116 100644 --- a/.github/workflows/ace-editor.lock.yml +++ b/.github/workflows/ace-editor.lock.yml @@ -65,9 +65,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/archie.lock.yml b/.github/workflows/archie.lock.yml index 051c4e6d598..fb80cdc6f71 100644 --- a/.github/workflows/archie.lock.yml +++ b/.github/workflows/archie.lock.yml @@ -81,9 +81,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/brave.lock.yml b/.github/workflows/brave.lock.yml index afa23f63b8e..1358334ff2d 100644 --- a/.github/workflows/brave.lock.yml +++ b/.github/workflows/brave.lock.yml @@ -71,9 +71,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/changeset.lock.yml b/.github/workflows/changeset.lock.yml index f1ab8c1feb3..eb1cca9aac4 100644 --- a/.github/workflows/changeset.lock.yml +++ b/.github/workflows/changeset.lock.yml @@ -88,9 +88,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: "" diff --git a/.github/workflows/ci-doctor.lock.yml b/.github/workflows/ci-doctor.lock.yml index e44b6c121f5..d688d2b3396 100644 --- a/.github/workflows/ci-doctor.lock.yml +++ b/.github/workflows/ci-doctor.lock.yml @@ -83,9 +83,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/craft.lock.yml b/.github/workflows/craft.lock.yml index 13ed115bfa7..55119e07c96 100644 --- a/.github/workflows/craft.lock.yml +++ b/.github/workflows/craft.lock.yml @@ -67,9 +67,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/dev.lock.yml b/.github/workflows/dev.lock.yml index ee4cdc65463..59725d5efe4 100644 --- a/.github/workflows/dev.lock.yml +++ b/.github/workflows/dev.lock.yml @@ -89,7 +89,6 @@ jobs: contents: read discussions: write issues: write - pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/grumpy-reviewer.lock.yml b/.github/workflows/grumpy-reviewer.lock.yml index e5217f41456..2a6286cc75a 100644 --- a/.github/workflows/grumpy-reviewer.lock.yml +++ b/.github/workflows/grumpy-reviewer.lock.yml @@ -82,7 +82,6 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write pull-requests: write outputs: diff --git a/.github/workflows/mergefest.lock.yml b/.github/workflows/mergefest.lock.yml index 3a14bd5dd0d..a8b65568c4f 100644 --- a/.github/workflows/mergefest.lock.yml +++ b/.github/workflows/mergefest.lock.yml @@ -67,9 +67,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/pdf-summary.lock.yml b/.github/workflows/pdf-summary.lock.yml index 7eb3ec2ecdd..ec0e5ddfffb 100644 --- a/.github/workflows/pdf-summary.lock.yml +++ b/.github/workflows/pdf-summary.lock.yml @@ -95,9 +95,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/plan.lock.yml b/.github/workflows/plan.lock.yml index 2d06e4e8559..de09ed34c01 100644 --- a/.github/workflows/plan.lock.yml +++ b/.github/workflows/plan.lock.yml @@ -72,7 +72,6 @@ jobs: contents: read discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/poem-bot.lock.yml b/.github/workflows/poem-bot.lock.yml index 40d3095a64e..e401f410ac9 100644 --- a/.github/workflows/poem-bot.lock.yml +++ b/.github/workflows/poem-bot.lock.yml @@ -88,9 +88,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/pr-nitpick-reviewer.lock.yml b/.github/workflows/pr-nitpick-reviewer.lock.yml index 86c4be38f31..19041c249d8 100644 --- a/.github/workflows/pr-nitpick-reviewer.lock.yml +++ b/.github/workflows/pr-nitpick-reviewer.lock.yml @@ -77,7 +77,6 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write pull-requests: write outputs: diff --git a/.github/workflows/security-review.lock.yml b/.github/workflows/security-review.lock.yml index 2f84086ec36..6e1d1291998 100644 --- a/.github/workflows/security-review.lock.yml +++ b/.github/workflows/security-review.lock.yml @@ -79,7 +79,6 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write pull-requests: write outputs: diff --git a/.github/workflows/smoke-agent-all-merged.lock.yml b/.github/workflows/smoke-agent-all-merged.lock.yml index 7743805dd3e..81249bd4825 100644 --- a/.github/workflows/smoke-agent-all-merged.lock.yml +++ b/.github/workflows/smoke-agent-all-merged.lock.yml @@ -89,9 +89,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-all-none.lock.yml b/.github/workflows/smoke-agent-all-none.lock.yml index 0aad235151f..13b9da636ad 100644 --- a/.github/workflows/smoke-agent-all-none.lock.yml +++ b/.github/workflows/smoke-agent-all-none.lock.yml @@ -89,9 +89,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-public-approved.lock.yml b/.github/workflows/smoke-agent-public-approved.lock.yml index f3551c138e3..025042bea67 100644 --- a/.github/workflows/smoke-agent-public-approved.lock.yml +++ b/.github/workflows/smoke-agent-public-approved.lock.yml @@ -91,9 +91,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-public-none.lock.yml b/.github/workflows/smoke-agent-public-none.lock.yml index 5e40aa1d6c7..b9607f24825 100644 --- a/.github/workflows/smoke-agent-public-none.lock.yml +++ b/.github/workflows/smoke-agent-public-none.lock.yml @@ -89,9 +89,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-scoped-approved.lock.yml b/.github/workflows/smoke-agent-scoped-approved.lock.yml index acb01dd34d2..5dc8a665d01 100644 --- a/.github/workflows/smoke-agent-scoped-approved.lock.yml +++ b/.github/workflows/smoke-agent-scoped-approved.lock.yml @@ -90,9 +90,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 9720c5a6ff2..66c79d80107 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -104,9 +104,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index e7d0d80289b..b7392818a52 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -100,9 +100,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-copilot-arm.lock.yml b/.github/workflows/smoke-copilot-arm.lock.yml index 57a0f01e5f2..bb182a5a6d7 100644 --- a/.github/workflows/smoke-copilot-arm.lock.yml +++ b/.github/workflows/smoke-copilot-arm.lock.yml @@ -100,9 +100,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index cca41299cb9..9be54f8d768 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -95,9 +95,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/smoke-create-cross-repo-pr.lock.yml b/.github/workflows/smoke-create-cross-repo-pr.lock.yml index 78b8877bcbc..e8a001e528c 100644 --- a/.github/workflows/smoke-create-cross-repo-pr.lock.yml +++ b/.github/workflows/smoke-create-cross-repo-pr.lock.yml @@ -89,9 +89,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-gemini.lock.yml b/.github/workflows/smoke-gemini.lock.yml index 27cfdc9571f..00c87c7c336 100644 --- a/.github/workflows/smoke-gemini.lock.yml +++ b/.github/workflows/smoke-gemini.lock.yml @@ -93,9 +93,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-multi-pr.lock.yml b/.github/workflows/smoke-multi-pr.lock.yml index b99c1b4140f..22c205bc806 100644 --- a/.github/workflows/smoke-multi-pr.lock.yml +++ b/.github/workflows/smoke-multi-pr.lock.yml @@ -89,9 +89,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-project.lock.yml b/.github/workflows/smoke-project.lock.yml index 6a99e4cc23e..f48bf7928a3 100644 --- a/.github/workflows/smoke-project.lock.yml +++ b/.github/workflows/smoke-project.lock.yml @@ -90,9 +90,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-service-ports.lock.yml b/.github/workflows/smoke-service-ports.lock.yml index 4565acb0813..929c7d1ca37 100644 --- a/.github/workflows/smoke-service-ports.lock.yml +++ b/.github/workflows/smoke-service-ports.lock.yml @@ -80,9 +80,6 @@ jobs: permissions: actions: read contents: read - discussions: write - issues: write - pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/smoke-temporary-id.lock.yml b/.github/workflows/smoke-temporary-id.lock.yml index e43cb991678..883a749f99a 100644 --- a/.github/workflows/smoke-temporary-id.lock.yml +++ b/.github/workflows/smoke-temporary-id.lock.yml @@ -88,9 +88,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-test-tools.lock.yml b/.github/workflows/smoke-test-tools.lock.yml index 3f5bb05600e..45cf8d7c230 100644 --- a/.github/workflows/smoke-test-tools.lock.yml +++ b/.github/workflows/smoke-test-tools.lock.yml @@ -93,9 +93,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-update-cross-repo-pr.lock.yml b/.github/workflows/smoke-update-cross-repo-pr.lock.yml index 5bb15df20c4..d63bc681d5c 100644 --- a/.github/workflows/smoke-update-cross-repo-pr.lock.yml +++ b/.github/workflows/smoke-update-cross-repo-pr.lock.yml @@ -91,9 +91,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/tidy.lock.yml b/.github/workflows/tidy.lock.yml index c398b18b37c..7dd56871208 100644 --- a/.github/workflows/tidy.lock.yml +++ b/.github/workflows/tidy.lock.yml @@ -87,9 +87,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/unbloat-docs.lock.yml b/.github/workflows/unbloat-docs.lock.yml index 00c3bd2263e..cec7056366e 100644 --- a/.github/workflows/unbloat-docs.lock.yml +++ b/.github/workflows/unbloat-docs.lock.yml @@ -86,9 +86,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/workflow-generator.lock.yml b/.github/workflows/workflow-generator.lock.yml index 7601d35e006..d1cb46b664b 100644 --- a/.github/workflows/workflow-generator.lock.yml +++ b/.github/workflows/workflow-generator.lock.yml @@ -71,9 +71,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: "" From 986dfab907a7025f3e1d9a1b3da915c5d1638d77 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 02:57:05 +0000 Subject: [PATCH 11/20] chore: restore lock files after plan update Agent-Logs-Url: https://github.com/github/gh-aw/sessions/80610c4f-24d3-427a-be56-0be0e5db7106 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/ace-editor.lock.yml | 2 ++ .github/workflows/archie.lock.yml | 2 ++ .github/workflows/brave.lock.yml | 2 ++ .github/workflows/changeset.lock.yml | 2 ++ .github/workflows/ci-doctor.lock.yml | 2 ++ .github/workflows/craft.lock.yml | 2 ++ .github/workflows/dev.lock.yml | 1 + .github/workflows/grumpy-reviewer.lock.yml | 1 + .github/workflows/mergefest.lock.yml | 2 ++ .github/workflows/pdf-summary.lock.yml | 2 ++ .github/workflows/plan.lock.yml | 1 + .github/workflows/poem-bot.lock.yml | 2 ++ .github/workflows/pr-nitpick-reviewer.lock.yml | 1 + .github/workflows/security-review.lock.yml | 1 + .github/workflows/smoke-agent-all-merged.lock.yml | 2 ++ .github/workflows/smoke-agent-all-none.lock.yml | 2 ++ .github/workflows/smoke-agent-public-approved.lock.yml | 2 ++ .github/workflows/smoke-agent-public-none.lock.yml | 2 ++ .github/workflows/smoke-agent-scoped-approved.lock.yml | 2 ++ .github/workflows/smoke-claude.lock.yml | 2 ++ .github/workflows/smoke-codex.lock.yml | 2 ++ .github/workflows/smoke-copilot-arm.lock.yml | 2 ++ .github/workflows/smoke-copilot.lock.yml | 2 ++ .github/workflows/smoke-create-cross-repo-pr.lock.yml | 2 ++ .github/workflows/smoke-gemini.lock.yml | 2 ++ .github/workflows/smoke-multi-pr.lock.yml | 2 ++ .github/workflows/smoke-project.lock.yml | 2 ++ .github/workflows/smoke-service-ports.lock.yml | 3 +++ .github/workflows/smoke-temporary-id.lock.yml | 2 ++ .github/workflows/smoke-test-tools.lock.yml | 2 ++ .github/workflows/smoke-update-cross-repo-pr.lock.yml | 2 ++ .github/workflows/tidy.lock.yml | 2 ++ .github/workflows/unbloat-docs.lock.yml | 2 ++ .github/workflows/workflow-generator.lock.yml | 2 ++ 34 files changed, 64 insertions(+) diff --git a/.github/workflows/ace-editor.lock.yml b/.github/workflows/ace-editor.lock.yml index 90b6f9ff116..6756c8705d0 100644 --- a/.github/workflows/ace-editor.lock.yml +++ b/.github/workflows/ace-editor.lock.yml @@ -65,7 +65,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/archie.lock.yml b/.github/workflows/archie.lock.yml index fb80cdc6f71..051c4e6d598 100644 --- a/.github/workflows/archie.lock.yml +++ b/.github/workflows/archie.lock.yml @@ -81,7 +81,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/brave.lock.yml b/.github/workflows/brave.lock.yml index 1358334ff2d..afa23f63b8e 100644 --- a/.github/workflows/brave.lock.yml +++ b/.github/workflows/brave.lock.yml @@ -71,7 +71,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/changeset.lock.yml b/.github/workflows/changeset.lock.yml index eb1cca9aac4..f1ab8c1feb3 100644 --- a/.github/workflows/changeset.lock.yml +++ b/.github/workflows/changeset.lock.yml @@ -88,7 +88,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: "" diff --git a/.github/workflows/ci-doctor.lock.yml b/.github/workflows/ci-doctor.lock.yml index d688d2b3396..e44b6c121f5 100644 --- a/.github/workflows/ci-doctor.lock.yml +++ b/.github/workflows/ci-doctor.lock.yml @@ -83,7 +83,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/craft.lock.yml b/.github/workflows/craft.lock.yml index 55119e07c96..13ed115bfa7 100644 --- a/.github/workflows/craft.lock.yml +++ b/.github/workflows/craft.lock.yml @@ -67,7 +67,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/dev.lock.yml b/.github/workflows/dev.lock.yml index 59725d5efe4..ee4cdc65463 100644 --- a/.github/workflows/dev.lock.yml +++ b/.github/workflows/dev.lock.yml @@ -89,6 +89,7 @@ jobs: contents: read discussions: write issues: write + pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/grumpy-reviewer.lock.yml b/.github/workflows/grumpy-reviewer.lock.yml index 2a6286cc75a..e5217f41456 100644 --- a/.github/workflows/grumpy-reviewer.lock.yml +++ b/.github/workflows/grumpy-reviewer.lock.yml @@ -82,6 +82,7 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write pull-requests: write outputs: diff --git a/.github/workflows/mergefest.lock.yml b/.github/workflows/mergefest.lock.yml index a8b65568c4f..3a14bd5dd0d 100644 --- a/.github/workflows/mergefest.lock.yml +++ b/.github/workflows/mergefest.lock.yml @@ -67,7 +67,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/pdf-summary.lock.yml b/.github/workflows/pdf-summary.lock.yml index ec0e5ddfffb..7eb3ec2ecdd 100644 --- a/.github/workflows/pdf-summary.lock.yml +++ b/.github/workflows/pdf-summary.lock.yml @@ -95,7 +95,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/plan.lock.yml b/.github/workflows/plan.lock.yml index de09ed34c01..2d06e4e8559 100644 --- a/.github/workflows/plan.lock.yml +++ b/.github/workflows/plan.lock.yml @@ -72,6 +72,7 @@ jobs: contents: read discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/poem-bot.lock.yml b/.github/workflows/poem-bot.lock.yml index e401f410ac9..40d3095a64e 100644 --- a/.github/workflows/poem-bot.lock.yml +++ b/.github/workflows/poem-bot.lock.yml @@ -88,7 +88,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/pr-nitpick-reviewer.lock.yml b/.github/workflows/pr-nitpick-reviewer.lock.yml index 19041c249d8..86c4be38f31 100644 --- a/.github/workflows/pr-nitpick-reviewer.lock.yml +++ b/.github/workflows/pr-nitpick-reviewer.lock.yml @@ -77,6 +77,7 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write pull-requests: write outputs: diff --git a/.github/workflows/security-review.lock.yml b/.github/workflows/security-review.lock.yml index 6e1d1291998..2f84086ec36 100644 --- a/.github/workflows/security-review.lock.yml +++ b/.github/workflows/security-review.lock.yml @@ -79,6 +79,7 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write pull-requests: write outputs: diff --git a/.github/workflows/smoke-agent-all-merged.lock.yml b/.github/workflows/smoke-agent-all-merged.lock.yml index 81249bd4825..7743805dd3e 100644 --- a/.github/workflows/smoke-agent-all-merged.lock.yml +++ b/.github/workflows/smoke-agent-all-merged.lock.yml @@ -89,7 +89,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-all-none.lock.yml b/.github/workflows/smoke-agent-all-none.lock.yml index 13b9da636ad..0aad235151f 100644 --- a/.github/workflows/smoke-agent-all-none.lock.yml +++ b/.github/workflows/smoke-agent-all-none.lock.yml @@ -89,7 +89,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-public-approved.lock.yml b/.github/workflows/smoke-agent-public-approved.lock.yml index 025042bea67..f3551c138e3 100644 --- a/.github/workflows/smoke-agent-public-approved.lock.yml +++ b/.github/workflows/smoke-agent-public-approved.lock.yml @@ -91,7 +91,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-public-none.lock.yml b/.github/workflows/smoke-agent-public-none.lock.yml index b9607f24825..5e40aa1d6c7 100644 --- a/.github/workflows/smoke-agent-public-none.lock.yml +++ b/.github/workflows/smoke-agent-public-none.lock.yml @@ -89,7 +89,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-scoped-approved.lock.yml b/.github/workflows/smoke-agent-scoped-approved.lock.yml index 5dc8a665d01..acb01dd34d2 100644 --- a/.github/workflows/smoke-agent-scoped-approved.lock.yml +++ b/.github/workflows/smoke-agent-scoped-approved.lock.yml @@ -90,7 +90,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 66c79d80107..9720c5a6ff2 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -104,7 +104,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index b7392818a52..e7d0d80289b 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -100,7 +100,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-copilot-arm.lock.yml b/.github/workflows/smoke-copilot-arm.lock.yml index bb182a5a6d7..57a0f01e5f2 100644 --- a/.github/workflows/smoke-copilot-arm.lock.yml +++ b/.github/workflows/smoke-copilot-arm.lock.yml @@ -100,7 +100,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index 9be54f8d768..cca41299cb9 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -95,7 +95,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/smoke-create-cross-repo-pr.lock.yml b/.github/workflows/smoke-create-cross-repo-pr.lock.yml index e8a001e528c..78b8877bcbc 100644 --- a/.github/workflows/smoke-create-cross-repo-pr.lock.yml +++ b/.github/workflows/smoke-create-cross-repo-pr.lock.yml @@ -89,7 +89,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-gemini.lock.yml b/.github/workflows/smoke-gemini.lock.yml index 00c87c7c336..27cfdc9571f 100644 --- a/.github/workflows/smoke-gemini.lock.yml +++ b/.github/workflows/smoke-gemini.lock.yml @@ -93,7 +93,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-multi-pr.lock.yml b/.github/workflows/smoke-multi-pr.lock.yml index 22c205bc806..b99c1b4140f 100644 --- a/.github/workflows/smoke-multi-pr.lock.yml +++ b/.github/workflows/smoke-multi-pr.lock.yml @@ -89,7 +89,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-project.lock.yml b/.github/workflows/smoke-project.lock.yml index f48bf7928a3..6a99e4cc23e 100644 --- a/.github/workflows/smoke-project.lock.yml +++ b/.github/workflows/smoke-project.lock.yml @@ -90,7 +90,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-service-ports.lock.yml b/.github/workflows/smoke-service-ports.lock.yml index 929c7d1ca37..4565acb0813 100644 --- a/.github/workflows/smoke-service-ports.lock.yml +++ b/.github/workflows/smoke-service-ports.lock.yml @@ -80,6 +80,9 @@ jobs: permissions: actions: read contents: read + discussions: write + issues: write + pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/smoke-temporary-id.lock.yml b/.github/workflows/smoke-temporary-id.lock.yml index 883a749f99a..e43cb991678 100644 --- a/.github/workflows/smoke-temporary-id.lock.yml +++ b/.github/workflows/smoke-temporary-id.lock.yml @@ -88,7 +88,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-test-tools.lock.yml b/.github/workflows/smoke-test-tools.lock.yml index 45cf8d7c230..3f5bb05600e 100644 --- a/.github/workflows/smoke-test-tools.lock.yml +++ b/.github/workflows/smoke-test-tools.lock.yml @@ -93,7 +93,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-update-cross-repo-pr.lock.yml b/.github/workflows/smoke-update-cross-repo-pr.lock.yml index d63bc681d5c..5bb15df20c4 100644 --- a/.github/workflows/smoke-update-cross-repo-pr.lock.yml +++ b/.github/workflows/smoke-update-cross-repo-pr.lock.yml @@ -91,7 +91,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/tidy.lock.yml b/.github/workflows/tidy.lock.yml index 7dd56871208..c398b18b37c 100644 --- a/.github/workflows/tidy.lock.yml +++ b/.github/workflows/tidy.lock.yml @@ -87,7 +87,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/unbloat-docs.lock.yml b/.github/workflows/unbloat-docs.lock.yml index cec7056366e..00c3bd2263e 100644 --- a/.github/workflows/unbloat-docs.lock.yml +++ b/.github/workflows/unbloat-docs.lock.yml @@ -86,7 +86,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/workflow-generator.lock.yml b/.github/workflows/workflow-generator.lock.yml index d1cb46b664b..7601d35e006 100644 --- a/.github/workflows/workflow-generator.lock.yml +++ b/.github/workflows/workflow-generator.lock.yml @@ -71,7 +71,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: "" From 7fd4182cf2b0fff6d065a1ecbd99a0ab53c18509 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 03:07:51 +0000 Subject: [PATCH 12/20] fix: fallback activation permissions when on parsing fails Agent-Logs-Url: https://github.com/github/gh-aw/sessions/80610c4f-24d3-427a-be56-0be0e5db7106 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../activation_permissions_scope_test.go | 21 +++++++++ pkg/workflow/compiler_activation_job.go | 45 ++++++++++++++----- 2 files changed, 54 insertions(+), 12 deletions(-) diff --git a/pkg/workflow/activation_permissions_scope_test.go b/pkg/workflow/activation_permissions_scope_test.go index 66a229aff1e..644a13bd119 100644 --- a/pkg/workflow/activation_permissions_scope_test.go +++ b/pkg/workflow/activation_permissions_scope_test.go @@ -113,3 +113,24 @@ engine: copilot assert.NotContains(t, activationJobSection, "github.event_name == 'discussion'", "status comment condition should not include discussion events when status-comment.discussions is false") assert.NotContains(t, activationJobSection, "github.event_name == 'discussion_comment'", "status comment condition should not include discussion_comment events when status-comment.discussions is false") } + +func TestAddActivationInteractionPermissionsMapFallsBackOnInvalidOnYAML(t *testing.T) { + permsMap := map[PermissionScope]PermissionLevel{} + + addActivationInteractionPermissionsMap(permsMap, "on: [", true, true, true) + + assert.Equal(t, PermissionWrite, permsMap[PermissionIssues], "fallback should include issues:write") + assert.Equal(t, PermissionWrite, permsMap[PermissionPullRequests], "fallback should include pull-requests:write") + assert.Equal(t, PermissionWrite, permsMap[PermissionDiscussions], "fallback should include discussions:write when enabled") +} + +func TestAddActivationInteractionPermissionsMapFallbackRespectsStatusCommentDiscussionsToggle(t *testing.T) { + permsMap := map[PermissionScope]PermissionLevel{} + + addActivationInteractionPermissionsMap(permsMap, "name: no-on-key", false, true, false) + + assert.Equal(t, PermissionWrite, permsMap[PermissionIssues], "fallback should include issues:write for status comments") + assert.Equal(t, PermissionWrite, permsMap[PermissionPullRequests], "fallback should include pull-requests:write for status comments") + _, hasDiscussions := permsMap[PermissionDiscussions] + assert.False(t, hasDiscussions, "fallback should omit discussions:write when status-comment.discussions is false and reactions are disabled") +} diff --git a/pkg/workflow/compiler_activation_job.go b/pkg/workflow/compiler_activation_job.go index b7d2e4956de..86c739e9629 100644 --- a/pkg/workflow/compiler_activation_job.go +++ b/pkg/workflow/compiler_activation_job.go @@ -649,17 +649,17 @@ func addActivationInteractionPermissionsMap( // Real compiled workflows always have a populated trigger section. if onSection == "" { compilerActivationJobLog.Print("Empty on section while computing activation permissions; using broad fallback permissions") - if hasReaction || hasStatusComment { - permsMap[PermissionIssues] = PermissionWrite - permsMap[PermissionPullRequests] = PermissionWrite - if hasReaction || statusCommentIncludesDiscussions { - permsMap[PermissionDiscussions] = PermissionWrite - } - } + addBroadActivationInteractionPermissions(permsMap, hasReaction, hasStatusComment, statusCommentIncludesDiscussions) + return + } + + eventSet, eventSetParsed := activationEventSet(onSection) + if !eventSetParsed { + compilerActivationJobLog.Print("Unable to parse activation trigger events while computing permissions; using broad fallback permissions") + addBroadActivationInteractionPermissions(permsMap, hasReaction, hasStatusComment, statusCommentIncludesDiscussions) return } - eventSet := activationEventSet(onSection) hasIssuesEvent := eventSet["issues"] hasIssueCommentEvent := eventSet["issue_comment"] hasPullRequestEvent := eventSet["pull_request"] @@ -694,6 +694,23 @@ func addActivationInteractionPermissionsMap( } } +func addBroadActivationInteractionPermissions( + permsMap map[PermissionScope]PermissionLevel, + hasReaction bool, + hasStatusComment bool, + statusCommentIncludesDiscussions bool, +) { + if !hasReaction && !hasStatusComment { + return + } + + permsMap[PermissionIssues] = PermissionWrite + permsMap[PermissionPullRequests] = PermissionWrite + if hasReaction || statusCommentIncludesDiscussions { + permsMap[PermissionDiscussions] = PermissionWrite + } +} + func shouldIncludeDiscussionStatusComments(data *WorkflowData) bool { if data == nil || data.StatusCommentDiscussions == nil { return true @@ -701,17 +718,18 @@ func shouldIncludeDiscussionStatusComments(data *WorkflowData) bool { return *data.StatusCommentDiscussions } -func activationEventSet(onSection string) map[string]bool { +func activationEventSet(onSection string) (map[string]bool, bool) { events := make(map[string]bool) var onData map[string]any if err := yaml.Unmarshal([]byte(onSection), &onData); err != nil { compilerActivationJobLog.Printf("Failed to parse on section for activation permission scoping: %v", err) - return events + return events, false } onValue, hasOn := onData["on"] if !hasOn { - return events + compilerActivationJobLog.Print("No top-level on key found while parsing activation permission events") + return events, false } switch v := onValue.(type) { @@ -730,9 +748,12 @@ func activationEventSet(onSection string) map[string]bool { } events[eventName] = true } + default: + compilerActivationJobLog.Printf("Unsupported on section type for activation permission scoping: %T", onValue) + return events, false } - return events + return events, true } func isActivationMetadataTriggerField(eventName string) bool { From c8c3fbf7945a27e9e0810e790848a0c63f648689 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 03:13:02 +0000 Subject: [PATCH 13/20] chore: plan remove status-comment enabled field Agent-Logs-Url: https://github.com/github/gh-aw/sessions/d99aa4d7-b4fc-420a-989f-6df131fc2cee Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/ace-editor.lock.yml | 2 -- .github/workflows/archie.lock.yml | 2 -- .github/workflows/brave.lock.yml | 2 -- .github/workflows/changeset.lock.yml | 2 -- .github/workflows/ci-doctor.lock.yml | 2 -- .github/workflows/craft.lock.yml | 2 -- .github/workflows/dev.lock.yml | 1 - .github/workflows/grumpy-reviewer.lock.yml | 1 - .github/workflows/mergefest.lock.yml | 2 -- .github/workflows/pdf-summary.lock.yml | 2 -- .github/workflows/plan.lock.yml | 1 - .github/workflows/poem-bot.lock.yml | 2 -- .github/workflows/pr-nitpick-reviewer.lock.yml | 1 - .github/workflows/security-review.lock.yml | 1 - .github/workflows/smoke-agent-all-merged.lock.yml | 2 -- .github/workflows/smoke-agent-all-none.lock.yml | 2 -- .github/workflows/smoke-agent-public-approved.lock.yml | 2 -- .github/workflows/smoke-agent-public-none.lock.yml | 2 -- .github/workflows/smoke-agent-scoped-approved.lock.yml | 2 -- .github/workflows/smoke-claude.lock.yml | 2 -- .github/workflows/smoke-codex.lock.yml | 2 -- .github/workflows/smoke-copilot-arm.lock.yml | 2 -- .github/workflows/smoke-copilot.lock.yml | 2 -- .github/workflows/smoke-create-cross-repo-pr.lock.yml | 2 -- .github/workflows/smoke-gemini.lock.yml | 2 -- .github/workflows/smoke-multi-pr.lock.yml | 2 -- .github/workflows/smoke-project.lock.yml | 2 -- .github/workflows/smoke-service-ports.lock.yml | 3 --- .github/workflows/smoke-temporary-id.lock.yml | 2 -- .github/workflows/smoke-test-tools.lock.yml | 2 -- .github/workflows/smoke-update-cross-repo-pr.lock.yml | 2 -- .github/workflows/tidy.lock.yml | 2 -- .github/workflows/unbloat-docs.lock.yml | 2 -- .github/workflows/workflow-generator.lock.yml | 2 -- 34 files changed, 64 deletions(-) diff --git a/.github/workflows/ace-editor.lock.yml b/.github/workflows/ace-editor.lock.yml index 6756c8705d0..90b6f9ff116 100644 --- a/.github/workflows/ace-editor.lock.yml +++ b/.github/workflows/ace-editor.lock.yml @@ -65,9 +65,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/archie.lock.yml b/.github/workflows/archie.lock.yml index 051c4e6d598..fb80cdc6f71 100644 --- a/.github/workflows/archie.lock.yml +++ b/.github/workflows/archie.lock.yml @@ -81,9 +81,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/brave.lock.yml b/.github/workflows/brave.lock.yml index afa23f63b8e..1358334ff2d 100644 --- a/.github/workflows/brave.lock.yml +++ b/.github/workflows/brave.lock.yml @@ -71,9 +71,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/changeset.lock.yml b/.github/workflows/changeset.lock.yml index f1ab8c1feb3..eb1cca9aac4 100644 --- a/.github/workflows/changeset.lock.yml +++ b/.github/workflows/changeset.lock.yml @@ -88,9 +88,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: "" diff --git a/.github/workflows/ci-doctor.lock.yml b/.github/workflows/ci-doctor.lock.yml index e44b6c121f5..d688d2b3396 100644 --- a/.github/workflows/ci-doctor.lock.yml +++ b/.github/workflows/ci-doctor.lock.yml @@ -83,9 +83,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/craft.lock.yml b/.github/workflows/craft.lock.yml index 13ed115bfa7..55119e07c96 100644 --- a/.github/workflows/craft.lock.yml +++ b/.github/workflows/craft.lock.yml @@ -67,9 +67,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/dev.lock.yml b/.github/workflows/dev.lock.yml index ee4cdc65463..59725d5efe4 100644 --- a/.github/workflows/dev.lock.yml +++ b/.github/workflows/dev.lock.yml @@ -89,7 +89,6 @@ jobs: contents: read discussions: write issues: write - pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/grumpy-reviewer.lock.yml b/.github/workflows/grumpy-reviewer.lock.yml index e5217f41456..2a6286cc75a 100644 --- a/.github/workflows/grumpy-reviewer.lock.yml +++ b/.github/workflows/grumpy-reviewer.lock.yml @@ -82,7 +82,6 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write pull-requests: write outputs: diff --git a/.github/workflows/mergefest.lock.yml b/.github/workflows/mergefest.lock.yml index 3a14bd5dd0d..a8b65568c4f 100644 --- a/.github/workflows/mergefest.lock.yml +++ b/.github/workflows/mergefest.lock.yml @@ -67,9 +67,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/pdf-summary.lock.yml b/.github/workflows/pdf-summary.lock.yml index 7eb3ec2ecdd..ec0e5ddfffb 100644 --- a/.github/workflows/pdf-summary.lock.yml +++ b/.github/workflows/pdf-summary.lock.yml @@ -95,9 +95,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/plan.lock.yml b/.github/workflows/plan.lock.yml index 2d06e4e8559..de09ed34c01 100644 --- a/.github/workflows/plan.lock.yml +++ b/.github/workflows/plan.lock.yml @@ -72,7 +72,6 @@ jobs: contents: read discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/poem-bot.lock.yml b/.github/workflows/poem-bot.lock.yml index 40d3095a64e..e401f410ac9 100644 --- a/.github/workflows/poem-bot.lock.yml +++ b/.github/workflows/poem-bot.lock.yml @@ -88,9 +88,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/pr-nitpick-reviewer.lock.yml b/.github/workflows/pr-nitpick-reviewer.lock.yml index 86c4be38f31..19041c249d8 100644 --- a/.github/workflows/pr-nitpick-reviewer.lock.yml +++ b/.github/workflows/pr-nitpick-reviewer.lock.yml @@ -77,7 +77,6 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write pull-requests: write outputs: diff --git a/.github/workflows/security-review.lock.yml b/.github/workflows/security-review.lock.yml index 2f84086ec36..6e1d1291998 100644 --- a/.github/workflows/security-review.lock.yml +++ b/.github/workflows/security-review.lock.yml @@ -79,7 +79,6 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write pull-requests: write outputs: diff --git a/.github/workflows/smoke-agent-all-merged.lock.yml b/.github/workflows/smoke-agent-all-merged.lock.yml index 7743805dd3e..81249bd4825 100644 --- a/.github/workflows/smoke-agent-all-merged.lock.yml +++ b/.github/workflows/smoke-agent-all-merged.lock.yml @@ -89,9 +89,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-all-none.lock.yml b/.github/workflows/smoke-agent-all-none.lock.yml index 0aad235151f..13b9da636ad 100644 --- a/.github/workflows/smoke-agent-all-none.lock.yml +++ b/.github/workflows/smoke-agent-all-none.lock.yml @@ -89,9 +89,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-public-approved.lock.yml b/.github/workflows/smoke-agent-public-approved.lock.yml index f3551c138e3..025042bea67 100644 --- a/.github/workflows/smoke-agent-public-approved.lock.yml +++ b/.github/workflows/smoke-agent-public-approved.lock.yml @@ -91,9 +91,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-public-none.lock.yml b/.github/workflows/smoke-agent-public-none.lock.yml index 5e40aa1d6c7..b9607f24825 100644 --- a/.github/workflows/smoke-agent-public-none.lock.yml +++ b/.github/workflows/smoke-agent-public-none.lock.yml @@ -89,9 +89,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-scoped-approved.lock.yml b/.github/workflows/smoke-agent-scoped-approved.lock.yml index acb01dd34d2..5dc8a665d01 100644 --- a/.github/workflows/smoke-agent-scoped-approved.lock.yml +++ b/.github/workflows/smoke-agent-scoped-approved.lock.yml @@ -90,9 +90,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 9720c5a6ff2..66c79d80107 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -104,9 +104,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index e7d0d80289b..b7392818a52 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -100,9 +100,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-copilot-arm.lock.yml b/.github/workflows/smoke-copilot-arm.lock.yml index 57a0f01e5f2..bb182a5a6d7 100644 --- a/.github/workflows/smoke-copilot-arm.lock.yml +++ b/.github/workflows/smoke-copilot-arm.lock.yml @@ -100,9 +100,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index cca41299cb9..9be54f8d768 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -95,9 +95,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/smoke-create-cross-repo-pr.lock.yml b/.github/workflows/smoke-create-cross-repo-pr.lock.yml index 78b8877bcbc..e8a001e528c 100644 --- a/.github/workflows/smoke-create-cross-repo-pr.lock.yml +++ b/.github/workflows/smoke-create-cross-repo-pr.lock.yml @@ -89,9 +89,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-gemini.lock.yml b/.github/workflows/smoke-gemini.lock.yml index 27cfdc9571f..00c87c7c336 100644 --- a/.github/workflows/smoke-gemini.lock.yml +++ b/.github/workflows/smoke-gemini.lock.yml @@ -93,9 +93,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-multi-pr.lock.yml b/.github/workflows/smoke-multi-pr.lock.yml index b99c1b4140f..22c205bc806 100644 --- a/.github/workflows/smoke-multi-pr.lock.yml +++ b/.github/workflows/smoke-multi-pr.lock.yml @@ -89,9 +89,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-project.lock.yml b/.github/workflows/smoke-project.lock.yml index 6a99e4cc23e..f48bf7928a3 100644 --- a/.github/workflows/smoke-project.lock.yml +++ b/.github/workflows/smoke-project.lock.yml @@ -90,9 +90,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-service-ports.lock.yml b/.github/workflows/smoke-service-ports.lock.yml index 4565acb0813..929c7d1ca37 100644 --- a/.github/workflows/smoke-service-ports.lock.yml +++ b/.github/workflows/smoke-service-ports.lock.yml @@ -80,9 +80,6 @@ jobs: permissions: actions: read contents: read - discussions: write - issues: write - pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/smoke-temporary-id.lock.yml b/.github/workflows/smoke-temporary-id.lock.yml index e43cb991678..883a749f99a 100644 --- a/.github/workflows/smoke-temporary-id.lock.yml +++ b/.github/workflows/smoke-temporary-id.lock.yml @@ -88,9 +88,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-test-tools.lock.yml b/.github/workflows/smoke-test-tools.lock.yml index 3f5bb05600e..45cf8d7c230 100644 --- a/.github/workflows/smoke-test-tools.lock.yml +++ b/.github/workflows/smoke-test-tools.lock.yml @@ -93,9 +93,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-update-cross-repo-pr.lock.yml b/.github/workflows/smoke-update-cross-repo-pr.lock.yml index 5bb15df20c4..d63bc681d5c 100644 --- a/.github/workflows/smoke-update-cross-repo-pr.lock.yml +++ b/.github/workflows/smoke-update-cross-repo-pr.lock.yml @@ -91,9 +91,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/tidy.lock.yml b/.github/workflows/tidy.lock.yml index c398b18b37c..7dd56871208 100644 --- a/.github/workflows/tidy.lock.yml +++ b/.github/workflows/tidy.lock.yml @@ -87,9 +87,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/unbloat-docs.lock.yml b/.github/workflows/unbloat-docs.lock.yml index 00c3bd2263e..cec7056366e 100644 --- a/.github/workflows/unbloat-docs.lock.yml +++ b/.github/workflows/unbloat-docs.lock.yml @@ -86,9 +86,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/workflow-generator.lock.yml b/.github/workflows/workflow-generator.lock.yml index 7601d35e006..d1cb46b664b 100644 --- a/.github/workflows/workflow-generator.lock.yml +++ b/.github/workflows/workflow-generator.lock.yml @@ -71,9 +71,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: "" From 03365d8c5cd1865fff0abed4e91e0e86dbccd5f0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 03:13:13 +0000 Subject: [PATCH 14/20] chore: restore lock files after progress update Agent-Logs-Url: https://github.com/github/gh-aw/sessions/d99aa4d7-b4fc-420a-989f-6df131fc2cee Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/ace-editor.lock.yml | 2 ++ .github/workflows/archie.lock.yml | 2 ++ .github/workflows/brave.lock.yml | 2 ++ .github/workflows/changeset.lock.yml | 2 ++ .github/workflows/ci-doctor.lock.yml | 2 ++ .github/workflows/craft.lock.yml | 2 ++ .github/workflows/dev.lock.yml | 1 + .github/workflows/grumpy-reviewer.lock.yml | 1 + .github/workflows/mergefest.lock.yml | 2 ++ .github/workflows/pdf-summary.lock.yml | 2 ++ .github/workflows/plan.lock.yml | 1 + .github/workflows/poem-bot.lock.yml | 2 ++ .github/workflows/pr-nitpick-reviewer.lock.yml | 1 + .github/workflows/security-review.lock.yml | 1 + .github/workflows/smoke-agent-all-merged.lock.yml | 2 ++ .github/workflows/smoke-agent-all-none.lock.yml | 2 ++ .github/workflows/smoke-agent-public-approved.lock.yml | 2 ++ .github/workflows/smoke-agent-public-none.lock.yml | 2 ++ .github/workflows/smoke-agent-scoped-approved.lock.yml | 2 ++ .github/workflows/smoke-claude.lock.yml | 2 ++ .github/workflows/smoke-codex.lock.yml | 2 ++ .github/workflows/smoke-copilot-arm.lock.yml | 2 ++ .github/workflows/smoke-copilot.lock.yml | 2 ++ .github/workflows/smoke-create-cross-repo-pr.lock.yml | 2 ++ .github/workflows/smoke-gemini.lock.yml | 2 ++ .github/workflows/smoke-multi-pr.lock.yml | 2 ++ .github/workflows/smoke-project.lock.yml | 2 ++ .github/workflows/smoke-service-ports.lock.yml | 3 +++ .github/workflows/smoke-temporary-id.lock.yml | 2 ++ .github/workflows/smoke-test-tools.lock.yml | 2 ++ .github/workflows/smoke-update-cross-repo-pr.lock.yml | 2 ++ .github/workflows/tidy.lock.yml | 2 ++ .github/workflows/unbloat-docs.lock.yml | 2 ++ .github/workflows/workflow-generator.lock.yml | 2 ++ 34 files changed, 64 insertions(+) diff --git a/.github/workflows/ace-editor.lock.yml b/.github/workflows/ace-editor.lock.yml index 90b6f9ff116..6756c8705d0 100644 --- a/.github/workflows/ace-editor.lock.yml +++ b/.github/workflows/ace-editor.lock.yml @@ -65,7 +65,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/archie.lock.yml b/.github/workflows/archie.lock.yml index fb80cdc6f71..051c4e6d598 100644 --- a/.github/workflows/archie.lock.yml +++ b/.github/workflows/archie.lock.yml @@ -81,7 +81,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/brave.lock.yml b/.github/workflows/brave.lock.yml index 1358334ff2d..afa23f63b8e 100644 --- a/.github/workflows/brave.lock.yml +++ b/.github/workflows/brave.lock.yml @@ -71,7 +71,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/changeset.lock.yml b/.github/workflows/changeset.lock.yml index eb1cca9aac4..f1ab8c1feb3 100644 --- a/.github/workflows/changeset.lock.yml +++ b/.github/workflows/changeset.lock.yml @@ -88,7 +88,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: "" diff --git a/.github/workflows/ci-doctor.lock.yml b/.github/workflows/ci-doctor.lock.yml index d688d2b3396..e44b6c121f5 100644 --- a/.github/workflows/ci-doctor.lock.yml +++ b/.github/workflows/ci-doctor.lock.yml @@ -83,7 +83,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/craft.lock.yml b/.github/workflows/craft.lock.yml index 55119e07c96..13ed115bfa7 100644 --- a/.github/workflows/craft.lock.yml +++ b/.github/workflows/craft.lock.yml @@ -67,7 +67,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/dev.lock.yml b/.github/workflows/dev.lock.yml index 59725d5efe4..ee4cdc65463 100644 --- a/.github/workflows/dev.lock.yml +++ b/.github/workflows/dev.lock.yml @@ -89,6 +89,7 @@ jobs: contents: read discussions: write issues: write + pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/grumpy-reviewer.lock.yml b/.github/workflows/grumpy-reviewer.lock.yml index 2a6286cc75a..e5217f41456 100644 --- a/.github/workflows/grumpy-reviewer.lock.yml +++ b/.github/workflows/grumpy-reviewer.lock.yml @@ -82,6 +82,7 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write pull-requests: write outputs: diff --git a/.github/workflows/mergefest.lock.yml b/.github/workflows/mergefest.lock.yml index a8b65568c4f..3a14bd5dd0d 100644 --- a/.github/workflows/mergefest.lock.yml +++ b/.github/workflows/mergefest.lock.yml @@ -67,7 +67,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/pdf-summary.lock.yml b/.github/workflows/pdf-summary.lock.yml index ec0e5ddfffb..7eb3ec2ecdd 100644 --- a/.github/workflows/pdf-summary.lock.yml +++ b/.github/workflows/pdf-summary.lock.yml @@ -95,7 +95,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/plan.lock.yml b/.github/workflows/plan.lock.yml index de09ed34c01..2d06e4e8559 100644 --- a/.github/workflows/plan.lock.yml +++ b/.github/workflows/plan.lock.yml @@ -72,6 +72,7 @@ jobs: contents: read discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/poem-bot.lock.yml b/.github/workflows/poem-bot.lock.yml index e401f410ac9..40d3095a64e 100644 --- a/.github/workflows/poem-bot.lock.yml +++ b/.github/workflows/poem-bot.lock.yml @@ -88,7 +88,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/pr-nitpick-reviewer.lock.yml b/.github/workflows/pr-nitpick-reviewer.lock.yml index 19041c249d8..86c4be38f31 100644 --- a/.github/workflows/pr-nitpick-reviewer.lock.yml +++ b/.github/workflows/pr-nitpick-reviewer.lock.yml @@ -77,6 +77,7 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write pull-requests: write outputs: diff --git a/.github/workflows/security-review.lock.yml b/.github/workflows/security-review.lock.yml index 6e1d1291998..2f84086ec36 100644 --- a/.github/workflows/security-review.lock.yml +++ b/.github/workflows/security-review.lock.yml @@ -79,6 +79,7 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write pull-requests: write outputs: diff --git a/.github/workflows/smoke-agent-all-merged.lock.yml b/.github/workflows/smoke-agent-all-merged.lock.yml index 81249bd4825..7743805dd3e 100644 --- a/.github/workflows/smoke-agent-all-merged.lock.yml +++ b/.github/workflows/smoke-agent-all-merged.lock.yml @@ -89,7 +89,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-all-none.lock.yml b/.github/workflows/smoke-agent-all-none.lock.yml index 13b9da636ad..0aad235151f 100644 --- a/.github/workflows/smoke-agent-all-none.lock.yml +++ b/.github/workflows/smoke-agent-all-none.lock.yml @@ -89,7 +89,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-public-approved.lock.yml b/.github/workflows/smoke-agent-public-approved.lock.yml index 025042bea67..f3551c138e3 100644 --- a/.github/workflows/smoke-agent-public-approved.lock.yml +++ b/.github/workflows/smoke-agent-public-approved.lock.yml @@ -91,7 +91,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-public-none.lock.yml b/.github/workflows/smoke-agent-public-none.lock.yml index b9607f24825..5e40aa1d6c7 100644 --- a/.github/workflows/smoke-agent-public-none.lock.yml +++ b/.github/workflows/smoke-agent-public-none.lock.yml @@ -89,7 +89,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-scoped-approved.lock.yml b/.github/workflows/smoke-agent-scoped-approved.lock.yml index 5dc8a665d01..acb01dd34d2 100644 --- a/.github/workflows/smoke-agent-scoped-approved.lock.yml +++ b/.github/workflows/smoke-agent-scoped-approved.lock.yml @@ -90,7 +90,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 66c79d80107..9720c5a6ff2 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -104,7 +104,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index b7392818a52..e7d0d80289b 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -100,7 +100,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-copilot-arm.lock.yml b/.github/workflows/smoke-copilot-arm.lock.yml index bb182a5a6d7..57a0f01e5f2 100644 --- a/.github/workflows/smoke-copilot-arm.lock.yml +++ b/.github/workflows/smoke-copilot-arm.lock.yml @@ -100,7 +100,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index 9be54f8d768..cca41299cb9 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -95,7 +95,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/smoke-create-cross-repo-pr.lock.yml b/.github/workflows/smoke-create-cross-repo-pr.lock.yml index e8a001e528c..78b8877bcbc 100644 --- a/.github/workflows/smoke-create-cross-repo-pr.lock.yml +++ b/.github/workflows/smoke-create-cross-repo-pr.lock.yml @@ -89,7 +89,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-gemini.lock.yml b/.github/workflows/smoke-gemini.lock.yml index 00c87c7c336..27cfdc9571f 100644 --- a/.github/workflows/smoke-gemini.lock.yml +++ b/.github/workflows/smoke-gemini.lock.yml @@ -93,7 +93,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-multi-pr.lock.yml b/.github/workflows/smoke-multi-pr.lock.yml index 22c205bc806..b99c1b4140f 100644 --- a/.github/workflows/smoke-multi-pr.lock.yml +++ b/.github/workflows/smoke-multi-pr.lock.yml @@ -89,7 +89,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-project.lock.yml b/.github/workflows/smoke-project.lock.yml index f48bf7928a3..6a99e4cc23e 100644 --- a/.github/workflows/smoke-project.lock.yml +++ b/.github/workflows/smoke-project.lock.yml @@ -90,7 +90,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-service-ports.lock.yml b/.github/workflows/smoke-service-ports.lock.yml index 929c7d1ca37..4565acb0813 100644 --- a/.github/workflows/smoke-service-ports.lock.yml +++ b/.github/workflows/smoke-service-ports.lock.yml @@ -80,6 +80,9 @@ jobs: permissions: actions: read contents: read + discussions: write + issues: write + pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/smoke-temporary-id.lock.yml b/.github/workflows/smoke-temporary-id.lock.yml index 883a749f99a..e43cb991678 100644 --- a/.github/workflows/smoke-temporary-id.lock.yml +++ b/.github/workflows/smoke-temporary-id.lock.yml @@ -88,7 +88,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-test-tools.lock.yml b/.github/workflows/smoke-test-tools.lock.yml index 45cf8d7c230..3f5bb05600e 100644 --- a/.github/workflows/smoke-test-tools.lock.yml +++ b/.github/workflows/smoke-test-tools.lock.yml @@ -93,7 +93,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-update-cross-repo-pr.lock.yml b/.github/workflows/smoke-update-cross-repo-pr.lock.yml index d63bc681d5c..5bb15df20c4 100644 --- a/.github/workflows/smoke-update-cross-repo-pr.lock.yml +++ b/.github/workflows/smoke-update-cross-repo-pr.lock.yml @@ -91,7 +91,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/tidy.lock.yml b/.github/workflows/tidy.lock.yml index 7dd56871208..c398b18b37c 100644 --- a/.github/workflows/tidy.lock.yml +++ b/.github/workflows/tidy.lock.yml @@ -87,7 +87,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/unbloat-docs.lock.yml b/.github/workflows/unbloat-docs.lock.yml index cec7056366e..00c3bd2263e 100644 --- a/.github/workflows/unbloat-docs.lock.yml +++ b/.github/workflows/unbloat-docs.lock.yml @@ -86,7 +86,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/workflow-generator.lock.yml b/.github/workflows/workflow-generator.lock.yml index d1cb46b664b..7601d35e006 100644 --- a/.github/workflows/workflow-generator.lock.yml +++ b/.github/workflows/workflow-generator.lock.yml @@ -71,7 +71,9 @@ jobs: permissions: actions: read contents: read + discussions: write issues: write + pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: "" From 470d515a2235ea41e2d13ad8dcf4eeda023b8984 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 03:23:29 +0000 Subject: [PATCH 15/20] refactor: imply status-comment enabled in object form Agent-Logs-Url: https://github.com/github/gh-aw/sessions/d99aa4d7-b4fc-420a-989f-6df131fc2cee Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/parser/schemas/main_workflow_schema.json | 8 ++------ pkg/workflow/activation_permissions_scope_test.go | 1 - pkg/workflow/compiler_safe_outputs.go | 12 ++---------- 3 files changed, 4 insertions(+), 17 deletions(-) diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index b6d3ec452ea..54e351a0f33 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -1894,10 +1894,6 @@ "type": "object", "additionalProperties": false, "properties": { - "enabled": { - "type": "boolean", - "description": "Whether status comments are enabled." - }, "discussions": { "type": "boolean", "description": "Whether status comments are allowed for discussion and discussion_comment triggers." @@ -1905,8 +1901,8 @@ } } ], - "description": "Whether to post status comments (started/completed) on the triggering item. Boolean form enables/disables status comments globally. Object form supports fine-grained control with `enabled` and `discussions` fields. Automatically enabled for slash_command and label_command triggers when not explicitly configured.", - "examples": [true, false, { "enabled": true, "discussions": false }] + "description": "Whether to post status comments (started/completed) on the triggering item. Boolean form enables/disables status comments globally. Object form implies enabled status comments and supports optional `discussions` field to control discussion and discussion_comment triggers. Automatically enabled for slash_command and label_command triggers when not explicitly configured.", + "examples": [true, false, { "discussions": false }] }, "github-token": { "type": "string", diff --git a/pkg/workflow/activation_permissions_scope_test.go b/pkg/workflow/activation_permissions_scope_test.go index 644a13bd119..149ea95a09f 100644 --- a/pkg/workflow/activation_permissions_scope_test.go +++ b/pkg/workflow/activation_permissions_scope_test.go @@ -85,7 +85,6 @@ func TestActivationPermissionsStatusCommentDiscussionsDisabled(t *testing.T) { on: reaction: none status-comment: - enabled: true discussions: false discussion: types: [created] diff --git a/pkg/workflow/compiler_safe_outputs.go b/pkg/workflow/compiler_safe_outputs.go index ae5daff242f..877c43abfeb 100644 --- a/pkg/workflow/compiler_safe_outputs.go +++ b/pkg/workflow/compiler_safe_outputs.go @@ -68,15 +68,6 @@ func (c *Compiler) parseOnSection(frontmatter map[string]any, workflowData *Work workflowData.StatusComment = &statusCommentBool compilerSafeOutputsLog.Printf("status-comment set to: %v", statusCommentBool) } else if statusCommentMap, ok := statusCommentValue.(map[string]any); ok { - statusCommentEnabled := true - if enabledValue, hasEnabled := statusCommentMap["enabled"]; hasEnabled { - enabledBool, ok := enabledValue.(bool) - if !ok { - return fmt.Errorf("status-comment.enabled must be a boolean value, got %T", enabledValue) - } - statusCommentEnabled = enabledBool - } - statusCommentDiscussions := true if discussionsValue, hasDiscussions := statusCommentMap["discussions"]; hasDiscussions { discussionsBool, ok := discussionsValue.(bool) @@ -86,9 +77,10 @@ func (c *Compiler) parseOnSection(frontmatter map[string]any, workflowData *Work statusCommentDiscussions = discussionsBool } + statusCommentEnabled := true workflowData.StatusComment = &statusCommentEnabled workflowData.StatusCommentDiscussions = &statusCommentDiscussions - compilerSafeOutputsLog.Printf("status-comment object set: enabled=%v discussions=%v", statusCommentEnabled, statusCommentDiscussions) + compilerSafeOutputsLog.Printf("status-comment object set: discussions=%v", statusCommentDiscussions) } else { return fmt.Errorf("status-comment must be a boolean or object value, got %T", statusCommentValue) } From 2427213259bccbab3506540e23e531c63701e076 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 03:28:36 +0000 Subject: [PATCH 16/20] chore: plan status-comment issues toggle Agent-Logs-Url: https://github.com/github/gh-aw/sessions/915874e7-3b67-43fa-8510-40b447231a2f Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/ace-editor.lock.yml | 2 -- .github/workflows/archie.lock.yml | 2 -- .github/workflows/brave.lock.yml | 2 -- .github/workflows/changeset.lock.yml | 2 -- .github/workflows/ci-doctor.lock.yml | 2 -- .github/workflows/craft.lock.yml | 2 -- .github/workflows/dev.lock.yml | 1 - .github/workflows/grumpy-reviewer.lock.yml | 1 - .github/workflows/mergefest.lock.yml | 2 -- .github/workflows/pdf-summary.lock.yml | 2 -- .github/workflows/plan.lock.yml | 1 - .github/workflows/poem-bot.lock.yml | 2 -- .github/workflows/pr-nitpick-reviewer.lock.yml | 1 - .github/workflows/security-review.lock.yml | 1 - .github/workflows/smoke-agent-all-merged.lock.yml | 2 -- .github/workflows/smoke-agent-all-none.lock.yml | 2 -- .github/workflows/smoke-agent-public-approved.lock.yml | 2 -- .github/workflows/smoke-agent-public-none.lock.yml | 2 -- .github/workflows/smoke-agent-scoped-approved.lock.yml | 2 -- .github/workflows/smoke-claude.lock.yml | 2 -- .github/workflows/smoke-codex.lock.yml | 2 -- .github/workflows/smoke-copilot-arm.lock.yml | 2 -- .github/workflows/smoke-copilot.lock.yml | 2 -- .github/workflows/smoke-create-cross-repo-pr.lock.yml | 2 -- .github/workflows/smoke-gemini.lock.yml | 2 -- .github/workflows/smoke-multi-pr.lock.yml | 2 -- .github/workflows/smoke-project.lock.yml | 2 -- .github/workflows/smoke-service-ports.lock.yml | 3 --- .github/workflows/smoke-temporary-id.lock.yml | 2 -- .github/workflows/smoke-test-tools.lock.yml | 2 -- .github/workflows/smoke-update-cross-repo-pr.lock.yml | 2 -- .github/workflows/tidy.lock.yml | 2 -- .github/workflows/unbloat-docs.lock.yml | 2 -- .github/workflows/workflow-generator.lock.yml | 2 -- 34 files changed, 64 deletions(-) diff --git a/.github/workflows/ace-editor.lock.yml b/.github/workflows/ace-editor.lock.yml index 6756c8705d0..90b6f9ff116 100644 --- a/.github/workflows/ace-editor.lock.yml +++ b/.github/workflows/ace-editor.lock.yml @@ -65,9 +65,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/archie.lock.yml b/.github/workflows/archie.lock.yml index 051c4e6d598..fb80cdc6f71 100644 --- a/.github/workflows/archie.lock.yml +++ b/.github/workflows/archie.lock.yml @@ -81,9 +81,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/brave.lock.yml b/.github/workflows/brave.lock.yml index afa23f63b8e..1358334ff2d 100644 --- a/.github/workflows/brave.lock.yml +++ b/.github/workflows/brave.lock.yml @@ -71,9 +71,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/changeset.lock.yml b/.github/workflows/changeset.lock.yml index f1ab8c1feb3..eb1cca9aac4 100644 --- a/.github/workflows/changeset.lock.yml +++ b/.github/workflows/changeset.lock.yml @@ -88,9 +88,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: "" diff --git a/.github/workflows/ci-doctor.lock.yml b/.github/workflows/ci-doctor.lock.yml index e44b6c121f5..d688d2b3396 100644 --- a/.github/workflows/ci-doctor.lock.yml +++ b/.github/workflows/ci-doctor.lock.yml @@ -83,9 +83,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/craft.lock.yml b/.github/workflows/craft.lock.yml index 13ed115bfa7..55119e07c96 100644 --- a/.github/workflows/craft.lock.yml +++ b/.github/workflows/craft.lock.yml @@ -67,9 +67,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/dev.lock.yml b/.github/workflows/dev.lock.yml index ee4cdc65463..59725d5efe4 100644 --- a/.github/workflows/dev.lock.yml +++ b/.github/workflows/dev.lock.yml @@ -89,7 +89,6 @@ jobs: contents: read discussions: write issues: write - pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/grumpy-reviewer.lock.yml b/.github/workflows/grumpy-reviewer.lock.yml index e5217f41456..2a6286cc75a 100644 --- a/.github/workflows/grumpy-reviewer.lock.yml +++ b/.github/workflows/grumpy-reviewer.lock.yml @@ -82,7 +82,6 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write pull-requests: write outputs: diff --git a/.github/workflows/mergefest.lock.yml b/.github/workflows/mergefest.lock.yml index 3a14bd5dd0d..a8b65568c4f 100644 --- a/.github/workflows/mergefest.lock.yml +++ b/.github/workflows/mergefest.lock.yml @@ -67,9 +67,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/pdf-summary.lock.yml b/.github/workflows/pdf-summary.lock.yml index 7eb3ec2ecdd..ec0e5ddfffb 100644 --- a/.github/workflows/pdf-summary.lock.yml +++ b/.github/workflows/pdf-summary.lock.yml @@ -95,9 +95,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/plan.lock.yml b/.github/workflows/plan.lock.yml index 2d06e4e8559..de09ed34c01 100644 --- a/.github/workflows/plan.lock.yml +++ b/.github/workflows/plan.lock.yml @@ -72,7 +72,6 @@ jobs: contents: read discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/poem-bot.lock.yml b/.github/workflows/poem-bot.lock.yml index 40d3095a64e..e401f410ac9 100644 --- a/.github/workflows/poem-bot.lock.yml +++ b/.github/workflows/poem-bot.lock.yml @@ -88,9 +88,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/pr-nitpick-reviewer.lock.yml b/.github/workflows/pr-nitpick-reviewer.lock.yml index 86c4be38f31..19041c249d8 100644 --- a/.github/workflows/pr-nitpick-reviewer.lock.yml +++ b/.github/workflows/pr-nitpick-reviewer.lock.yml @@ -77,7 +77,6 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write pull-requests: write outputs: diff --git a/.github/workflows/security-review.lock.yml b/.github/workflows/security-review.lock.yml index 2f84086ec36..6e1d1291998 100644 --- a/.github/workflows/security-review.lock.yml +++ b/.github/workflows/security-review.lock.yml @@ -79,7 +79,6 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write pull-requests: write outputs: diff --git a/.github/workflows/smoke-agent-all-merged.lock.yml b/.github/workflows/smoke-agent-all-merged.lock.yml index 7743805dd3e..81249bd4825 100644 --- a/.github/workflows/smoke-agent-all-merged.lock.yml +++ b/.github/workflows/smoke-agent-all-merged.lock.yml @@ -89,9 +89,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-all-none.lock.yml b/.github/workflows/smoke-agent-all-none.lock.yml index 0aad235151f..13b9da636ad 100644 --- a/.github/workflows/smoke-agent-all-none.lock.yml +++ b/.github/workflows/smoke-agent-all-none.lock.yml @@ -89,9 +89,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-public-approved.lock.yml b/.github/workflows/smoke-agent-public-approved.lock.yml index f3551c138e3..025042bea67 100644 --- a/.github/workflows/smoke-agent-public-approved.lock.yml +++ b/.github/workflows/smoke-agent-public-approved.lock.yml @@ -91,9 +91,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-public-none.lock.yml b/.github/workflows/smoke-agent-public-none.lock.yml index 5e40aa1d6c7..b9607f24825 100644 --- a/.github/workflows/smoke-agent-public-none.lock.yml +++ b/.github/workflows/smoke-agent-public-none.lock.yml @@ -89,9 +89,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-agent-scoped-approved.lock.yml b/.github/workflows/smoke-agent-scoped-approved.lock.yml index acb01dd34d2..5dc8a665d01 100644 --- a/.github/workflows/smoke-agent-scoped-approved.lock.yml +++ b/.github/workflows/smoke-agent-scoped-approved.lock.yml @@ -90,9 +90,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 9720c5a6ff2..66c79d80107 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -104,9 +104,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index e7d0d80289b..b7392818a52 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -100,9 +100,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-copilot-arm.lock.yml b/.github/workflows/smoke-copilot-arm.lock.yml index 57a0f01e5f2..bb182a5a6d7 100644 --- a/.github/workflows/smoke-copilot-arm.lock.yml +++ b/.github/workflows/smoke-copilot-arm.lock.yml @@ -100,9 +100,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index cca41299cb9..9be54f8d768 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -95,9 +95,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/smoke-create-cross-repo-pr.lock.yml b/.github/workflows/smoke-create-cross-repo-pr.lock.yml index 78b8877bcbc..e8a001e528c 100644 --- a/.github/workflows/smoke-create-cross-repo-pr.lock.yml +++ b/.github/workflows/smoke-create-cross-repo-pr.lock.yml @@ -89,9 +89,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-gemini.lock.yml b/.github/workflows/smoke-gemini.lock.yml index 27cfdc9571f..00c87c7c336 100644 --- a/.github/workflows/smoke-gemini.lock.yml +++ b/.github/workflows/smoke-gemini.lock.yml @@ -93,9 +93,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-multi-pr.lock.yml b/.github/workflows/smoke-multi-pr.lock.yml index b99c1b4140f..22c205bc806 100644 --- a/.github/workflows/smoke-multi-pr.lock.yml +++ b/.github/workflows/smoke-multi-pr.lock.yml @@ -89,9 +89,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-project.lock.yml b/.github/workflows/smoke-project.lock.yml index 6a99e4cc23e..f48bf7928a3 100644 --- a/.github/workflows/smoke-project.lock.yml +++ b/.github/workflows/smoke-project.lock.yml @@ -90,9 +90,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-service-ports.lock.yml b/.github/workflows/smoke-service-ports.lock.yml index 4565acb0813..929c7d1ca37 100644 --- a/.github/workflows/smoke-service-ports.lock.yml +++ b/.github/workflows/smoke-service-ports.lock.yml @@ -80,9 +80,6 @@ jobs: permissions: actions: read contents: read - discussions: write - issues: write - pull-requests: write outputs: comment_id: ${{ steps.add-comment.outputs.comment-id }} comment_repo: ${{ steps.add-comment.outputs.comment-repo }} diff --git a/.github/workflows/smoke-temporary-id.lock.yml b/.github/workflows/smoke-temporary-id.lock.yml index e43cb991678..883a749f99a 100644 --- a/.github/workflows/smoke-temporary-id.lock.yml +++ b/.github/workflows/smoke-temporary-id.lock.yml @@ -88,9 +88,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-test-tools.lock.yml b/.github/workflows/smoke-test-tools.lock.yml index 3f5bb05600e..45cf8d7c230 100644 --- a/.github/workflows/smoke-test-tools.lock.yml +++ b/.github/workflows/smoke-test-tools.lock.yml @@ -93,9 +93,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/smoke-update-cross-repo-pr.lock.yml b/.github/workflows/smoke-update-cross-repo-pr.lock.yml index 5bb15df20c4..d63bc681d5c 100644 --- a/.github/workflows/smoke-update-cross-repo-pr.lock.yml +++ b/.github/workflows/smoke-update-cross-repo-pr.lock.yml @@ -91,9 +91,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/tidy.lock.yml b/.github/workflows/tidy.lock.yml index c398b18b37c..7dd56871208 100644 --- a/.github/workflows/tidy.lock.yml +++ b/.github/workflows/tidy.lock.yml @@ -87,9 +87,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/unbloat-docs.lock.yml b/.github/workflows/unbloat-docs.lock.yml index 00c3bd2263e..cec7056366e 100644 --- a/.github/workflows/unbloat-docs.lock.yml +++ b/.github/workflows/unbloat-docs.lock.yml @@ -86,9 +86,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: ${{ steps.add-comment.outputs.comment-id }} diff --git a/.github/workflows/workflow-generator.lock.yml b/.github/workflows/workflow-generator.lock.yml index 7601d35e006..d1cb46b664b 100644 --- a/.github/workflows/workflow-generator.lock.yml +++ b/.github/workflows/workflow-generator.lock.yml @@ -71,9 +71,7 @@ jobs: permissions: actions: read contents: read - discussions: write issues: write - pull-requests: write outputs: body: ${{ steps.sanitized.outputs.body }} comment_id: "" From 1a9ecdee50a368c79bab4140da0d0ed874b33995 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 03:45:08 +0000 Subject: [PATCH 17/20] feat: add status-comment.issues toggle for issue write scoping Agent-Logs-Url: https://github.com/github/gh-aw/sessions/915874e7-3b67-43fa-8510-40b447231a2f Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/parser/schemas/main_workflow_schema.json | 8 ++- .../activation_permissions_scope_test.go | 53 ++++++++++++++- pkg/workflow/compiler_activation_job.go | 64 ++++++++++++++++--- pkg/workflow/compiler_safe_outputs.go | 12 +++- pkg/workflow/compiler_types.go | 1 + pkg/workflow/expression_builder.go | 36 +++++++---- 6 files changed, 148 insertions(+), 26 deletions(-) diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index 54e351a0f33..e754bec83c3 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -1894,6 +1894,10 @@ "type": "object", "additionalProperties": false, "properties": { + "issues": { + "type": "boolean", + "description": "Whether status comments are allowed for issue-related triggers (issues, issue_comment, pull_request, pull_request_review_comment)." + }, "discussions": { "type": "boolean", "description": "Whether status comments are allowed for discussion and discussion_comment triggers." @@ -1901,8 +1905,8 @@ } } ], - "description": "Whether to post status comments (started/completed) on the triggering item. Boolean form enables/disables status comments globally. Object form implies enabled status comments and supports optional `discussions` field to control discussion and discussion_comment triggers. Automatically enabled for slash_command and label_command triggers when not explicitly configured.", - "examples": [true, false, { "discussions": false }] + "description": "Whether to post status comments (started/completed) on the triggering item. Boolean form enables/disables status comments globally. Object form implies enabled status comments and supports optional `issues` and `discussions` fields to control issue-related and discussion-related triggers independently. Automatically enabled for slash_command and label_command triggers when not explicitly configured.", + "examples": [true, false, { "issues": false }, { "discussions": false }, { "issues": false, "discussions": true }] }, "github-token": { "type": "string", diff --git a/pkg/workflow/activation_permissions_scope_test.go b/pkg/workflow/activation_permissions_scope_test.go index 149ea95a09f..4265798e746 100644 --- a/pkg/workflow/activation_permissions_scope_test.go +++ b/pkg/workflow/activation_permissions_scope_test.go @@ -116,7 +116,7 @@ engine: copilot func TestAddActivationInteractionPermissionsMapFallsBackOnInvalidOnYAML(t *testing.T) { permsMap := map[PermissionScope]PermissionLevel{} - addActivationInteractionPermissionsMap(permsMap, "on: [", true, true, true) + addActivationInteractionPermissionsMap(permsMap, "on: [", true, true, true, true) assert.Equal(t, PermissionWrite, permsMap[PermissionIssues], "fallback should include issues:write") assert.Equal(t, PermissionWrite, permsMap[PermissionPullRequests], "fallback should include pull-requests:write") @@ -126,10 +126,59 @@ func TestAddActivationInteractionPermissionsMapFallsBackOnInvalidOnYAML(t *testi func TestAddActivationInteractionPermissionsMapFallbackRespectsStatusCommentDiscussionsToggle(t *testing.T) { permsMap := map[PermissionScope]PermissionLevel{} - addActivationInteractionPermissionsMap(permsMap, "name: no-on-key", false, true, false) + addActivationInteractionPermissionsMap(permsMap, "name: no-on-key", false, true, true, false) assert.Equal(t, PermissionWrite, permsMap[PermissionIssues], "fallback should include issues:write for status comments") assert.Equal(t, PermissionWrite, permsMap[PermissionPullRequests], "fallback should include pull-requests:write for status comments") _, hasDiscussions := permsMap[PermissionDiscussions] assert.False(t, hasDiscussions, "fallback should omit discussions:write when status-comment.discussions is false and reactions are disabled") } + +func TestActivationPermissionsStatusCommentIssuesDisabled(t *testing.T) { + tmpDir := testutil.TempDir(t, "activation-perms-status-comment-issues-disabled") + testFile := filepath.Join(tmpDir, "status-comment-issues-disabled.md") + testContent := `--- +on: + reaction: none + status-comment: + issues: false + issues: + types: [opened] + discussion: + types: [created] +engine: copilot +--- + +# Status comment issues disabled +` + + err := os.WriteFile(testFile, []byte(testContent), 0644) + require.NoError(t, err, "failed to write test workflow") + + compiler := NewCompiler() + err = compiler.CompileWorkflow(testFile) + require.NoError(t, err, "failed to compile workflow") + + lockContent, err := os.ReadFile(stringutil.MarkdownToLockFile(testFile)) + require.NoError(t, err, "failed to read generated lock file") + + activationJobSection := extractJobSection(string(lockContent), string(constants.ActivationJobName)) + assert.Contains(t, activationJobSection, "discussions: write", "activation job should include discussions: write for discussion status comments") + assert.NotContains(t, activationJobSection, "issues: write", "activation job should not include issues: write when status-comment.issues is false and reactions are disabled") + assert.NotContains(t, activationJobSection, "pull-requests: write", "activation job should not include pull-requests: write when status-comment.issues is false and reactions are disabled") + assert.Contains(t, activationJobSection, "github.event_name == 'discussion'", "status comment condition should include discussion events when status-comment.issues is false") + assert.NotContains(t, activationJobSection, "github.event_name == 'issues'", "status comment condition should not include issue events when status-comment.issues is false") + assert.NotContains(t, activationJobSection, "github.event_name == 'issue_comment'", "status comment condition should not include issue_comment events when status-comment.issues is false") +} + +func TestAddActivationInteractionPermissionsMapFallbackRespectsStatusCommentIssuesToggle(t *testing.T) { + permsMap := map[PermissionScope]PermissionLevel{} + + addActivationInteractionPermissionsMap(permsMap, "name: no-on-key", false, true, false, true) + + _, hasIssues := permsMap[PermissionIssues] + _, hasPullRequests := permsMap[PermissionPullRequests] + assert.False(t, hasIssues, "fallback should omit issues:write when status-comment.issues is false and reactions are disabled") + assert.False(t, hasPullRequests, "fallback should omit pull-requests:write when status-comment.issues is false and reactions are disabled") + assert.Equal(t, PermissionWrite, permsMap[PermissionDiscussions], "fallback should include discussions:write when status-comment.discussions is true") +} diff --git a/pkg/workflow/compiler_activation_job.go b/pkg/workflow/compiler_activation_job.go index 86c739e9629..8845e9eacc4 100644 --- a/pkg/workflow/compiler_activation_job.go +++ b/pkg/workflow/compiler_activation_job.go @@ -118,6 +118,7 @@ func (c *Compiler) buildActivationJob(data *WorkflowData, preActivationJobCreate // inserted right after generate_aw_info for fast user feedback. hasReaction := data.AIReaction != "" && data.AIReaction != "none" hasStatusComment := data.StatusComment != nil && *data.StatusComment + statusCommentIncludesIssues := shouldIncludeIssueStatusComments(data) statusCommentIncludesDiscussions := shouldIncludeDiscussionStatusComments(data) hasLabelCommand := len(data.LabelCommand) > 0 // shouldRemoveLabel is true when label-command is active AND remove_label is not disabled @@ -138,7 +139,14 @@ func (c *Compiler) buildActivationJob(data *WorkflowData, preActivationJobCreate // Build the combined permissions needed for all activation steps. // For label removal we only add the scopes required by the enabled events. appPerms := NewPermissions() - addActivationInteractionPermissions(appPerms, data.On, hasReaction, hasStatusComment, statusCommentIncludesDiscussions) + addActivationInteractionPermissions( + appPerms, + data.On, + hasReaction, + hasStatusComment, + statusCommentIncludesIssues, + statusCommentIncludesDiscussions, + ) if shouldRemoveLabel { if slices.Contains(filteredLabelEvents, "issues") || slices.Contains(filteredLabelEvents, "pull_request") { appPerms.Set(PermissionIssues, PermissionWrite) @@ -300,7 +308,7 @@ func (c *Compiler) buildActivationJob(data *WorkflowData, preActivationJobCreate // Add comment with workflow run link if status comments are explicitly enabled if data.StatusComment != nil && *data.StatusComment { - statusCommentCondition := BuildStatusCommentCondition(statusCommentIncludesDiscussions) + statusCommentCondition := BuildStatusCommentCondition(statusCommentIncludesIssues, statusCommentIncludesDiscussions) steps = append(steps, " - name: Add comment with workflow run link\n") steps = append(steps, " id: add-comment\n") @@ -563,7 +571,14 @@ func (c *Compiler) buildActivationJob(data *WorkflowData, preActivationJobCreate permsMap[PermissionActions] = PermissionRead } - addActivationInteractionPermissionsMap(permsMap, data.On, hasReaction, hasStatusComment, statusCommentIncludesDiscussions) + addActivationInteractionPermissionsMap( + permsMap, + data.On, + hasReaction, + hasStatusComment, + statusCommentIncludesIssues, + statusCommentIncludesDiscussions, + ) // Add issues:write permission if lock-for-agent is enabled (even without reaction) if data.LockForAgent { @@ -622,13 +637,21 @@ func addActivationInteractionPermissions( onSection string, hasReaction bool, hasStatusComment bool, + statusCommentIncludesIssues bool, statusCommentIncludesDiscussions bool, ) { if perms == nil { return } permsMap := make(map[PermissionScope]PermissionLevel) - addActivationInteractionPermissionsMap(permsMap, onSection, hasReaction, hasStatusComment, statusCommentIncludesDiscussions) + addActivationInteractionPermissionsMap( + permsMap, + onSection, + hasReaction, + hasStatusComment, + statusCommentIncludesIssues, + statusCommentIncludesDiscussions, + ) for scope, level := range permsMap { perms.Set(scope, level) } @@ -639,6 +662,7 @@ func addActivationInteractionPermissionsMap( onSection string, hasReaction bool, hasStatusComment bool, + statusCommentIncludesIssues bool, statusCommentIncludesDiscussions bool, ) { if !hasReaction && !hasStatusComment { @@ -649,14 +673,26 @@ func addActivationInteractionPermissionsMap( // Real compiled workflows always have a populated trigger section. if onSection == "" { compilerActivationJobLog.Print("Empty on section while computing activation permissions; using broad fallback permissions") - addBroadActivationInteractionPermissions(permsMap, hasReaction, hasStatusComment, statusCommentIncludesDiscussions) + addBroadActivationInteractionPermissions( + permsMap, + hasReaction, + hasStatusComment, + statusCommentIncludesIssues, + statusCommentIncludesDiscussions, + ) return } eventSet, eventSetParsed := activationEventSet(onSection) if !eventSetParsed { compilerActivationJobLog.Print("Unable to parse activation trigger events while computing permissions; using broad fallback permissions") - addBroadActivationInteractionPermissions(permsMap, hasReaction, hasStatusComment, statusCommentIncludesDiscussions) + addBroadActivationInteractionPermissions( + permsMap, + hasReaction, + hasStatusComment, + statusCommentIncludesIssues, + statusCommentIncludesDiscussions, + ) return } @@ -684,7 +720,7 @@ func addActivationInteractionPermissionsMap( if hasStatusComment { // Status comments for issue and pull request related events use issue comment endpoints. - if hasIssuesEvent || hasIssueCommentEvent || hasPullRequestEvent || hasPullRequestReviewCommentEvent { + if statusCommentIncludesIssues && (hasIssuesEvent || hasIssueCommentEvent || hasPullRequestEvent || hasPullRequestReviewCommentEvent) { permsMap[PermissionIssues] = PermissionWrite } // Status comments for discussions use discussion comment APIs and can be disabled via frontmatter. @@ -698,19 +734,29 @@ func addBroadActivationInteractionPermissions( permsMap map[PermissionScope]PermissionLevel, hasReaction bool, hasStatusComment bool, + statusCommentIncludesIssues bool, statusCommentIncludesDiscussions bool, ) { if !hasReaction && !hasStatusComment { return } - permsMap[PermissionIssues] = PermissionWrite - permsMap[PermissionPullRequests] = PermissionWrite + if hasReaction || statusCommentIncludesIssues { + permsMap[PermissionIssues] = PermissionWrite + permsMap[PermissionPullRequests] = PermissionWrite + } if hasReaction || statusCommentIncludesDiscussions { permsMap[PermissionDiscussions] = PermissionWrite } } +func shouldIncludeIssueStatusComments(data *WorkflowData) bool { + if data == nil || data.StatusCommentIssues == nil { + return true + } + return *data.StatusCommentIssues +} + func shouldIncludeDiscussionStatusComments(data *WorkflowData) bool { if data == nil || data.StatusCommentDiscussions == nil { return true diff --git a/pkg/workflow/compiler_safe_outputs.go b/pkg/workflow/compiler_safe_outputs.go index 877c43abfeb..3843ad761ec 100644 --- a/pkg/workflow/compiler_safe_outputs.go +++ b/pkg/workflow/compiler_safe_outputs.go @@ -68,6 +68,15 @@ func (c *Compiler) parseOnSection(frontmatter map[string]any, workflowData *Work workflowData.StatusComment = &statusCommentBool compilerSafeOutputsLog.Printf("status-comment set to: %v", statusCommentBool) } else if statusCommentMap, ok := statusCommentValue.(map[string]any); ok { + statusCommentIssues := true + if issuesValue, hasIssues := statusCommentMap["issues"]; hasIssues { + issuesBool, ok := issuesValue.(bool) + if !ok { + return fmt.Errorf("status-comment.issues must be a boolean value, got %T", issuesValue) + } + statusCommentIssues = issuesBool + } + statusCommentDiscussions := true if discussionsValue, hasDiscussions := statusCommentMap["discussions"]; hasDiscussions { discussionsBool, ok := discussionsValue.(bool) @@ -79,8 +88,9 @@ func (c *Compiler) parseOnSection(frontmatter map[string]any, workflowData *Work statusCommentEnabled := true workflowData.StatusComment = &statusCommentEnabled + workflowData.StatusCommentIssues = &statusCommentIssues workflowData.StatusCommentDiscussions = &statusCommentDiscussions - compilerSafeOutputsLog.Printf("status-comment object set: discussions=%v", statusCommentDiscussions) + compilerSafeOutputsLog.Printf("status-comment object set: issues=%v discussions=%v", statusCommentIssues, statusCommentDiscussions) } else { return fmt.Errorf("status-comment must be a boolean or object value, got %T", statusCommentValue) } diff --git a/pkg/workflow/compiler_types.go b/pkg/workflow/compiler_types.go index 97d0cc3e074..5ff33932433 100644 --- a/pkg/workflow/compiler_types.go +++ b/pkg/workflow/compiler_types.go @@ -436,6 +436,7 @@ type WorkflowData struct { LabelCommandRemoveLabel bool // whether to automatically remove the triggering label (default: true) AIReaction string // AI reaction type like "eyes", "heart", etc. StatusComment *bool // whether to post status comments (default: true when ai-reaction is set, false otherwise) + StatusCommentIssues *bool // whether status comments are allowed on issue/issue_comment/pull_request/pull_request_review_comment triggers (default: true) StatusCommentDiscussions *bool // whether status comments are allowed on discussion/discussion_comment triggers (default: true) ActivationGitHubToken string // custom github token from on.github-token for reactions/comments ActivationGitHubApp *GitHubAppConfig // github app config from on.github-app for minting activation tokens diff --git a/pkg/workflow/expression_builder.go b/pkg/workflow/expression_builder.go index 849f82c361a..98c8829378b 100644 --- a/pkg/workflow/expression_builder.go +++ b/pkg/workflow/expression_builder.go @@ -65,23 +65,30 @@ func BuildAnd(left ConditionNode, right ConditionNode) ConditionNode { // BuildReactionCondition creates a condition tree for the add_reaction job func BuildReactionCondition() ConditionNode { expressionBuilderLog.Print("Building reaction condition for multiple event types") - return buildReactionLikeCondition(true) + return buildReactionLikeCondition(true, true) } // BuildStatusCommentCondition creates a condition tree for activation status comments. +// When includeIssues is false, issue/PR-related events are excluded. // When includeDiscussions is false, discussion and discussion_comment events are excluded. -func BuildStatusCommentCondition(includeDiscussions bool) ConditionNode { - expressionBuilderLog.Printf("Building status comment condition: includeDiscussions=%t", includeDiscussions) - return buildReactionLikeCondition(includeDiscussions) +func BuildStatusCommentCondition(includeIssues bool, includeDiscussions bool) ConditionNode { + expressionBuilderLog.Printf( + "Building status comment condition: includeIssues=%t includeDiscussions=%t", + includeIssues, + includeDiscussions, + ) + return buildReactionLikeCondition(includeIssues, includeDiscussions) } -func buildReactionLikeCondition(includeDiscussions bool) ConditionNode { +func buildReactionLikeCondition(includeIssues bool, includeDiscussions bool) ConditionNode { // Build a list of event types that should trigger reactions/status-comments using expression nodes. var terms []ConditionNode - terms = append(terms, BuildEventTypeEquals("issues")) - terms = append(terms, BuildEventTypeEquals("issue_comment")) - terms = append(terms, BuildEventTypeEquals("pull_request_review_comment")) + if includeIssues { + terms = append(terms, BuildEventTypeEquals("issues")) + terms = append(terms, BuildEventTypeEquals("issue_comment")) + terms = append(terms, BuildEventTypeEquals("pull_request_review_comment")) + } if includeDiscussions { terms = append(terms, BuildEventTypeEquals("discussion")) terms = append(terms, BuildEventTypeEquals("discussion_comment")) @@ -89,13 +96,18 @@ func buildReactionLikeCondition(includeDiscussions bool) ConditionNode { // For pull_request events, we need to ensure it's not from a forked repository // since forked repositories have read-only permissions and cannot add reactions - pullRequestCondition := &AndNode{ - Left: BuildEventTypeEquals("pull_request"), - Right: BuildNotFromFork(), + if includeIssues { + pullRequestCondition := &AndNode{ + Left: BuildEventTypeEquals("pull_request"), + Right: BuildNotFromFork(), + } + terms = append(terms, pullRequestCondition) } - terms = append(terms, pullRequestCondition) expressionBuilderLog.Printf("Created disjunction with %d event type terms", len(terms)) + if len(terms) == 0 { + return BuildBooleanLiteral(false) + } // Use DisjunctionNode to avoid deep nesting return &DisjunctionNode{Terms: terms} From 2a9b73fe0d7eae2e8311aa4352e14dfad88f950a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 03:49:56 +0000 Subject: [PATCH 18/20] fix: validate status-comment targets and trim fallback pr permission Agent-Logs-Url: https://github.com/github/gh-aw/sessions/915874e7-3b67-43fa-8510-40b447231a2f Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../activation_permissions_scope_test.go | 28 ++++++++++++++++++- pkg/workflow/compiler_activation_job.go | 2 ++ pkg/workflow/compiler_safe_outputs.go | 3 ++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/pkg/workflow/activation_permissions_scope_test.go b/pkg/workflow/activation_permissions_scope_test.go index 4265798e746..8413e8644fd 100644 --- a/pkg/workflow/activation_permissions_scope_test.go +++ b/pkg/workflow/activation_permissions_scope_test.go @@ -129,7 +129,8 @@ func TestAddActivationInteractionPermissionsMapFallbackRespectsStatusCommentDisc addActivationInteractionPermissionsMap(permsMap, "name: no-on-key", false, true, true, false) assert.Equal(t, PermissionWrite, permsMap[PermissionIssues], "fallback should include issues:write for status comments") - assert.Equal(t, PermissionWrite, permsMap[PermissionPullRequests], "fallback should include pull-requests:write for status comments") + _, hasPullRequests := permsMap[PermissionPullRequests] + assert.False(t, hasPullRequests, "fallback should omit pull-requests:write when only status comments are enabled") _, hasDiscussions := permsMap[PermissionDiscussions] assert.False(t, hasDiscussions, "fallback should omit discussions:write when status-comment.discussions is false and reactions are disabled") } @@ -182,3 +183,28 @@ func TestAddActivationInteractionPermissionsMapFallbackRespectsStatusCommentIssu assert.False(t, hasPullRequests, "fallback should omit pull-requests:write when status-comment.issues is false and reactions are disabled") assert.Equal(t, PermissionWrite, permsMap[PermissionDiscussions], "fallback should include discussions:write when status-comment.discussions is true") } + +func TestStatusCommentObjectRejectsAllTargetsDisabled(t *testing.T) { + tmpDir := testutil.TempDir(t, "status-comment-object-all-disabled") + testFile := filepath.Join(tmpDir, "status-comment-object-all-disabled.md") + testContent := `--- +on: + status-comment: + issues: false + discussions: false + issues: + types: [opened] +engine: copilot +--- + +# Invalid status comment object +` + + err := os.WriteFile(testFile, []byte(testContent), 0644) + require.NoError(t, err, "failed to write test workflow") + + compiler := NewCompiler() + err = compiler.CompileWorkflow(testFile) + require.Error(t, err, "compilation should fail when status-comment object disables all targets") + assert.Contains(t, err.Error(), "status-comment object requires at least one target to be enabled", "error should explain invalid status-comment object configuration") +} diff --git a/pkg/workflow/compiler_activation_job.go b/pkg/workflow/compiler_activation_job.go index 8845e9eacc4..b70593031fc 100644 --- a/pkg/workflow/compiler_activation_job.go +++ b/pkg/workflow/compiler_activation_job.go @@ -743,6 +743,8 @@ func addBroadActivationInteractionPermissions( if hasReaction || statusCommentIncludesIssues { permsMap[PermissionIssues] = PermissionWrite + } + if hasReaction { permsMap[PermissionPullRequests] = PermissionWrite } if hasReaction || statusCommentIncludesDiscussions { diff --git a/pkg/workflow/compiler_safe_outputs.go b/pkg/workflow/compiler_safe_outputs.go index 3843ad761ec..5a45df6dc66 100644 --- a/pkg/workflow/compiler_safe_outputs.go +++ b/pkg/workflow/compiler_safe_outputs.go @@ -90,6 +90,9 @@ func (c *Compiler) parseOnSection(frontmatter map[string]any, workflowData *Work workflowData.StatusComment = &statusCommentEnabled workflowData.StatusCommentIssues = &statusCommentIssues workflowData.StatusCommentDiscussions = &statusCommentDiscussions + if !statusCommentIssues && !statusCommentDiscussions { + return fmt.Errorf("status-comment object requires at least one target to be enabled (set issues: true or discussions: true, or use status-comment: false)") + } compilerSafeOutputsLog.Printf("status-comment object set: issues=%v discussions=%v", statusCommentIssues, statusCommentDiscussions) } else { return fmt.Errorf("status-comment must be a boolean or object value, got %T", statusCommentValue) From 3d2241651cb79e4274ec945f9f9e25c1b4c80e45 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 04:38:33 +0000 Subject: [PATCH 19/20] feat: add status-comment pull-requests toggle Agent-Logs-Url: https://github.com/github/gh-aw/sessions/45039d61-768a-4aaf-bc99-a51fdcfc6947 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/parser/schemas/main_workflow_schema.json | 10 +++- .../activation_permissions_scope_test.go | 55 ++++++++++++++++++- pkg/workflow/compiler_activation_job.go | 29 +++++++++- pkg/workflow/compiler_safe_outputs.go | 22 +++++++- pkg/workflow/compiler_types.go | 3 +- pkg/workflow/expression_builder.go | 18 +++--- 6 files changed, 117 insertions(+), 20 deletions(-) diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index e754bec83c3..e498389930a 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -1896,7 +1896,11 @@ "properties": { "issues": { "type": "boolean", - "description": "Whether status comments are allowed for issue-related triggers (issues, issue_comment, pull_request, pull_request_review_comment)." + "description": "Whether status comments are allowed for issue triggers (issues, issue_comment)." + }, + "pull-requests": { + "type": "boolean", + "description": "Whether status comments are allowed for pull request triggers (pull_request, pull_request_review_comment)." }, "discussions": { "type": "boolean", @@ -1905,8 +1909,8 @@ } } ], - "description": "Whether to post status comments (started/completed) on the triggering item. Boolean form enables/disables status comments globally. Object form implies enabled status comments and supports optional `issues` and `discussions` fields to control issue-related and discussion-related triggers independently. Automatically enabled for slash_command and label_command triggers when not explicitly configured.", - "examples": [true, false, { "issues": false }, { "discussions": false }, { "issues": false, "discussions": true }] + "description": "Whether to post status comments (started/completed) on the triggering item. Boolean form enables/disables status comments globally. Object form implies enabled status comments and supports optional `issues`, `pull-requests`, and `discussions` fields to control trigger groups independently. Automatically enabled for slash_command and label_command triggers when not explicitly configured.", + "examples": [true, false, { "issues": false }, { "pull-requests": false }, { "discussions": false }, { "issues": false, "pull-requests": true, "discussions": true }] }, "github-token": { "type": "string", diff --git a/pkg/workflow/activation_permissions_scope_test.go b/pkg/workflow/activation_permissions_scope_test.go index 8413e8644fd..f5418e296f0 100644 --- a/pkg/workflow/activation_permissions_scope_test.go +++ b/pkg/workflow/activation_permissions_scope_test.go @@ -116,7 +116,7 @@ engine: copilot func TestAddActivationInteractionPermissionsMapFallsBackOnInvalidOnYAML(t *testing.T) { permsMap := map[PermissionScope]PermissionLevel{} - addActivationInteractionPermissionsMap(permsMap, "on: [", true, true, true, true) + addActivationInteractionPermissionsMap(permsMap, "on: [", true, true, true, true, true) assert.Equal(t, PermissionWrite, permsMap[PermissionIssues], "fallback should include issues:write") assert.Equal(t, PermissionWrite, permsMap[PermissionPullRequests], "fallback should include pull-requests:write") @@ -126,7 +126,7 @@ func TestAddActivationInteractionPermissionsMapFallsBackOnInvalidOnYAML(t *testi func TestAddActivationInteractionPermissionsMapFallbackRespectsStatusCommentDiscussionsToggle(t *testing.T) { permsMap := map[PermissionScope]PermissionLevel{} - addActivationInteractionPermissionsMap(permsMap, "name: no-on-key", false, true, true, false) + addActivationInteractionPermissionsMap(permsMap, "name: no-on-key", false, true, true, true, false) assert.Equal(t, PermissionWrite, permsMap[PermissionIssues], "fallback should include issues:write for status comments") _, hasPullRequests := permsMap[PermissionPullRequests] @@ -175,7 +175,7 @@ engine: copilot func TestAddActivationInteractionPermissionsMapFallbackRespectsStatusCommentIssuesToggle(t *testing.T) { permsMap := map[PermissionScope]PermissionLevel{} - addActivationInteractionPermissionsMap(permsMap, "name: no-on-key", false, true, false, true) + addActivationInteractionPermissionsMap(permsMap, "name: no-on-key", false, true, false, false, true) _, hasIssues := permsMap[PermissionIssues] _, hasPullRequests := permsMap[PermissionPullRequests] @@ -191,6 +191,7 @@ func TestStatusCommentObjectRejectsAllTargetsDisabled(t *testing.T) { on: status-comment: issues: false + pull-requests: false discussions: false issues: types: [opened] @@ -208,3 +209,51 @@ engine: copilot require.Error(t, err, "compilation should fail when status-comment object disables all targets") assert.Contains(t, err.Error(), "status-comment object requires at least one target to be enabled", "error should explain invalid status-comment object configuration") } + +func TestActivationPermissionsStatusCommentPullRequestsDisabled(t *testing.T) { + tmpDir := testutil.TempDir(t, "activation-perms-status-comment-pull-requests-disabled") + testFile := filepath.Join(tmpDir, "status-comment-pull-requests-disabled.md") + testContent := `--- +on: + reaction: none + status-comment: + pull-requests: false + issues: + types: [opened] + pull_request: + types: [opened] +engine: copilot +--- + +# Status comment pull-requests disabled +` + + err := os.WriteFile(testFile, []byte(testContent), 0644) + require.NoError(t, err, "failed to write test workflow") + + compiler := NewCompiler() + err = compiler.CompileWorkflow(testFile) + require.NoError(t, err, "failed to compile workflow") + + lockContent, err := os.ReadFile(stringutil.MarkdownToLockFile(testFile)) + require.NoError(t, err, "failed to read generated lock file") + + activationJobSection := extractJobSection(string(lockContent), string(constants.ActivationJobName)) + assert.Contains(t, activationJobSection, "issues: write", "activation job should include issues: write for issue status comments") + assert.NotContains(t, activationJobSection, "pull-requests: write", "activation job should not include pull-requests: write when reactions are disabled") + assert.Contains(t, activationJobSection, "github.event_name == 'issues'", "status comment condition should include issue events") + assert.Contains(t, activationJobSection, "github.event_name == 'issue_comment'", "status comment condition should include issue_comment events") + assert.NotContains(t, activationJobSection, "github.event_name == 'pull_request_review_comment'", "status comment condition should not include pull_request_review_comment when status-comment.pull-requests is false") +} + +func TestAddActivationInteractionPermissionsMapFallbackRespectsStatusCommentPullRequestsToggle(t *testing.T) { + permsMap := map[PermissionScope]PermissionLevel{} + + addActivationInteractionPermissionsMap(permsMap, "name: no-on-key", false, true, false, false, true) + + _, hasIssues := permsMap[PermissionIssues] + _, hasPullRequests := permsMap[PermissionPullRequests] + assert.False(t, hasIssues, "fallback should omit issues:write when status-comment.issues and status-comment.pull-requests are false and reactions are disabled") + assert.False(t, hasPullRequests, "fallback should omit pull-requests:write when reactions are disabled") + assert.Equal(t, PermissionWrite, permsMap[PermissionDiscussions], "fallback should include discussions:write when status-comment.discussions is true") +} diff --git a/pkg/workflow/compiler_activation_job.go b/pkg/workflow/compiler_activation_job.go index b70593031fc..32738b3bfdc 100644 --- a/pkg/workflow/compiler_activation_job.go +++ b/pkg/workflow/compiler_activation_job.go @@ -119,6 +119,7 @@ func (c *Compiler) buildActivationJob(data *WorkflowData, preActivationJobCreate hasReaction := data.AIReaction != "" && data.AIReaction != "none" hasStatusComment := data.StatusComment != nil && *data.StatusComment statusCommentIncludesIssues := shouldIncludeIssueStatusComments(data) + statusCommentIncludesPullRequests := shouldIncludePullRequestStatusComments(data) statusCommentIncludesDiscussions := shouldIncludeDiscussionStatusComments(data) hasLabelCommand := len(data.LabelCommand) > 0 // shouldRemoveLabel is true when label-command is active AND remove_label is not disabled @@ -145,6 +146,7 @@ func (c *Compiler) buildActivationJob(data *WorkflowData, preActivationJobCreate hasReaction, hasStatusComment, statusCommentIncludesIssues, + statusCommentIncludesPullRequests, statusCommentIncludesDiscussions, ) if shouldRemoveLabel { @@ -308,7 +310,11 @@ func (c *Compiler) buildActivationJob(data *WorkflowData, preActivationJobCreate // Add comment with workflow run link if status comments are explicitly enabled if data.StatusComment != nil && *data.StatusComment { - statusCommentCondition := BuildStatusCommentCondition(statusCommentIncludesIssues, statusCommentIncludesDiscussions) + statusCommentCondition := BuildStatusCommentCondition( + statusCommentIncludesIssues, + statusCommentIncludesPullRequests, + statusCommentIncludesDiscussions, + ) steps = append(steps, " - name: Add comment with workflow run link\n") steps = append(steps, " id: add-comment\n") @@ -577,6 +583,7 @@ func (c *Compiler) buildActivationJob(data *WorkflowData, preActivationJobCreate hasReaction, hasStatusComment, statusCommentIncludesIssues, + statusCommentIncludesPullRequests, statusCommentIncludesDiscussions, ) @@ -638,6 +645,7 @@ func addActivationInteractionPermissions( hasReaction bool, hasStatusComment bool, statusCommentIncludesIssues bool, + statusCommentIncludesPullRequests bool, statusCommentIncludesDiscussions bool, ) { if perms == nil { @@ -650,6 +658,7 @@ func addActivationInteractionPermissions( hasReaction, hasStatusComment, statusCommentIncludesIssues, + statusCommentIncludesPullRequests, statusCommentIncludesDiscussions, ) for scope, level := range permsMap { @@ -663,6 +672,7 @@ func addActivationInteractionPermissionsMap( hasReaction bool, hasStatusComment bool, statusCommentIncludesIssues bool, + statusCommentIncludesPullRequests bool, statusCommentIncludesDiscussions bool, ) { if !hasReaction && !hasStatusComment { @@ -678,6 +688,7 @@ func addActivationInteractionPermissionsMap( hasReaction, hasStatusComment, statusCommentIncludesIssues, + statusCommentIncludesPullRequests, statusCommentIncludesDiscussions, ) return @@ -691,6 +702,7 @@ func addActivationInteractionPermissionsMap( hasReaction, hasStatusComment, statusCommentIncludesIssues, + statusCommentIncludesPullRequests, statusCommentIncludesDiscussions, ) return @@ -720,7 +732,10 @@ func addActivationInteractionPermissionsMap( if hasStatusComment { // Status comments for issue and pull request related events use issue comment endpoints. - if statusCommentIncludesIssues && (hasIssuesEvent || hasIssueCommentEvent || hasPullRequestEvent || hasPullRequestReviewCommentEvent) { + if statusCommentIncludesIssues && (hasIssuesEvent || hasIssueCommentEvent) { + permsMap[PermissionIssues] = PermissionWrite + } + if statusCommentIncludesPullRequests && (hasPullRequestEvent || hasPullRequestReviewCommentEvent) { permsMap[PermissionIssues] = PermissionWrite } // Status comments for discussions use discussion comment APIs and can be disabled via frontmatter. @@ -735,13 +750,14 @@ func addBroadActivationInteractionPermissions( hasReaction bool, hasStatusComment bool, statusCommentIncludesIssues bool, + statusCommentIncludesPullRequests bool, statusCommentIncludesDiscussions bool, ) { if !hasReaction && !hasStatusComment { return } - if hasReaction || statusCommentIncludesIssues { + if hasReaction || statusCommentIncludesIssues || statusCommentIncludesPullRequests { permsMap[PermissionIssues] = PermissionWrite } if hasReaction { @@ -759,6 +775,13 @@ func shouldIncludeIssueStatusComments(data *WorkflowData) bool { return *data.StatusCommentIssues } +func shouldIncludePullRequestStatusComments(data *WorkflowData) bool { + if data == nil || data.StatusCommentPullRequests == nil { + return true + } + return *data.StatusCommentPullRequests +} + func shouldIncludeDiscussionStatusComments(data *WorkflowData) bool { if data == nil || data.StatusCommentDiscussions == nil { return true diff --git a/pkg/workflow/compiler_safe_outputs.go b/pkg/workflow/compiler_safe_outputs.go index 5a45df6dc66..a8ed1654964 100644 --- a/pkg/workflow/compiler_safe_outputs.go +++ b/pkg/workflow/compiler_safe_outputs.go @@ -2,6 +2,7 @@ package workflow import ( "encoding/json" + "errors" "fmt" "maps" "path/filepath" @@ -77,6 +78,15 @@ func (c *Compiler) parseOnSection(frontmatter map[string]any, workflowData *Work statusCommentIssues = issuesBool } + statusCommentPullRequests := true + if pullRequestsValue, hasPullRequests := statusCommentMap["pull-requests"]; hasPullRequests { + pullRequestsBool, ok := pullRequestsValue.(bool) + if !ok { + return fmt.Errorf("status-comment.pull-requests must be a boolean value, got %T", pullRequestsValue) + } + statusCommentPullRequests = pullRequestsBool + } + statusCommentDiscussions := true if discussionsValue, hasDiscussions := statusCommentMap["discussions"]; hasDiscussions { discussionsBool, ok := discussionsValue.(bool) @@ -89,11 +99,17 @@ func (c *Compiler) parseOnSection(frontmatter map[string]any, workflowData *Work statusCommentEnabled := true workflowData.StatusComment = &statusCommentEnabled workflowData.StatusCommentIssues = &statusCommentIssues + workflowData.StatusCommentPullRequests = &statusCommentPullRequests workflowData.StatusCommentDiscussions = &statusCommentDiscussions - if !statusCommentIssues && !statusCommentDiscussions { - return fmt.Errorf("status-comment object requires at least one target to be enabled (set issues: true or discussions: true, or use status-comment: false)") + if !statusCommentIssues && !statusCommentPullRequests && !statusCommentDiscussions { + return errors.New("status-comment object requires at least one target to be enabled (set issues: true, pull-requests: true, or discussions: true, or use status-comment: false)") } - compilerSafeOutputsLog.Printf("status-comment object set: issues=%v discussions=%v", statusCommentIssues, statusCommentDiscussions) + compilerSafeOutputsLog.Printf( + "status-comment object set: issues=%v pullRequests=%v discussions=%v", + statusCommentIssues, + statusCommentPullRequests, + statusCommentDiscussions, + ) } else { return fmt.Errorf("status-comment must be a boolean or object value, got %T", statusCommentValue) } diff --git a/pkg/workflow/compiler_types.go b/pkg/workflow/compiler_types.go index 5ff33932433..a3f683f657e 100644 --- a/pkg/workflow/compiler_types.go +++ b/pkg/workflow/compiler_types.go @@ -436,7 +436,8 @@ type WorkflowData struct { LabelCommandRemoveLabel bool // whether to automatically remove the triggering label (default: true) AIReaction string // AI reaction type like "eyes", "heart", etc. StatusComment *bool // whether to post status comments (default: true when ai-reaction is set, false otherwise) - StatusCommentIssues *bool // whether status comments are allowed on issue/issue_comment/pull_request/pull_request_review_comment triggers (default: true) + StatusCommentIssues *bool // whether status comments are allowed on issues/issue_comment triggers (default: true) + StatusCommentPullRequests *bool // whether status comments are allowed on pull_request/pull_request_review_comment triggers (default: true) StatusCommentDiscussions *bool // whether status comments are allowed on discussion/discussion_comment triggers (default: true) ActivationGitHubToken string // custom github token from on.github-token for reactions/comments ActivationGitHubApp *GitHubAppConfig // github app config from on.github-app for minting activation tokens diff --git a/pkg/workflow/expression_builder.go b/pkg/workflow/expression_builder.go index 98c8829378b..2a07fc1b08d 100644 --- a/pkg/workflow/expression_builder.go +++ b/pkg/workflow/expression_builder.go @@ -65,28 +65,32 @@ func BuildAnd(left ConditionNode, right ConditionNode) ConditionNode { // BuildReactionCondition creates a condition tree for the add_reaction job func BuildReactionCondition() ConditionNode { expressionBuilderLog.Print("Building reaction condition for multiple event types") - return buildReactionLikeCondition(true, true) + return buildReactionLikeCondition(true, true, true) } // BuildStatusCommentCondition creates a condition tree for activation status comments. -// When includeIssues is false, issue/PR-related events are excluded. +// When includeIssues is false, issues and issue_comment events are excluded. +// When includePullRequests is false, pull_request and pull_request_review_comment events are excluded. // When includeDiscussions is false, discussion and discussion_comment events are excluded. -func BuildStatusCommentCondition(includeIssues bool, includeDiscussions bool) ConditionNode { +func BuildStatusCommentCondition(includeIssues bool, includePullRequests bool, includeDiscussions bool) ConditionNode { expressionBuilderLog.Printf( - "Building status comment condition: includeIssues=%t includeDiscussions=%t", + "Building status comment condition: includeIssues=%t includePullRequests=%t includeDiscussions=%t", includeIssues, + includePullRequests, includeDiscussions, ) - return buildReactionLikeCondition(includeIssues, includeDiscussions) + return buildReactionLikeCondition(includeIssues, includePullRequests, includeDiscussions) } -func buildReactionLikeCondition(includeIssues bool, includeDiscussions bool) ConditionNode { +func buildReactionLikeCondition(includeIssues bool, includePullRequests bool, includeDiscussions bool) ConditionNode { // Build a list of event types that should trigger reactions/status-comments using expression nodes. var terms []ConditionNode if includeIssues { terms = append(terms, BuildEventTypeEquals("issues")) terms = append(terms, BuildEventTypeEquals("issue_comment")) + } + if includePullRequests { terms = append(terms, BuildEventTypeEquals("pull_request_review_comment")) } if includeDiscussions { @@ -96,7 +100,7 @@ func buildReactionLikeCondition(includeIssues bool, includeDiscussions bool) Con // For pull_request events, we need to ensure it's not from a forked repository // since forked repositories have read-only permissions and cannot add reactions - if includeIssues { + if includePullRequests { pullRequestCondition := &AndNode{ Left: BuildEventTypeEquals("pull_request"), Right: BuildNotFromFork(), From d57f5ea30755b0ef8434451052122bcef2225f9f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 04:51:58 +0000 Subject: [PATCH 20/20] refactor: tighten status-comment target validation and permission condition Agent-Logs-Url: https://github.com/github/gh-aw/sessions/45039d61-768a-4aaf-bc99-a51fdcfc6947 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/workflow/compiler_activation_job.go | 6 ++---- pkg/workflow/compiler_safe_outputs.go | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/pkg/workflow/compiler_activation_job.go b/pkg/workflow/compiler_activation_job.go index 32738b3bfdc..07a7d70aa50 100644 --- a/pkg/workflow/compiler_activation_job.go +++ b/pkg/workflow/compiler_activation_job.go @@ -732,10 +732,8 @@ func addActivationInteractionPermissionsMap( if hasStatusComment { // Status comments for issue and pull request related events use issue comment endpoints. - if statusCommentIncludesIssues && (hasIssuesEvent || hasIssueCommentEvent) { - permsMap[PermissionIssues] = PermissionWrite - } - if statusCommentIncludesPullRequests && (hasPullRequestEvent || hasPullRequestReviewCommentEvent) { + if (statusCommentIncludesIssues && (hasIssuesEvent || hasIssueCommentEvent)) || + (statusCommentIncludesPullRequests && (hasPullRequestEvent || hasPullRequestReviewCommentEvent)) { permsMap[PermissionIssues] = PermissionWrite } // Status comments for discussions use discussion comment APIs and can be disabled via frontmatter. diff --git a/pkg/workflow/compiler_safe_outputs.go b/pkg/workflow/compiler_safe_outputs.go index a8ed1654964..ebc092ebee9 100644 --- a/pkg/workflow/compiler_safe_outputs.go +++ b/pkg/workflow/compiler_safe_outputs.go @@ -102,7 +102,7 @@ func (c *Compiler) parseOnSection(frontmatter map[string]any, workflowData *Work workflowData.StatusCommentPullRequests = &statusCommentPullRequests workflowData.StatusCommentDiscussions = &statusCommentDiscussions if !statusCommentIssues && !statusCommentPullRequests && !statusCommentDiscussions { - return errors.New("status-comment object requires at least one target to be enabled (set issues: true, pull-requests: true, or discussions: true, or use status-comment: false)") + return errors.New("status-comment object requires at least one target to be enabled (issues, pull-requests, or discussions)") } compilerSafeOutputsLog.Printf( "status-comment object set: issues=%v pullRequests=%v discussions=%v",