From ed77e56cdc1b6d3f7f0787fc6519799ee6942ab4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Feb 2026 01:46:53 +0000 Subject: [PATCH 01/10] Initial plan From e13d0101564cb7d80543b42e8a2144ddbfb7b7f3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Feb 2026 01:51:42 +0000 Subject: [PATCH 02/10] Fix add-comment and hide-comment to not require discussions:write permission unconditionally Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/workflow/add_comment.go | 2 +- pkg/workflow/safe_outputs_permissions.go | 4 +- pkg/workflow/safe_outputs_permissions_test.go | 42 +++++++++++++++++-- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/pkg/workflow/add_comment.go b/pkg/workflow/add_comment.go index ffd52ea953c..b22709fc5f7 100644 --- a/pkg/workflow/add_comment.go +++ b/pkg/workflow/add_comment.go @@ -121,7 +121,7 @@ func (c *Compiler) buildCreateOutputAddCommentJob(data *WorkflowData, mainJobNam MainJobName: mainJobName, CustomEnvVars: customEnvVars, Script: getAddCommentScript(), - Permissions: NewPermissionsContentsReadIssuesWritePRWriteDiscussionsWrite(), + Permissions: NewPermissionsContentsReadIssuesWritePRWrite(), Outputs: outputs, Condition: jobCondition, Needs: needs, diff --git a/pkg/workflow/safe_outputs_permissions.go b/pkg/workflow/safe_outputs_permissions.go index a8f1faf61be..24295bc6320 100644 --- a/pkg/workflow/safe_outputs_permissions.go +++ b/pkg/workflow/safe_outputs_permissions.go @@ -30,7 +30,7 @@ func computePermissionsForSafeOutputs(safeOutputs *SafeOutputsConfig) *Permissio } if safeOutputs.AddComments != nil { safeOutputsPermissionsLog.Print("Adding permissions for add-comment") - permissions.Merge(NewPermissionsContentsReadIssuesWritePRWriteDiscussionsWrite()) + permissions.Merge(NewPermissionsContentsReadIssuesWritePRWrite()) } if safeOutputs.CloseIssues != nil { safeOutputsPermissionsLog.Print("Adding permissions for close-issue") @@ -97,7 +97,7 @@ func computePermissionsForSafeOutputs(safeOutputs *SafeOutputsConfig) *Permissio } if safeOutputs.HideComment != nil { safeOutputsPermissionsLog.Print("Adding permissions for hide-comment") - permissions.Merge(NewPermissionsContentsReadIssuesWritePRWriteDiscussionsWrite()) + permissions.Merge(NewPermissionsContentsReadIssuesWritePRWrite()) } if safeOutputs.DispatchWorkflow != nil { safeOutputsPermissionsLog.Print("Adding permissions for dispatch-workflow") diff --git a/pkg/workflow/safe_outputs_permissions_test.go b/pkg/workflow/safe_outputs_permissions_test.go index c570e6deb46..d609487c640 100644 --- a/pkg/workflow/safe_outputs_permissions_test.go +++ b/pkg/workflow/safe_outputs_permissions_test.go @@ -72,7 +72,7 @@ func TestComputePermissionsForSafeOutputs(t *testing.T) { }, }, { - name: "add-comment includes all write permissions including discussions", + name: "add-comment only - no discussions permission", safeOutputs: &SafeOutputsConfig{ AddComments: &AddCommentsConfig{ BaseSafeOutputConfig: BaseSafeOutputConfig{Max: 1}, @@ -82,11 +82,10 @@ func TestComputePermissionsForSafeOutputs(t *testing.T) { PermissionContents: PermissionRead, PermissionIssues: PermissionWrite, PermissionPullRequests: PermissionWrite, - PermissionDiscussions: PermissionWrite, }, }, { - name: "hide-comment includes all write permissions including discussions", + name: "hide-comment only - no discussions permission", safeOutputs: &SafeOutputsConfig{ HideComment: &HideCommentConfig{ BaseSafeOutputConfig: BaseSafeOutputConfig{Max: 1}, @@ -96,7 +95,6 @@ func TestComputePermissionsForSafeOutputs(t *testing.T) { PermissionContents: PermissionRead, PermissionIssues: PermissionWrite, PermissionPullRequests: PermissionWrite, - PermissionDiscussions: PermissionWrite, }, }, { @@ -237,6 +235,42 @@ func TestComputePermissionsForSafeOutputs(t *testing.T) { PermissionContents: PermissionWrite, }, }, + { + name: "add-comment with create-discussion includes discussions permission", + safeOutputs: &SafeOutputsConfig{ + AddComments: &AddCommentsConfig{ + BaseSafeOutputConfig: BaseSafeOutputConfig{Max: 1}, + }, + CreateDiscussions: &CreateDiscussionsConfig{ + BaseSafeOutputConfig: BaseSafeOutputConfig{Max: 1}, + }, + }, + expected: map[PermissionScope]PermissionLevel{ + PermissionContents: PermissionRead, + PermissionIssues: PermissionWrite, + PermissionPullRequests: PermissionWrite, + PermissionDiscussions: PermissionWrite, + }, + }, + { + name: "hide-comment with update-discussion includes discussions permission", + safeOutputs: &SafeOutputsConfig{ + HideComment: &HideCommentConfig{ + BaseSafeOutputConfig: BaseSafeOutputConfig{Max: 1}, + }, + UpdateDiscussions: &UpdateDiscussionsConfig{ + UpdateEntityConfig: UpdateEntityConfig{ + BaseSafeOutputConfig: BaseSafeOutputConfig{Max: 1}, + }, + }, + }, + expected: map[PermissionScope]PermissionLevel{ + PermissionContents: PermissionRead, + PermissionIssues: PermissionWrite, + PermissionPullRequests: PermissionWrite, + PermissionDiscussions: PermissionWrite, + }, + }, { name: "create-code-scanning-alert requires security-events write", safeOutputs: &SafeOutputsConfig{ From 56354f130bc7d5d2fd81562a771dfe6201676207 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Feb 2026 01:54:18 +0000 Subject: [PATCH 03/10] Update tests to reflect removed discussions permission requirement Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/workflow/compiler_safe_outputs_job_test.go | 4 ++-- pkg/workflow/notify_comment_test.go | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/pkg/workflow/compiler_safe_outputs_job_test.go b/pkg/workflow/compiler_safe_outputs_job_test.go index a51c1f32047..0441f3da150 100644 --- a/pkg/workflow/compiler_safe_outputs_job_test.go +++ b/pkg/workflow/compiler_safe_outputs_job_test.go @@ -52,7 +52,7 @@ func TestBuildConsolidatedSafeOutputsJob(t *testing.T) { }, expectedJobName: "safe_outputs", checkPermissions: true, - expectedPerms: []string{"contents: read", "issues: write", "pull-requests: write", "discussions: write"}, + expectedPerms: []string{"contents: read", "issues: write", "pull-requests: write"}, }, { name: "create pull requests with patch", @@ -83,7 +83,7 @@ func TestBuildConsolidatedSafeOutputsJob(t *testing.T) { }, expectedJobName: "safe_outputs", checkPermissions: true, - expectedPerms: []string{"contents: read", "issues: write", "pull-requests: write", "discussions: write"}, + expectedPerms: []string{"contents: read", "issues: write", "pull-requests: write"}, }, { name: "with threat detection enabled", diff --git a/pkg/workflow/notify_comment_test.go b/pkg/workflow/notify_comment_test.go index 892379204a9..2d81cf598bb 100644 --- a/pkg/workflow/notify_comment_test.go +++ b/pkg/workflow/notify_comment_test.go @@ -219,16 +219,13 @@ func TestConclusionJob(t *testing.T) { // When add-comment is configured, it requires issues, pull-requests, and discussions permissions // When only missing_tool/noop is configured, minimal permissions are needed if tt.addCommentConfig { - // add-comment requires full write permissions + // add-comment requires write permissions for issues and PRs (but not discussions unless discussion-related safe outputs are configured) if !strings.Contains(job.Permissions, "issues: write") { t.Error("Expected 'issues: write' permission when add-comment is configured") } if !strings.Contains(job.Permissions, "pull-requests: write") { t.Error("Expected 'pull-requests: write' permission when add-comment is configured") } - if !strings.Contains(job.Permissions, "discussions: write") { - t.Error("Expected 'discussions: write' permission when add-comment is configured") - } } // No need to check for specific permissions when only noop/missing_tool is configured // as they don't require write permissions on their own From 1ba5f92bf1cfbc885726d99f29c522678e1e3b17 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Feb 2026 02:03:08 +0000 Subject: [PATCH 04/10] Recompile workflows to apply permission fixes Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/ai-moderator.lock.yml | 2 -- .github/workflows/archie.lock.yml | 2 -- .github/workflows/brave.lock.yml | 2 -- .github/workflows/ci-doctor.lock.yml | 2 -- .github/workflows/cloclo.lock.yml | 2 -- .github/workflows/contribution-check.lock.yml | 2 -- .github/workflows/craft.lock.yml | 2 -- .github/workflows/daily-assign-issue-to-user.lock.yml | 2 -- .github/workflows/daily-cli-performance.lock.yml | 2 -- .github/workflows/daily-fact.lock.yml | 2 -- .github/workflows/dev-hawk.lock.yml | 2 -- .github/workflows/discussion-task-miner.lock.yml | 2 -- .github/workflows/draft-pr-cleanup.lock.yml | 2 -- .github/workflows/issue-monster.lock.yml | 2 -- .github/workflows/issue-triage-agent.lock.yml | 2 -- .github/workflows/pr-triage-agent.lock.yml | 2 -- .github/workflows/q.lock.yml | 2 -- .github/workflows/refiner.lock.yml | 2 -- .github/workflows/scout.lock.yml | 2 -- .github/workflows/smoke-claude.lock.yml | 2 -- .github/workflows/smoke-codex.lock.yml | 2 -- .github/workflows/smoke-copilot-sdk.lock.yml | 2 -- .github/workflows/smoke-opencode.lock.yml | 2 -- .github/workflows/smoke-project.lock.yml | 2 -- .github/workflows/smoke-temporary-id.lock.yml | 2 -- .github/workflows/smoke-test-tools.lock.yml | 2 -- .github/workflows/sub-issue-closer.lock.yml | 2 -- .github/workflows/technical-doc-writer.lock.yml | 2 -- .github/workflows/unbloat-docs.lock.yml | 2 -- .github/workflows/workflow-health-manager.lock.yml | 2 -- 30 files changed, 60 deletions(-) diff --git a/.github/workflows/ai-moderator.lock.yml b/.github/workflows/ai-moderator.lock.yml index d8b5425059d..ac50515f401 100644 --- a/.github/workflows/ai-moderator.lock.yml +++ b/.github/workflows/ai-moderator.lock.yml @@ -866,7 +866,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1026,7 +1025,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/archie.lock.yml b/.github/workflows/archie.lock.yml index 748f2dbd91a..00caa282957 100644 --- a/.github/workflows/archie.lock.yml +++ b/.github/workflows/archie.lock.yml @@ -848,7 +848,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1119,7 +1118,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/brave.lock.yml b/.github/workflows/brave.lock.yml index 550608718c1..90b23842a72 100644 --- a/.github/workflows/brave.lock.yml +++ b/.github/workflows/brave.lock.yml @@ -840,7 +840,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1108,7 +1107,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/ci-doctor.lock.yml b/.github/workflows/ci-doctor.lock.yml index 4d966720d04..b4139002238 100644 --- a/.github/workflows/ci-doctor.lock.yml +++ b/.github/workflows/ci-doctor.lock.yml @@ -1016,7 +1016,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1275,7 +1274,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/cloclo.lock.yml b/.github/workflows/cloclo.lock.yml index 1d5f1a35ec8..254a3ff0163 100644 --- a/.github/workflows/cloclo.lock.yml +++ b/.github/workflows/cloclo.lock.yml @@ -1172,7 +1172,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write outputs: @@ -1484,7 +1483,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/contribution-check.lock.yml b/.github/workflows/contribution-check.lock.yml index 85f1db559bc..84653dc46d4 100644 --- a/.github/workflows/contribution-check.lock.yml +++ b/.github/workflows/contribution-check.lock.yml @@ -892,7 +892,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1100,7 +1099,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/craft.lock.yml b/.github/workflows/craft.lock.yml index 8ea46f2b1df..f91749789ba 100644 --- a/.github/workflows/craft.lock.yml +++ b/.github/workflows/craft.lock.yml @@ -875,7 +875,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write outputs: @@ -1143,7 +1142,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/daily-assign-issue-to-user.lock.yml b/.github/workflows/daily-assign-issue-to-user.lock.yml index 891f8aaf37a..89e3f7b3023 100644 --- a/.github/workflows/daily-assign-issue-to-user.lock.yml +++ b/.github/workflows/daily-assign-issue-to-user.lock.yml @@ -837,7 +837,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1045,7 +1044,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/daily-cli-performance.lock.yml b/.github/workflows/daily-cli-performance.lock.yml index ba2e87a938e..8839e564751 100644 --- a/.github/workflows/daily-cli-performance.lock.yml +++ b/.github/workflows/daily-cli-performance.lock.yml @@ -1070,7 +1070,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1351,7 +1350,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/daily-fact.lock.yml b/.github/workflows/daily-fact.lock.yml index df3df936db2..3c9ee19780a 100644 --- a/.github/workflows/daily-fact.lock.yml +++ b/.github/workflows/daily-fact.lock.yml @@ -779,7 +779,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -970,7 +969,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/dev-hawk.lock.yml b/.github/workflows/dev-hawk.lock.yml index 1a6b6115ab3..26fd3920a37 100644 --- a/.github/workflows/dev-hawk.lock.yml +++ b/.github/workflows/dev-hawk.lock.yml @@ -907,7 +907,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1147,7 +1146,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/discussion-task-miner.lock.yml b/.github/workflows/discussion-task-miner.lock.yml index b4c31881379..572bf0fe25a 100644 --- a/.github/workflows/discussion-task-miner.lock.yml +++ b/.github/workflows/discussion-task-miner.lock.yml @@ -945,7 +945,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1227,7 +1226,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/draft-pr-cleanup.lock.yml b/.github/workflows/draft-pr-cleanup.lock.yml index e631b352372..2e9b94b6163 100644 --- a/.github/workflows/draft-pr-cleanup.lock.yml +++ b/.github/workflows/draft-pr-cleanup.lock.yml @@ -866,7 +866,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1075,7 +1074,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/issue-monster.lock.yml b/.github/workflows/issue-monster.lock.yml index 6d6a0885bc1..0a87a66fbcd 100644 --- a/.github/workflows/issue-monster.lock.yml +++ b/.github/workflows/issue-monster.lock.yml @@ -862,7 +862,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1128,7 +1127,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/issue-triage-agent.lock.yml b/.github/workflows/issue-triage-agent.lock.yml index c6d03da5dff..5dc42d37663 100644 --- a/.github/workflows/issue-triage-agent.lock.yml +++ b/.github/workflows/issue-triage-agent.lock.yml @@ -804,7 +804,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1011,7 +1010,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/pr-triage-agent.lock.yml b/.github/workflows/pr-triage-agent.lock.yml index 28352f7854e..e0cbd222b83 100644 --- a/.github/workflows/pr-triage-agent.lock.yml +++ b/.github/workflows/pr-triage-agent.lock.yml @@ -949,7 +949,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1227,7 +1226,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/q.lock.yml b/.github/workflows/q.lock.yml index f663c462d65..ddbdcec0d94 100644 --- a/.github/workflows/q.lock.yml +++ b/.github/workflows/q.lock.yml @@ -1020,7 +1020,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write outputs: @@ -1312,7 +1311,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/refiner.lock.yml b/.github/workflows/refiner.lock.yml index bac192a794c..a0c6456b035 100644 --- a/.github/workflows/refiner.lock.yml +++ b/.github/workflows/refiner.lock.yml @@ -881,7 +881,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write outputs: @@ -1136,7 +1135,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/scout.lock.yml b/.github/workflows/scout.lock.yml index 6b2c8cb1d71..7a9f3e33ab6 100644 --- a/.github/workflows/scout.lock.yml +++ b/.github/workflows/scout.lock.yml @@ -1011,7 +1011,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1306,7 +1305,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index ed228c9e25a..10e2cdfe472 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -2082,7 +2082,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write outputs: @@ -2374,7 +2373,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index 3c9b1991b88..50037b2db6d 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -1266,7 +1266,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1533,7 +1532,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/smoke-copilot-sdk.lock.yml b/.github/workflows/smoke-copilot-sdk.lock.yml index a3a0fd9d0f6..41026a1576e 100644 --- a/.github/workflows/smoke-copilot-sdk.lock.yml +++ b/.github/workflows/smoke-copilot-sdk.lock.yml @@ -1170,7 +1170,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1454,7 +1453,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/smoke-opencode.lock.yml b/.github/workflows/smoke-opencode.lock.yml index 3d45c2fa939..0655d14d7fa 100644 --- a/.github/workflows/smoke-opencode.lock.yml +++ b/.github/workflows/smoke-opencode.lock.yml @@ -1489,7 +1489,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1810,7 +1809,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/smoke-project.lock.yml b/.github/workflows/smoke-project.lock.yml index 5f4c68a7602..33732d89df0 100644 --- a/.github/workflows/smoke-project.lock.yml +++ b/.github/workflows/smoke-project.lock.yml @@ -1276,7 +1276,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write outputs: @@ -1566,7 +1565,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/smoke-temporary-id.lock.yml b/.github/workflows/smoke-temporary-id.lock.yml index f7cac5d6e66..be51e4c5410 100644 --- a/.github/workflows/smoke-temporary-id.lock.yml +++ b/.github/workflows/smoke-temporary-id.lock.yml @@ -932,7 +932,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1207,7 +1206,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/smoke-test-tools.lock.yml b/.github/workflows/smoke-test-tools.lock.yml index 67043453878..a57aaf7fe50 100644 --- a/.github/workflows/smoke-test-tools.lock.yml +++ b/.github/workflows/smoke-test-tools.lock.yml @@ -826,7 +826,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1066,7 +1065,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/sub-issue-closer.lock.yml b/.github/workflows/sub-issue-closer.lock.yml index 37b5f5da5a7..0f3636327b4 100644 --- a/.github/workflows/sub-issue-closer.lock.yml +++ b/.github/workflows/sub-issue-closer.lock.yml @@ -879,7 +879,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1087,7 +1086,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/technical-doc-writer.lock.yml b/.github/workflows/technical-doc-writer.lock.yml index 18789653701..d029fb02f52 100644 --- a/.github/workflows/technical-doc-writer.lock.yml +++ b/.github/workflows/technical-doc-writer.lock.yml @@ -960,7 +960,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write outputs: @@ -1184,7 +1183,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/unbloat-docs.lock.yml b/.github/workflows/unbloat-docs.lock.yml index 27317da4d32..f90c0082675 100644 --- a/.github/workflows/unbloat-docs.lock.yml +++ b/.github/workflows/unbloat-docs.lock.yml @@ -1104,7 +1104,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write outputs: @@ -1403,7 +1402,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/workflow-health-manager.lock.yml b/.github/workflows/workflow-health-manager.lock.yml index 00e7a2128d5..c01767240a2 100644 --- a/.github/workflows/workflow-health-manager.lock.yml +++ b/.github/workflows/workflow-health-manager.lock.yml @@ -1009,7 +1009,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1316,7 +1315,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 From ef1b6a56bb524a78ae48d11986a1435a9c91cb49 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Feb 2026 02:18:05 +0000 Subject: [PATCH 05/10] Fix: Only request discussions permission when add-comment has discussion: true Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/workflow/add_comment.go | 10 ++++++++- pkg/workflow/safe_outputs_permissions.go | 21 ++++++++++++++++--- pkg/workflow/safe_outputs_permissions_test.go | 15 +++++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/pkg/workflow/add_comment.go b/pkg/workflow/add_comment.go index b22709fc5f7..6614cc2da5c 100644 --- a/pkg/workflow/add_comment.go +++ b/pkg/workflow/add_comment.go @@ -113,6 +113,14 @@ func (c *Compiler) buildCreateOutputAddCommentJob(data *WorkflowData, mainJobNam needs = append(needs, createPullRequestJobName) } + // Determine permissions based on whether discussions are enabled + var permissions *Permissions + if data.SafeOutputs.AddComments.Discussion != nil && *data.SafeOutputs.AddComments.Discussion { + permissions = NewPermissionsContentsReadIssuesWritePRWriteDiscussionsWrite() + } else { + permissions = NewPermissionsContentsReadIssuesWritePRWrite() + } + // Use the shared builder function to create the job return c.buildSafeOutputJob(data, SafeOutputJobConfig{ JobName: "add_comment", @@ -121,7 +129,7 @@ func (c *Compiler) buildCreateOutputAddCommentJob(data *WorkflowData, mainJobNam MainJobName: mainJobName, CustomEnvVars: customEnvVars, Script: getAddCommentScript(), - Permissions: NewPermissionsContentsReadIssuesWritePRWrite(), + Permissions: permissions, Outputs: outputs, Condition: jobCondition, Needs: needs, diff --git a/pkg/workflow/safe_outputs_permissions.go b/pkg/workflow/safe_outputs_permissions.go index 24295bc6320..43bf6f57812 100644 --- a/pkg/workflow/safe_outputs_permissions.go +++ b/pkg/workflow/safe_outputs_permissions.go @@ -29,8 +29,14 @@ func computePermissionsForSafeOutputs(safeOutputs *SafeOutputsConfig) *Permissio permissions.Merge(NewPermissionsContentsReadIssuesWriteDiscussionsWrite()) } if safeOutputs.AddComments != nil { - safeOutputsPermissionsLog.Print("Adding permissions for add-comment") - permissions.Merge(NewPermissionsContentsReadIssuesWritePRWrite()) + // Check if add-comment is configured to target discussions + if safeOutputs.AddComments.Discussion != nil && *safeOutputs.AddComments.Discussion { + safeOutputsPermissionsLog.Print("Adding permissions for add-comment (with discussions support)") + permissions.Merge(NewPermissionsContentsReadIssuesWritePRWriteDiscussionsWrite()) + } else { + safeOutputsPermissionsLog.Print("Adding permissions for add-comment") + permissions.Merge(NewPermissionsContentsReadIssuesWritePRWrite()) + } } if safeOutputs.CloseIssues != nil { safeOutputsPermissionsLog.Print("Adding permissions for close-issue") @@ -97,7 +103,16 @@ func computePermissionsForSafeOutputs(safeOutputs *SafeOutputsConfig) *Permissio } if safeOutputs.HideComment != nil { safeOutputsPermissionsLog.Print("Adding permissions for hide-comment") - permissions.Merge(NewPermissionsContentsReadIssuesWritePRWrite()) + // hide-comment needs discussions permission only if discussion-related safe outputs are configured + // (since it can only hide discussion comments if the agent can interact with discussions) + if safeOutputs.CreateDiscussions != nil || safeOutputs.CloseDiscussions != nil || + safeOutputs.UpdateDiscussions != nil || (safeOutputs.AddComments != nil && + safeOutputs.AddComments.Discussion != nil && *safeOutputs.AddComments.Discussion) { + safeOutputsPermissionsLog.Print("Adding discussions permission for hide-comment (discussion safe outputs configured)") + permissions.Merge(NewPermissionsContentsReadIssuesWritePRWriteDiscussionsWrite()) + } else { + permissions.Merge(NewPermissionsContentsReadIssuesWritePRWrite()) + } } if safeOutputs.DispatchWorkflow != nil { safeOutputsPermissionsLog.Print("Adding permissions for dispatch-workflow") diff --git a/pkg/workflow/safe_outputs_permissions_test.go b/pkg/workflow/safe_outputs_permissions_test.go index d609487c640..68862d48c59 100644 --- a/pkg/workflow/safe_outputs_permissions_test.go +++ b/pkg/workflow/safe_outputs_permissions_test.go @@ -84,6 +84,21 @@ func TestComputePermissionsForSafeOutputs(t *testing.T) { PermissionPullRequests: PermissionWrite, }, }, + { + name: "add-comment with discussion: true requires discussions permission", + safeOutputs: &SafeOutputsConfig{ + AddComments: &AddCommentsConfig{ + BaseSafeOutputConfig: BaseSafeOutputConfig{Max: 1}, + Discussion: ptrBool(true), + }, + }, + expected: map[PermissionScope]PermissionLevel{ + PermissionContents: PermissionRead, + PermissionIssues: PermissionWrite, + PermissionPullRequests: PermissionWrite, + PermissionDiscussions: PermissionWrite, + }, + }, { name: "hide-comment only - no discussions permission", safeOutputs: &SafeOutputsConfig{ From a2d255f913cc67fcba12f0aaeb73fa222fd5fe3f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Feb 2026 02:35:21 +0000 Subject: [PATCH 06/10] Change discussion field default to true, allow false to opt-out Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/archie.lock.yml | 2 ++ .github/workflows/brave.lock.yml | 2 ++ .github/workflows/ci-doctor.lock.yml | 2 ++ .github/workflows/cloclo.lock.yml | 2 ++ .github/workflows/contribution-check.lock.yml | 2 ++ .github/workflows/craft.lock.yml | 2 ++ .../daily-assign-issue-to-user.lock.yml | 2 ++ .../workflows/daily-cli-performance.lock.yml | 2 ++ .github/workflows/daily-fact.lock.yml | 2 ++ .github/workflows/dev-hawk.lock.yml | 2 ++ .../workflows/discussion-task-miner.lock.yml | 2 ++ .github/workflows/draft-pr-cleanup.lock.yml | 2 ++ .github/workflows/issue-monster.lock.yml | 2 ++ .github/workflows/issue-triage-agent.lock.yml | 2 ++ .github/workflows/pr-triage-agent.lock.yml | 2 ++ .github/workflows/q.lock.yml | 2 ++ .github/workflows/refiner.lock.yml | 2 ++ .github/workflows/scout.lock.yml | 2 ++ .github/workflows/smoke-claude.lock.yml | 2 ++ .github/workflows/smoke-codex.lock.yml | 2 ++ .github/workflows/smoke-copilot-sdk.lock.yml | 2 ++ .github/workflows/smoke-opencode.lock.yml | 2 ++ .github/workflows/smoke-project.lock.yml | 2 ++ .github/workflows/smoke-temporary-id.lock.yml | 2 ++ .github/workflows/smoke-test-tools.lock.yml | 2 ++ .github/workflows/sub-issue-closer.lock.yml | 2 ++ .github/workflows/technical-doc-writer.lock.yml | 2 ++ .github/workflows/unbloat-docs.lock.yml | 2 ++ .../workflows/workflow-health-manager.lock.yml | 2 ++ pkg/parser/schemas/main_workflow_schema.json | 5 ++--- pkg/workflow/add_comment.go | 15 +++++---------- pkg/workflow/compiler_safe_outputs_job_test.go | 4 ++-- pkg/workflow/notify_comment_test.go | 5 ++++- pkg/workflow/safe_outputs_permissions.go | 9 +++++---- pkg/workflow/safe_outputs_permissions_test.go | 17 ++++++++++++++++- 35 files changed, 92 insertions(+), 21 deletions(-) diff --git a/.github/workflows/archie.lock.yml b/.github/workflows/archie.lock.yml index 00caa282957..748f2dbd91a 100644 --- a/.github/workflows/archie.lock.yml +++ b/.github/workflows/archie.lock.yml @@ -848,6 +848,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -1118,6 +1119,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/brave.lock.yml b/.github/workflows/brave.lock.yml index 90b23842a72..550608718c1 100644 --- a/.github/workflows/brave.lock.yml +++ b/.github/workflows/brave.lock.yml @@ -840,6 +840,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -1107,6 +1108,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/ci-doctor.lock.yml b/.github/workflows/ci-doctor.lock.yml index b4139002238..4d966720d04 100644 --- a/.github/workflows/ci-doctor.lock.yml +++ b/.github/workflows/ci-doctor.lock.yml @@ -1016,6 +1016,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -1274,6 +1275,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/cloclo.lock.yml b/.github/workflows/cloclo.lock.yml index 254a3ff0163..1d5f1a35ec8 100644 --- a/.github/workflows/cloclo.lock.yml +++ b/.github/workflows/cloclo.lock.yml @@ -1172,6 +1172,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: write + discussions: write issues: write pull-requests: write outputs: @@ -1483,6 +1484,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: write + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/contribution-check.lock.yml b/.github/workflows/contribution-check.lock.yml index 84653dc46d4..85f1db559bc 100644 --- a/.github/workflows/contribution-check.lock.yml +++ b/.github/workflows/contribution-check.lock.yml @@ -892,6 +892,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -1099,6 +1100,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/craft.lock.yml b/.github/workflows/craft.lock.yml index f91749789ba..8ea46f2b1df 100644 --- a/.github/workflows/craft.lock.yml +++ b/.github/workflows/craft.lock.yml @@ -875,6 +875,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: write + discussions: write issues: write pull-requests: write outputs: @@ -1142,6 +1143,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: write + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/daily-assign-issue-to-user.lock.yml b/.github/workflows/daily-assign-issue-to-user.lock.yml index 89e3f7b3023..891f8aaf37a 100644 --- a/.github/workflows/daily-assign-issue-to-user.lock.yml +++ b/.github/workflows/daily-assign-issue-to-user.lock.yml @@ -837,6 +837,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -1044,6 +1045,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/daily-cli-performance.lock.yml b/.github/workflows/daily-cli-performance.lock.yml index 8839e564751..ba2e87a938e 100644 --- a/.github/workflows/daily-cli-performance.lock.yml +++ b/.github/workflows/daily-cli-performance.lock.yml @@ -1070,6 +1070,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -1350,6 +1351,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/daily-fact.lock.yml b/.github/workflows/daily-fact.lock.yml index 3c9ee19780a..df3df936db2 100644 --- a/.github/workflows/daily-fact.lock.yml +++ b/.github/workflows/daily-fact.lock.yml @@ -779,6 +779,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -969,6 +970,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/dev-hawk.lock.yml b/.github/workflows/dev-hawk.lock.yml index 26fd3920a37..1a6b6115ab3 100644 --- a/.github/workflows/dev-hawk.lock.yml +++ b/.github/workflows/dev-hawk.lock.yml @@ -907,6 +907,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -1146,6 +1147,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/discussion-task-miner.lock.yml b/.github/workflows/discussion-task-miner.lock.yml index 572bf0fe25a..b4c31881379 100644 --- a/.github/workflows/discussion-task-miner.lock.yml +++ b/.github/workflows/discussion-task-miner.lock.yml @@ -945,6 +945,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -1226,6 +1227,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/draft-pr-cleanup.lock.yml b/.github/workflows/draft-pr-cleanup.lock.yml index 2e9b94b6163..e631b352372 100644 --- a/.github/workflows/draft-pr-cleanup.lock.yml +++ b/.github/workflows/draft-pr-cleanup.lock.yml @@ -866,6 +866,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -1074,6 +1075,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/issue-monster.lock.yml b/.github/workflows/issue-monster.lock.yml index 0a87a66fbcd..6d6a0885bc1 100644 --- a/.github/workflows/issue-monster.lock.yml +++ b/.github/workflows/issue-monster.lock.yml @@ -862,6 +862,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -1127,6 +1128,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/issue-triage-agent.lock.yml b/.github/workflows/issue-triage-agent.lock.yml index 5dc42d37663..c6d03da5dff 100644 --- a/.github/workflows/issue-triage-agent.lock.yml +++ b/.github/workflows/issue-triage-agent.lock.yml @@ -804,6 +804,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -1010,6 +1011,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/pr-triage-agent.lock.yml b/.github/workflows/pr-triage-agent.lock.yml index e0cbd222b83..28352f7854e 100644 --- a/.github/workflows/pr-triage-agent.lock.yml +++ b/.github/workflows/pr-triage-agent.lock.yml @@ -949,6 +949,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -1226,6 +1227,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/q.lock.yml b/.github/workflows/q.lock.yml index ddbdcec0d94..f663c462d65 100644 --- a/.github/workflows/q.lock.yml +++ b/.github/workflows/q.lock.yml @@ -1020,6 +1020,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: write + discussions: write issues: write pull-requests: write outputs: @@ -1311,6 +1312,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: write + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/refiner.lock.yml b/.github/workflows/refiner.lock.yml index a0c6456b035..bac192a794c 100644 --- a/.github/workflows/refiner.lock.yml +++ b/.github/workflows/refiner.lock.yml @@ -881,6 +881,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: write + discussions: write issues: write pull-requests: write outputs: @@ -1135,6 +1136,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: write + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/scout.lock.yml b/.github/workflows/scout.lock.yml index 7a9f3e33ab6..6b2c8cb1d71 100644 --- a/.github/workflows/scout.lock.yml +++ b/.github/workflows/scout.lock.yml @@ -1011,6 +1011,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -1305,6 +1306,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 10e2cdfe472..ed228c9e25a 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -2082,6 +2082,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: write + discussions: write issues: write pull-requests: write outputs: @@ -2373,6 +2374,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: write + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index 50037b2db6d..3c9b1991b88 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -1266,6 +1266,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -1532,6 +1533,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/smoke-copilot-sdk.lock.yml b/.github/workflows/smoke-copilot-sdk.lock.yml index 41026a1576e..a3a0fd9d0f6 100644 --- a/.github/workflows/smoke-copilot-sdk.lock.yml +++ b/.github/workflows/smoke-copilot-sdk.lock.yml @@ -1170,6 +1170,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -1453,6 +1454,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/smoke-opencode.lock.yml b/.github/workflows/smoke-opencode.lock.yml index 0655d14d7fa..3d45c2fa939 100644 --- a/.github/workflows/smoke-opencode.lock.yml +++ b/.github/workflows/smoke-opencode.lock.yml @@ -1489,6 +1489,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -1809,6 +1810,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/smoke-project.lock.yml b/.github/workflows/smoke-project.lock.yml index 33732d89df0..5f4c68a7602 100644 --- a/.github/workflows/smoke-project.lock.yml +++ b/.github/workflows/smoke-project.lock.yml @@ -1276,6 +1276,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: write + discussions: write issues: write pull-requests: write outputs: @@ -1565,6 +1566,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: write + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/smoke-temporary-id.lock.yml b/.github/workflows/smoke-temporary-id.lock.yml index be51e4c5410..f7cac5d6e66 100644 --- a/.github/workflows/smoke-temporary-id.lock.yml +++ b/.github/workflows/smoke-temporary-id.lock.yml @@ -932,6 +932,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -1206,6 +1207,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/smoke-test-tools.lock.yml b/.github/workflows/smoke-test-tools.lock.yml index a57aaf7fe50..67043453878 100644 --- a/.github/workflows/smoke-test-tools.lock.yml +++ b/.github/workflows/smoke-test-tools.lock.yml @@ -826,6 +826,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -1065,6 +1066,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/sub-issue-closer.lock.yml b/.github/workflows/sub-issue-closer.lock.yml index 0f3636327b4..37b5f5da5a7 100644 --- a/.github/workflows/sub-issue-closer.lock.yml +++ b/.github/workflows/sub-issue-closer.lock.yml @@ -879,6 +879,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -1086,6 +1087,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/technical-doc-writer.lock.yml b/.github/workflows/technical-doc-writer.lock.yml index d029fb02f52..18789653701 100644 --- a/.github/workflows/technical-doc-writer.lock.yml +++ b/.github/workflows/technical-doc-writer.lock.yml @@ -960,6 +960,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: write + discussions: write issues: write pull-requests: write outputs: @@ -1183,6 +1184,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: write + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/unbloat-docs.lock.yml b/.github/workflows/unbloat-docs.lock.yml index f90c0082675..27317da4d32 100644 --- a/.github/workflows/unbloat-docs.lock.yml +++ b/.github/workflows/unbloat-docs.lock.yml @@ -1104,6 +1104,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: write + discussions: write issues: write pull-requests: write outputs: @@ -1402,6 +1403,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: write + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/workflow-health-manager.lock.yml b/.github/workflows/workflow-health-manager.lock.yml index c01767240a2..00e7a2128d5 100644 --- a/.github/workflows/workflow-health-manager.lock.yml +++ b/.github/workflows/workflow-health-manager.lock.yml @@ -1009,6 +1009,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -1315,6 +1316,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index 9409c952d50..f7c7cc1efd5 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -4802,9 +4802,8 @@ }, "discussion": { "type": "boolean", - "const": true, - "description": "DEPRECATED: This field is deprecated and will be removed in a future version. The add_comment handler now automatically detects whether to target discussions based on context (discussion/discussion_comment events) or the item_number field provided by the agent. Remove this field from your workflow configuration.", - "deprecated": true + "description": "Enable discussion comment support (default: true). Set to false to disable discussions permission and restrict comments to issues and pull requests only.", + "default": true }, "hide-older-comments": { "type": "boolean", diff --git a/pkg/workflow/add_comment.go b/pkg/workflow/add_comment.go index 6614cc2da5c..7442a3a3275 100644 --- a/pkg/workflow/add_comment.go +++ b/pkg/workflow/add_comment.go @@ -20,7 +20,7 @@ type AddCommentsConfig struct { Target string `yaml:"target,omitempty"` // Target for comments: "triggering" (default), "*" (any issue), or explicit issue number TargetRepoSlug string `yaml:"target-repo,omitempty"` // Target repository in format "owner/repo" for cross-repository comments AllowedRepos []string `yaml:"allowed-repos,omitempty"` // List of additional repositories that comments can be added to (additionally to the target-repo) - Discussion *bool `yaml:"discussion,omitempty"` // Target discussion comments instead of issue/PR comments. Must be true if present. + Discussion *bool `yaml:"discussion,omitempty"` // Enable discussion comment support (default: true). Set to false to disable. HideOlderComments bool `yaml:"hide-older-comments,omitempty"` // When true, minimizes/hides all previous comments from the same workflow before creating the new comment AllowedReasons []string `yaml:"allowed-reasons,omitempty"` // List of allowed reasons for hiding older comments (default: all reasons allowed) } @@ -114,11 +114,12 @@ func (c *Compiler) buildCreateOutputAddCommentJob(data *WorkflowData, mainJobNam } // Determine permissions based on whether discussions are enabled + // Default is true (discussion support enabled) unless explicitly set to false var permissions *Permissions - if data.SafeOutputs.AddComments.Discussion != nil && *data.SafeOutputs.AddComments.Discussion { - permissions = NewPermissionsContentsReadIssuesWritePRWriteDiscussionsWrite() - } else { + if data.SafeOutputs.AddComments.Discussion != nil && !*data.SafeOutputs.AddComments.Discussion { permissions = NewPermissionsContentsReadIssuesWritePRWrite() + } else { + permissions = NewPermissionsContentsReadIssuesWritePRWriteDiscussionsWrite() } // Use the shared builder function to create the job @@ -166,11 +167,5 @@ func (c *Compiler) parseCommentsConfig(outputMap map[string]any) *AddCommentsCon return nil // Invalid configuration, return nil to cause validation error } - // Validate discussion field - must be true if present - if config.Discussion != nil && !*config.Discussion { - addCommentLog.Print("Invalid discussion: must be true if present") - return nil // Invalid configuration, return nil to cause validation error - } - return &config } diff --git a/pkg/workflow/compiler_safe_outputs_job_test.go b/pkg/workflow/compiler_safe_outputs_job_test.go index 0441f3da150..a51c1f32047 100644 --- a/pkg/workflow/compiler_safe_outputs_job_test.go +++ b/pkg/workflow/compiler_safe_outputs_job_test.go @@ -52,7 +52,7 @@ func TestBuildConsolidatedSafeOutputsJob(t *testing.T) { }, expectedJobName: "safe_outputs", checkPermissions: true, - expectedPerms: []string{"contents: read", "issues: write", "pull-requests: write"}, + expectedPerms: []string{"contents: read", "issues: write", "pull-requests: write", "discussions: write"}, }, { name: "create pull requests with patch", @@ -83,7 +83,7 @@ func TestBuildConsolidatedSafeOutputsJob(t *testing.T) { }, expectedJobName: "safe_outputs", checkPermissions: true, - expectedPerms: []string{"contents: read", "issues: write", "pull-requests: write"}, + expectedPerms: []string{"contents: read", "issues: write", "pull-requests: write", "discussions: write"}, }, { name: "with threat detection enabled", diff --git a/pkg/workflow/notify_comment_test.go b/pkg/workflow/notify_comment_test.go index 2d81cf598bb..7cd95886b75 100644 --- a/pkg/workflow/notify_comment_test.go +++ b/pkg/workflow/notify_comment_test.go @@ -219,13 +219,16 @@ func TestConclusionJob(t *testing.T) { // When add-comment is configured, it requires issues, pull-requests, and discussions permissions // When only missing_tool/noop is configured, minimal permissions are needed if tt.addCommentConfig { - // add-comment requires write permissions for issues and PRs (but not discussions unless discussion-related safe outputs are configured) + // add-comment requires write permissions for issues, PRs, and discussions (default) if !strings.Contains(job.Permissions, "issues: write") { t.Error("Expected 'issues: write' permission when add-comment is configured") } if !strings.Contains(job.Permissions, "pull-requests: write") { t.Error("Expected 'pull-requests: write' permission when add-comment is configured") } + if !strings.Contains(job.Permissions, "discussions: write") { + t.Error("Expected 'discussions: write' permission when add-comment is configured (default)") + } } // No need to check for specific permissions when only noop/missing_tool is configured // as they don't require write permissions on their own diff --git a/pkg/workflow/safe_outputs_permissions.go b/pkg/workflow/safe_outputs_permissions.go index 43bf6f57812..eb2ea013e7e 100644 --- a/pkg/workflow/safe_outputs_permissions.go +++ b/pkg/workflow/safe_outputs_permissions.go @@ -30,12 +30,13 @@ func computePermissionsForSafeOutputs(safeOutputs *SafeOutputsConfig) *Permissio } if safeOutputs.AddComments != nil { // Check if add-comment is configured to target discussions - if safeOutputs.AddComments.Discussion != nil && *safeOutputs.AddComments.Discussion { + // Default is true (discussion support enabled) unless explicitly set to false + if safeOutputs.AddComments.Discussion != nil && !*safeOutputs.AddComments.Discussion { + safeOutputsPermissionsLog.Print("Adding permissions for add-comment (discussions disabled)") + permissions.Merge(NewPermissionsContentsReadIssuesWritePRWrite()) + } else { safeOutputsPermissionsLog.Print("Adding permissions for add-comment (with discussions support)") permissions.Merge(NewPermissionsContentsReadIssuesWritePRWriteDiscussionsWrite()) - } else { - safeOutputsPermissionsLog.Print("Adding permissions for add-comment") - permissions.Merge(NewPermissionsContentsReadIssuesWritePRWrite()) } } if safeOutputs.CloseIssues != nil { diff --git a/pkg/workflow/safe_outputs_permissions_test.go b/pkg/workflow/safe_outputs_permissions_test.go index 68862d48c59..3e6c380d234 100644 --- a/pkg/workflow/safe_outputs_permissions_test.go +++ b/pkg/workflow/safe_outputs_permissions_test.go @@ -72,7 +72,7 @@ func TestComputePermissionsForSafeOutputs(t *testing.T) { }, }, { - name: "add-comment only - no discussions permission", + name: "add-comment only - includes discussions permission (default)", safeOutputs: &SafeOutputsConfig{ AddComments: &AddCommentsConfig{ BaseSafeOutputConfig: BaseSafeOutputConfig{Max: 1}, @@ -82,6 +82,7 @@ func TestComputePermissionsForSafeOutputs(t *testing.T) { PermissionContents: PermissionRead, PermissionIssues: PermissionWrite, PermissionPullRequests: PermissionWrite, + PermissionDiscussions: PermissionWrite, }, }, { @@ -99,6 +100,20 @@ func TestComputePermissionsForSafeOutputs(t *testing.T) { PermissionDiscussions: PermissionWrite, }, }, + { + name: "add-comment with discussion: false - no discussions permission", + safeOutputs: &SafeOutputsConfig{ + AddComments: &AddCommentsConfig{ + BaseSafeOutputConfig: BaseSafeOutputConfig{Max: 1}, + Discussion: ptrBool(false), + }, + }, + expected: map[PermissionScope]PermissionLevel{ + PermissionContents: PermissionRead, + PermissionIssues: PermissionWrite, + PermissionPullRequests: PermissionWrite, + }, + }, { name: "hide-comment only - no discussions permission", safeOutputs: &SafeOutputsConfig{ From d06ddbe71e4ec33115356cab14ca7203feecdc4c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Feb 2026 02:48:03 +0000 Subject: [PATCH 07/10] Add discussion field to hide-comment with default true Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/ai-moderator.lock.yml | 2 + pkg/parser/schemas/main_workflow_schema.json | 5 ++ pkg/workflow/hide_comment.go | 60 ++++++++----------- pkg/workflow/safe_outputs_permissions.go | 16 +++-- pkg/workflow/safe_outputs_permissions_test.go | 32 +++++++++- 5 files changed, 69 insertions(+), 46 deletions(-) diff --git a/.github/workflows/ai-moderator.lock.yml b/.github/workflows/ai-moderator.lock.yml index ac50515f401..d8b5425059d 100644 --- a/.github/workflows/ai-moderator.lock.yml +++ b/.github/workflows/ai-moderator.lock.yml @@ -866,6 +866,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write outputs: @@ -1025,6 +1026,7 @@ jobs: runs-on: ubuntu-slim permissions: contents: read + discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index f7c7cc1efd5..81fcd97ef01 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -5728,6 +5728,11 @@ "type": "string", "description": "Target repository in format 'owner/repo' for cross-repository comment hiding. Takes precedence over trial target repo settings." }, + "discussion": { + "type": "boolean", + "description": "Enable discussion comment support (default: true). Set to false to disable discussions permission and restrict comment hiding to issues and pull requests only.", + "default": true + }, "allowed-reasons": { "type": "array", "description": "List of allowed reasons for hiding comments. Default: all reasons allowed (spam, abuse, off_topic, outdated, resolved).", diff --git a/pkg/workflow/hide_comment.go b/pkg/workflow/hide_comment.go index 694d0e1581c..88af7803b07 100644 --- a/pkg/workflow/hide_comment.go +++ b/pkg/workflow/hide_comment.go @@ -10,48 +10,36 @@ var hideCommentLog = logger.New("workflow:hide_comment") type HideCommentConfig struct { BaseSafeOutputConfig `yaml:",inline"` SafeOutputTargetConfig `yaml:",inline"` + Discussion *bool `yaml:"discussion,omitempty"` // Enable discussion comment support (default: true). Set to false to disable. AllowedReasons []string `yaml:"allowed-reasons,omitempty"` // List of allowed reasons for hiding comments (default: all reasons allowed) } // parseHideCommentConfig handles hide-comment configuration func (c *Compiler) parseHideCommentConfig(outputMap map[string]any) *HideCommentConfig { + // Check if the key exists + if _, exists := outputMap["hide-comment"]; !exists { + return nil + } + hideCommentLog.Print("Parsing hide-comment configuration") - if configData, exists := outputMap["hide-comment"]; exists { - hideCommentConfig := &HideCommentConfig{} - - if configMap, ok := configData.(map[string]any); ok { - hideCommentLog.Print("Found hide-comment config map") - - // Parse target config (target-repo) with validation - targetConfig, isInvalid := ParseTargetConfig(configMap) - if isInvalid { - return nil // Invalid configuration (e.g., wildcard target-repo), return nil to cause validation error - } - hideCommentConfig.SafeOutputTargetConfig = targetConfig - - // Parse allowed-reasons - if allowedReasons, exists := configMap["allowed-reasons"]; exists { - if reasonsArray, ok := allowedReasons.([]any); ok { - for _, reason := range reasonsArray { - if reasonStr, ok := reason.(string); ok { - hideCommentConfig.AllowedReasons = append(hideCommentConfig.AllowedReasons, reasonStr) - } - } - } - } - - // Parse common base fields with default max of 5 - c.parseBaseSafeOutputConfig(configMap, &hideCommentConfig.BaseSafeOutputConfig, 5) - - hideCommentLog.Printf("Parsed hide-comment config: max=%d, target_repo=%s", - hideCommentConfig.Max, hideCommentConfig.TargetRepoSlug) - } else { - // If configData is nil or not a map, still set the default max - hideCommentConfig.Max = 5 - } - - return hideCommentConfig + + // Unmarshal into typed config struct + var config HideCommentConfig + if err := unmarshalConfig(outputMap, "hide-comment", &config, hideCommentLog); err != nil { + hideCommentLog.Printf("Failed to unmarshal config: %v", err) + // For backward compatibility, handle nil/empty config + config = HideCommentConfig{} + } + + // Set default max if not specified + if config.Max == 0 { + config.Max = 5 + } + + // Validate target-repo (wildcard "*" is not allowed) + if validateTargetRepoSlug(config.TargetRepoSlug, hideCommentLog) { + return nil // Invalid configuration, return nil to cause validation error } - return nil + return &config } diff --git a/pkg/workflow/safe_outputs_permissions.go b/pkg/workflow/safe_outputs_permissions.go index eb2ea013e7e..a131d8e596a 100644 --- a/pkg/workflow/safe_outputs_permissions.go +++ b/pkg/workflow/safe_outputs_permissions.go @@ -103,16 +103,14 @@ func computePermissionsForSafeOutputs(safeOutputs *SafeOutputsConfig) *Permissio permissions.Merge(NewPermissionsContentsReadPRWrite()) } if safeOutputs.HideComment != nil { - safeOutputsPermissionsLog.Print("Adding permissions for hide-comment") - // hide-comment needs discussions permission only if discussion-related safe outputs are configured - // (since it can only hide discussion comments if the agent can interact with discussions) - if safeOutputs.CreateDiscussions != nil || safeOutputs.CloseDiscussions != nil || - safeOutputs.UpdateDiscussions != nil || (safeOutputs.AddComments != nil && - safeOutputs.AddComments.Discussion != nil && *safeOutputs.AddComments.Discussion) { - safeOutputsPermissionsLog.Print("Adding discussions permission for hide-comment (discussion safe outputs configured)") - permissions.Merge(NewPermissionsContentsReadIssuesWritePRWriteDiscussionsWrite()) - } else { + // Check if hide-comment is configured to support discussions + // Default is true (discussion support enabled) unless explicitly set to false + if safeOutputs.HideComment.Discussion != nil && !*safeOutputs.HideComment.Discussion { + safeOutputsPermissionsLog.Print("Adding permissions for hide-comment (discussions disabled)") permissions.Merge(NewPermissionsContentsReadIssuesWritePRWrite()) + } else { + safeOutputsPermissionsLog.Print("Adding permissions for hide-comment (with discussions support)") + permissions.Merge(NewPermissionsContentsReadIssuesWritePRWriteDiscussionsWrite()) } } if safeOutputs.DispatchWorkflow != nil { diff --git a/pkg/workflow/safe_outputs_permissions_test.go b/pkg/workflow/safe_outputs_permissions_test.go index 3e6c380d234..b3f2061d84e 100644 --- a/pkg/workflow/safe_outputs_permissions_test.go +++ b/pkg/workflow/safe_outputs_permissions_test.go @@ -115,12 +115,42 @@ func TestComputePermissionsForSafeOutputs(t *testing.T) { }, }, { - name: "hide-comment only - no discussions permission", + name: "hide-comment only - includes discussions permission (default)", safeOutputs: &SafeOutputsConfig{ HideComment: &HideCommentConfig{ BaseSafeOutputConfig: BaseSafeOutputConfig{Max: 1}, }, }, + expected: map[PermissionScope]PermissionLevel{ + PermissionContents: PermissionRead, + PermissionIssues: PermissionWrite, + PermissionPullRequests: PermissionWrite, + PermissionDiscussions: PermissionWrite, + }, + }, + { + name: "hide-comment with discussion: true - includes discussions permission", + safeOutputs: &SafeOutputsConfig{ + HideComment: &HideCommentConfig{ + BaseSafeOutputConfig: BaseSafeOutputConfig{Max: 1}, + Discussion: ptrBool(true), + }, + }, + expected: map[PermissionScope]PermissionLevel{ + PermissionContents: PermissionRead, + PermissionIssues: PermissionWrite, + PermissionPullRequests: PermissionWrite, + PermissionDiscussions: PermissionWrite, + }, + }, + { + name: "hide-comment with discussion: false - no discussions permission", + safeOutputs: &SafeOutputsConfig{ + HideComment: &HideCommentConfig{ + BaseSafeOutputConfig: BaseSafeOutputConfig{Max: 1}, + Discussion: ptrBool(false), + }, + }, expected: map[PermissionScope]PermissionLevel{ PermissionContents: PermissionRead, PermissionIssues: PermissionWrite, From dcc228cb1acfcafd1c37178c76f5d8086aa34309 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Feb 2026 03:08:27 +0000 Subject: [PATCH 08/10] Change discussion field default back to false (opt-in) Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/ai-moderator.lock.yml | 2 -- .github/workflows/archie.lock.yml | 2 -- .github/workflows/brave.lock.yml | 2 -- .github/workflows/ci-doctor.lock.yml | 2 -- .github/workflows/cloclo.lock.yml | 2 -- .github/workflows/contribution-check.lock.yml | 2 -- .github/workflows/craft.lock.yml | 2 -- .../daily-assign-issue-to-user.lock.yml | 2 -- .../workflows/daily-cli-performance.lock.yml | 2 -- .github/workflows/daily-fact.lock.yml | 2 -- .github/workflows/dev-hawk.lock.yml | 2 -- .../workflows/discussion-task-miner.lock.yml | 2 -- .github/workflows/draft-pr-cleanup.lock.yml | 2 -- .github/workflows/issue-monster.lock.yml | 2 -- .github/workflows/issue-triage-agent.lock.yml | 2 -- .github/workflows/pr-triage-agent.lock.yml | 2 -- .github/workflows/q.lock.yml | 2 -- .github/workflows/refiner.lock.yml | 2 -- .github/workflows/scout.lock.yml | 2 -- .github/workflows/smoke-claude.lock.yml | 2 -- .github/workflows/smoke-codex.lock.yml | 2 -- .github/workflows/smoke-copilot-sdk.lock.yml | 2 -- .github/workflows/smoke-opencode.lock.yml | 2 -- .github/workflows/smoke-project.lock.yml | 2 -- .github/workflows/smoke-temporary-id.lock.yml | 2 -- .github/workflows/smoke-test-tools.lock.yml | 2 -- .github/workflows/sub-issue-closer.lock.yml | 2 -- .../workflows/technical-doc-writer.lock.yml | 2 -- .github/workflows/unbloat-docs.lock.yml | 2 -- .../workflow-health-manager.lock.yml | 2 -- pkg/parser/schemas/main_workflow_schema.json | 8 ++++---- pkg/workflow/add_comment.go | 10 +++++----- .../compiler_safe_outputs_job_test.go | 4 ++-- pkg/workflow/hide_comment.go | 2 +- pkg/workflow/notify_comment_test.go | 5 +---- pkg/workflow/safe_outputs_permissions.go | 20 +++++++++---------- pkg/workflow/safe_outputs_permissions_test.go | 6 ++---- 37 files changed, 25 insertions(+), 90 deletions(-) diff --git a/.github/workflows/ai-moderator.lock.yml b/.github/workflows/ai-moderator.lock.yml index d8b5425059d..ac50515f401 100644 --- a/.github/workflows/ai-moderator.lock.yml +++ b/.github/workflows/ai-moderator.lock.yml @@ -866,7 +866,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1026,7 +1025,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/archie.lock.yml b/.github/workflows/archie.lock.yml index 748f2dbd91a..00caa282957 100644 --- a/.github/workflows/archie.lock.yml +++ b/.github/workflows/archie.lock.yml @@ -848,7 +848,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1119,7 +1118,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/brave.lock.yml b/.github/workflows/brave.lock.yml index 550608718c1..90b23842a72 100644 --- a/.github/workflows/brave.lock.yml +++ b/.github/workflows/brave.lock.yml @@ -840,7 +840,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1108,7 +1107,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/ci-doctor.lock.yml b/.github/workflows/ci-doctor.lock.yml index 4d966720d04..b4139002238 100644 --- a/.github/workflows/ci-doctor.lock.yml +++ b/.github/workflows/ci-doctor.lock.yml @@ -1016,7 +1016,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1275,7 +1274,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/cloclo.lock.yml b/.github/workflows/cloclo.lock.yml index 1d5f1a35ec8..254a3ff0163 100644 --- a/.github/workflows/cloclo.lock.yml +++ b/.github/workflows/cloclo.lock.yml @@ -1172,7 +1172,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write outputs: @@ -1484,7 +1483,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/contribution-check.lock.yml b/.github/workflows/contribution-check.lock.yml index 85f1db559bc..84653dc46d4 100644 --- a/.github/workflows/contribution-check.lock.yml +++ b/.github/workflows/contribution-check.lock.yml @@ -892,7 +892,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1100,7 +1099,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/craft.lock.yml b/.github/workflows/craft.lock.yml index 8ea46f2b1df..f91749789ba 100644 --- a/.github/workflows/craft.lock.yml +++ b/.github/workflows/craft.lock.yml @@ -875,7 +875,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write outputs: @@ -1143,7 +1142,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/daily-assign-issue-to-user.lock.yml b/.github/workflows/daily-assign-issue-to-user.lock.yml index 891f8aaf37a..89e3f7b3023 100644 --- a/.github/workflows/daily-assign-issue-to-user.lock.yml +++ b/.github/workflows/daily-assign-issue-to-user.lock.yml @@ -837,7 +837,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1045,7 +1044,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/daily-cli-performance.lock.yml b/.github/workflows/daily-cli-performance.lock.yml index ba2e87a938e..8839e564751 100644 --- a/.github/workflows/daily-cli-performance.lock.yml +++ b/.github/workflows/daily-cli-performance.lock.yml @@ -1070,7 +1070,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1351,7 +1350,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/daily-fact.lock.yml b/.github/workflows/daily-fact.lock.yml index df3df936db2..3c9ee19780a 100644 --- a/.github/workflows/daily-fact.lock.yml +++ b/.github/workflows/daily-fact.lock.yml @@ -779,7 +779,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -970,7 +969,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/dev-hawk.lock.yml b/.github/workflows/dev-hawk.lock.yml index 1a6b6115ab3..26fd3920a37 100644 --- a/.github/workflows/dev-hawk.lock.yml +++ b/.github/workflows/dev-hawk.lock.yml @@ -907,7 +907,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1147,7 +1146,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/discussion-task-miner.lock.yml b/.github/workflows/discussion-task-miner.lock.yml index b4c31881379..572bf0fe25a 100644 --- a/.github/workflows/discussion-task-miner.lock.yml +++ b/.github/workflows/discussion-task-miner.lock.yml @@ -945,7 +945,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1227,7 +1226,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/draft-pr-cleanup.lock.yml b/.github/workflows/draft-pr-cleanup.lock.yml index e631b352372..2e9b94b6163 100644 --- a/.github/workflows/draft-pr-cleanup.lock.yml +++ b/.github/workflows/draft-pr-cleanup.lock.yml @@ -866,7 +866,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1075,7 +1074,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/issue-monster.lock.yml b/.github/workflows/issue-monster.lock.yml index 6d6a0885bc1..0a87a66fbcd 100644 --- a/.github/workflows/issue-monster.lock.yml +++ b/.github/workflows/issue-monster.lock.yml @@ -862,7 +862,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1128,7 +1127,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/issue-triage-agent.lock.yml b/.github/workflows/issue-triage-agent.lock.yml index c6d03da5dff..5dc42d37663 100644 --- a/.github/workflows/issue-triage-agent.lock.yml +++ b/.github/workflows/issue-triage-agent.lock.yml @@ -804,7 +804,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1011,7 +1010,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/pr-triage-agent.lock.yml b/.github/workflows/pr-triage-agent.lock.yml index 28352f7854e..e0cbd222b83 100644 --- a/.github/workflows/pr-triage-agent.lock.yml +++ b/.github/workflows/pr-triage-agent.lock.yml @@ -949,7 +949,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1227,7 +1226,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/q.lock.yml b/.github/workflows/q.lock.yml index f663c462d65..ddbdcec0d94 100644 --- a/.github/workflows/q.lock.yml +++ b/.github/workflows/q.lock.yml @@ -1020,7 +1020,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write outputs: @@ -1312,7 +1311,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/refiner.lock.yml b/.github/workflows/refiner.lock.yml index bac192a794c..a0c6456b035 100644 --- a/.github/workflows/refiner.lock.yml +++ b/.github/workflows/refiner.lock.yml @@ -881,7 +881,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write outputs: @@ -1136,7 +1135,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/scout.lock.yml b/.github/workflows/scout.lock.yml index 6b2c8cb1d71..7a9f3e33ab6 100644 --- a/.github/workflows/scout.lock.yml +++ b/.github/workflows/scout.lock.yml @@ -1011,7 +1011,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1306,7 +1305,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index ed228c9e25a..10e2cdfe472 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -2082,7 +2082,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write outputs: @@ -2374,7 +2373,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/smoke-codex.lock.yml b/.github/workflows/smoke-codex.lock.yml index 3c9b1991b88..50037b2db6d 100644 --- a/.github/workflows/smoke-codex.lock.yml +++ b/.github/workflows/smoke-codex.lock.yml @@ -1266,7 +1266,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1533,7 +1532,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/smoke-copilot-sdk.lock.yml b/.github/workflows/smoke-copilot-sdk.lock.yml index a3a0fd9d0f6..41026a1576e 100644 --- a/.github/workflows/smoke-copilot-sdk.lock.yml +++ b/.github/workflows/smoke-copilot-sdk.lock.yml @@ -1170,7 +1170,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1454,7 +1453,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/smoke-opencode.lock.yml b/.github/workflows/smoke-opencode.lock.yml index 3d45c2fa939..0655d14d7fa 100644 --- a/.github/workflows/smoke-opencode.lock.yml +++ b/.github/workflows/smoke-opencode.lock.yml @@ -1489,7 +1489,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1810,7 +1809,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/smoke-project.lock.yml b/.github/workflows/smoke-project.lock.yml index 5f4c68a7602..33732d89df0 100644 --- a/.github/workflows/smoke-project.lock.yml +++ b/.github/workflows/smoke-project.lock.yml @@ -1276,7 +1276,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write outputs: @@ -1566,7 +1565,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/smoke-temporary-id.lock.yml b/.github/workflows/smoke-temporary-id.lock.yml index f7cac5d6e66..be51e4c5410 100644 --- a/.github/workflows/smoke-temporary-id.lock.yml +++ b/.github/workflows/smoke-temporary-id.lock.yml @@ -932,7 +932,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1207,7 +1206,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/smoke-test-tools.lock.yml b/.github/workflows/smoke-test-tools.lock.yml index 67043453878..a57aaf7fe50 100644 --- a/.github/workflows/smoke-test-tools.lock.yml +++ b/.github/workflows/smoke-test-tools.lock.yml @@ -826,7 +826,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1066,7 +1065,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/sub-issue-closer.lock.yml b/.github/workflows/sub-issue-closer.lock.yml index 37b5f5da5a7..0f3636327b4 100644 --- a/.github/workflows/sub-issue-closer.lock.yml +++ b/.github/workflows/sub-issue-closer.lock.yml @@ -879,7 +879,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1087,7 +1086,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/technical-doc-writer.lock.yml b/.github/workflows/technical-doc-writer.lock.yml index 18789653701..d029fb02f52 100644 --- a/.github/workflows/technical-doc-writer.lock.yml +++ b/.github/workflows/technical-doc-writer.lock.yml @@ -960,7 +960,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write outputs: @@ -1184,7 +1183,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/unbloat-docs.lock.yml b/.github/workflows/unbloat-docs.lock.yml index 27317da4d32..f90c0082675 100644 --- a/.github/workflows/unbloat-docs.lock.yml +++ b/.github/workflows/unbloat-docs.lock.yml @@ -1104,7 +1104,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write outputs: @@ -1403,7 +1402,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: write - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/.github/workflows/workflow-health-manager.lock.yml b/.github/workflows/workflow-health-manager.lock.yml index 00e7a2128d5..c01767240a2 100644 --- a/.github/workflows/workflow-health-manager.lock.yml +++ b/.github/workflows/workflow-health-manager.lock.yml @@ -1009,7 +1009,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write outputs: @@ -1316,7 +1315,6 @@ jobs: runs-on: ubuntu-slim permissions: contents: read - discussions: write issues: write pull-requests: write timeout-minutes: 15 diff --git a/pkg/parser/schemas/main_workflow_schema.json b/pkg/parser/schemas/main_workflow_schema.json index 81fcd97ef01..60ed14747af 100644 --- a/pkg/parser/schemas/main_workflow_schema.json +++ b/pkg/parser/schemas/main_workflow_schema.json @@ -4802,8 +4802,8 @@ }, "discussion": { "type": "boolean", - "description": "Enable discussion comment support (default: true). Set to false to disable discussions permission and restrict comments to issues and pull requests only.", - "default": true + "description": "Enable discussion comment support. Set to true to enable discussions permission for commenting on discussions.", + "default": false }, "hide-older-comments": { "type": "boolean", @@ -5730,8 +5730,8 @@ }, "discussion": { "type": "boolean", - "description": "Enable discussion comment support (default: true). Set to false to disable discussions permission and restrict comment hiding to issues and pull requests only.", - "default": true + "description": "Enable discussion comment support. Set to true to enable discussions permission for hiding discussion comments.", + "default": false }, "allowed-reasons": { "type": "array", diff --git a/pkg/workflow/add_comment.go b/pkg/workflow/add_comment.go index 7442a3a3275..bd117ba188d 100644 --- a/pkg/workflow/add_comment.go +++ b/pkg/workflow/add_comment.go @@ -20,7 +20,7 @@ type AddCommentsConfig struct { Target string `yaml:"target,omitempty"` // Target for comments: "triggering" (default), "*" (any issue), or explicit issue number TargetRepoSlug string `yaml:"target-repo,omitempty"` // Target repository in format "owner/repo" for cross-repository comments AllowedRepos []string `yaml:"allowed-repos,omitempty"` // List of additional repositories that comments can be added to (additionally to the target-repo) - Discussion *bool `yaml:"discussion,omitempty"` // Enable discussion comment support (default: true). Set to false to disable. + Discussion *bool `yaml:"discussion,omitempty"` // Enable discussion comment support. Set to true to enable discussions permission. HideOlderComments bool `yaml:"hide-older-comments,omitempty"` // When true, minimizes/hides all previous comments from the same workflow before creating the new comment AllowedReasons []string `yaml:"allowed-reasons,omitempty"` // List of allowed reasons for hiding older comments (default: all reasons allowed) } @@ -114,12 +114,12 @@ func (c *Compiler) buildCreateOutputAddCommentJob(data *WorkflowData, mainJobNam } // Determine permissions based on whether discussions are enabled - // Default is true (discussion support enabled) unless explicitly set to false + // Default is false (no discussion permission) unless explicitly set to true var permissions *Permissions - if data.SafeOutputs.AddComments.Discussion != nil && !*data.SafeOutputs.AddComments.Discussion { - permissions = NewPermissionsContentsReadIssuesWritePRWrite() - } else { + if data.SafeOutputs.AddComments.Discussion != nil && *data.SafeOutputs.AddComments.Discussion { permissions = NewPermissionsContentsReadIssuesWritePRWriteDiscussionsWrite() + } else { + permissions = NewPermissionsContentsReadIssuesWritePRWrite() } // Use the shared builder function to create the job diff --git a/pkg/workflow/compiler_safe_outputs_job_test.go b/pkg/workflow/compiler_safe_outputs_job_test.go index a51c1f32047..0441f3da150 100644 --- a/pkg/workflow/compiler_safe_outputs_job_test.go +++ b/pkg/workflow/compiler_safe_outputs_job_test.go @@ -52,7 +52,7 @@ func TestBuildConsolidatedSafeOutputsJob(t *testing.T) { }, expectedJobName: "safe_outputs", checkPermissions: true, - expectedPerms: []string{"contents: read", "issues: write", "pull-requests: write", "discussions: write"}, + expectedPerms: []string{"contents: read", "issues: write", "pull-requests: write"}, }, { name: "create pull requests with patch", @@ -83,7 +83,7 @@ func TestBuildConsolidatedSafeOutputsJob(t *testing.T) { }, expectedJobName: "safe_outputs", checkPermissions: true, - expectedPerms: []string{"contents: read", "issues: write", "pull-requests: write", "discussions: write"}, + expectedPerms: []string{"contents: read", "issues: write", "pull-requests: write"}, }, { name: "with threat detection enabled", diff --git a/pkg/workflow/hide_comment.go b/pkg/workflow/hide_comment.go index 88af7803b07..4514bd91134 100644 --- a/pkg/workflow/hide_comment.go +++ b/pkg/workflow/hide_comment.go @@ -10,7 +10,7 @@ var hideCommentLog = logger.New("workflow:hide_comment") type HideCommentConfig struct { BaseSafeOutputConfig `yaml:",inline"` SafeOutputTargetConfig `yaml:",inline"` - Discussion *bool `yaml:"discussion,omitempty"` // Enable discussion comment support (default: true). Set to false to disable. + Discussion *bool `yaml:"discussion,omitempty"` // Enable discussion comment support. Set to true to enable discussions permission. AllowedReasons []string `yaml:"allowed-reasons,omitempty"` // List of allowed reasons for hiding comments (default: all reasons allowed) } diff --git a/pkg/workflow/notify_comment_test.go b/pkg/workflow/notify_comment_test.go index 7cd95886b75..01d228490b3 100644 --- a/pkg/workflow/notify_comment_test.go +++ b/pkg/workflow/notify_comment_test.go @@ -219,16 +219,13 @@ func TestConclusionJob(t *testing.T) { // When add-comment is configured, it requires issues, pull-requests, and discussions permissions // When only missing_tool/noop is configured, minimal permissions are needed if tt.addCommentConfig { - // add-comment requires write permissions for issues, PRs, and discussions (default) + // add-comment requires write permissions for issues and PRs (discussions only if explicitly enabled) if !strings.Contains(job.Permissions, "issues: write") { t.Error("Expected 'issues: write' permission when add-comment is configured") } if !strings.Contains(job.Permissions, "pull-requests: write") { t.Error("Expected 'pull-requests: write' permission when add-comment is configured") } - if !strings.Contains(job.Permissions, "discussions: write") { - t.Error("Expected 'discussions: write' permission when add-comment is configured (default)") - } } // No need to check for specific permissions when only noop/missing_tool is configured // as they don't require write permissions on their own diff --git a/pkg/workflow/safe_outputs_permissions.go b/pkg/workflow/safe_outputs_permissions.go index a131d8e596a..ffcafc6a9d3 100644 --- a/pkg/workflow/safe_outputs_permissions.go +++ b/pkg/workflow/safe_outputs_permissions.go @@ -30,13 +30,13 @@ func computePermissionsForSafeOutputs(safeOutputs *SafeOutputsConfig) *Permissio } if safeOutputs.AddComments != nil { // Check if add-comment is configured to target discussions - // Default is true (discussion support enabled) unless explicitly set to false - if safeOutputs.AddComments.Discussion != nil && !*safeOutputs.AddComments.Discussion { - safeOutputsPermissionsLog.Print("Adding permissions for add-comment (discussions disabled)") - permissions.Merge(NewPermissionsContentsReadIssuesWritePRWrite()) - } else { + // Default is false (no discussion permission) unless explicitly set to true + if safeOutputs.AddComments.Discussion != nil && *safeOutputs.AddComments.Discussion { safeOutputsPermissionsLog.Print("Adding permissions for add-comment (with discussions support)") permissions.Merge(NewPermissionsContentsReadIssuesWritePRWriteDiscussionsWrite()) + } else { + safeOutputsPermissionsLog.Print("Adding permissions for add-comment") + permissions.Merge(NewPermissionsContentsReadIssuesWritePRWrite()) } } if safeOutputs.CloseIssues != nil { @@ -104,13 +104,13 @@ func computePermissionsForSafeOutputs(safeOutputs *SafeOutputsConfig) *Permissio } if safeOutputs.HideComment != nil { // Check if hide-comment is configured to support discussions - // Default is true (discussion support enabled) unless explicitly set to false - if safeOutputs.HideComment.Discussion != nil && !*safeOutputs.HideComment.Discussion { - safeOutputsPermissionsLog.Print("Adding permissions for hide-comment (discussions disabled)") - permissions.Merge(NewPermissionsContentsReadIssuesWritePRWrite()) - } else { + // Default is false (no discussion permission) unless explicitly set to true + if safeOutputs.HideComment.Discussion != nil && *safeOutputs.HideComment.Discussion { safeOutputsPermissionsLog.Print("Adding permissions for hide-comment (with discussions support)") permissions.Merge(NewPermissionsContentsReadIssuesWritePRWriteDiscussionsWrite()) + } else { + safeOutputsPermissionsLog.Print("Adding permissions for hide-comment") + permissions.Merge(NewPermissionsContentsReadIssuesWritePRWrite()) } } if safeOutputs.DispatchWorkflow != nil { diff --git a/pkg/workflow/safe_outputs_permissions_test.go b/pkg/workflow/safe_outputs_permissions_test.go index b3f2061d84e..b2d9fb336d8 100644 --- a/pkg/workflow/safe_outputs_permissions_test.go +++ b/pkg/workflow/safe_outputs_permissions_test.go @@ -72,7 +72,7 @@ func TestComputePermissionsForSafeOutputs(t *testing.T) { }, }, { - name: "add-comment only - includes discussions permission (default)", + name: "add-comment only - no discussions permission (default)", safeOutputs: &SafeOutputsConfig{ AddComments: &AddCommentsConfig{ BaseSafeOutputConfig: BaseSafeOutputConfig{Max: 1}, @@ -82,7 +82,6 @@ func TestComputePermissionsForSafeOutputs(t *testing.T) { PermissionContents: PermissionRead, PermissionIssues: PermissionWrite, PermissionPullRequests: PermissionWrite, - PermissionDiscussions: PermissionWrite, }, }, { @@ -115,7 +114,7 @@ func TestComputePermissionsForSafeOutputs(t *testing.T) { }, }, { - name: "hide-comment only - includes discussions permission (default)", + name: "hide-comment only - no discussions permission (default)", safeOutputs: &SafeOutputsConfig{ HideComment: &HideCommentConfig{ BaseSafeOutputConfig: BaseSafeOutputConfig{Max: 1}, @@ -125,7 +124,6 @@ func TestComputePermissionsForSafeOutputs(t *testing.T) { PermissionContents: PermissionRead, PermissionIssues: PermissionWrite, PermissionPullRequests: PermissionWrite, - PermissionDiscussions: PermissionWrite, }, }, { From d084f410ed5c8942d1eceee750cee848789b72d9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Feb 2026 03:09:21 +0000 Subject: [PATCH 09/10] Format hide_comment.go whitespace Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/workflow/hide_comment.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/workflow/hide_comment.go b/pkg/workflow/hide_comment.go index 4514bd91134..7ff419740c3 100644 --- a/pkg/workflow/hide_comment.go +++ b/pkg/workflow/hide_comment.go @@ -10,7 +10,7 @@ var hideCommentLog = logger.New("workflow:hide_comment") type HideCommentConfig struct { BaseSafeOutputConfig `yaml:",inline"` SafeOutputTargetConfig `yaml:",inline"` - Discussion *bool `yaml:"discussion,omitempty"` // Enable discussion comment support. Set to true to enable discussions permission. + Discussion *bool `yaml:"discussion,omitempty"` // Enable discussion comment support. Set to true to enable discussions permission. AllowedReasons []string `yaml:"allowed-reasons,omitempty"` // List of allowed reasons for hiding comments (default: all reasons allowed) } From a2e59c4d19cb025e473352cf8bcc61ff5ecd9b65 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 18 Feb 2026 03:17:11 +0000 Subject: [PATCH 10/10] Add comprehensive parsing tests for add-comment and hide-comment fields Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .../add_comment_hide_comment_parsing_test.go | 279 ++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100644 pkg/workflow/add_comment_hide_comment_parsing_test.go diff --git a/pkg/workflow/add_comment_hide_comment_parsing_test.go b/pkg/workflow/add_comment_hide_comment_parsing_test.go new file mode 100644 index 00000000000..d30be443a51 --- /dev/null +++ b/pkg/workflow/add_comment_hide_comment_parsing_test.go @@ -0,0 +1,279 @@ +//go:build !integration + +package workflow + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// TestParseHideCommentConfig tests that all fields are properly parsed +func TestParseHideCommentConfig(t *testing.T) { + tests := []struct { + name string + inputMap map[string]any + expected *HideCommentConfig + isNil bool + }{ + { + name: "all fields parsed correctly", + inputMap: map[string]any{ + "hide-comment": map[string]any{ + "max": 10, + "target-repo": "owner/repo", + "discussion": true, + "allowed-reasons": []any{"spam", "outdated"}, + }, + }, + expected: &HideCommentConfig{ + BaseSafeOutputConfig: BaseSafeOutputConfig{ + Max: 10, + }, + SafeOutputTargetConfig: SafeOutputTargetConfig{ + TargetRepoSlug: "owner/repo", + }, + Discussion: ptrBool(true), + AllowedReasons: []string{"spam", "outdated"}, + }, + }, + { + name: "discussion false is preserved", + inputMap: map[string]any{ + "hide-comment": map[string]any{ + "max": 5, + "discussion": false, + }, + }, + expected: &HideCommentConfig{ + BaseSafeOutputConfig: BaseSafeOutputConfig{ + Max: 5, + }, + Discussion: ptrBool(false), + }, + }, + { + name: "no discussion field defaults to nil", + inputMap: map[string]any{ + "hide-comment": map[string]any{ + "max": 3, + }, + }, + expected: &HideCommentConfig{ + BaseSafeOutputConfig: BaseSafeOutputConfig{ + Max: 3, + }, + Discussion: nil, + }, + }, + { + name: "default max of 5 when not specified", + inputMap: map[string]any{ + "hide-comment": map[string]any{}, + }, + expected: &HideCommentConfig{ + BaseSafeOutputConfig: BaseSafeOutputConfig{ + Max: 5, + }, + }, + }, + { + name: "nil config sets default max", + inputMap: map[string]any{ + "hide-comment": nil, + }, + expected: &HideCommentConfig{ + BaseSafeOutputConfig: BaseSafeOutputConfig{ + Max: 5, + }, + }, + }, + { + name: "wildcard target-repo returns nil", + inputMap: map[string]any{ + "hide-comment": map[string]any{ + "target-repo": "*", + }, + }, + isNil: true, + }, + { + name: "allowed-repos is parsed", + inputMap: map[string]any{ + "hide-comment": map[string]any{ + "allowed-repos": []any{"owner/repo1", "owner/repo2"}, + }, + }, + expected: &HideCommentConfig{ + BaseSafeOutputConfig: BaseSafeOutputConfig{ + Max: 5, + }, + SafeOutputTargetConfig: SafeOutputTargetConfig{ + AllowedRepos: []string{"owner/repo1", "owner/repo2"}, + }, + }, + }, + { + name: "missing hide-comment key returns nil", + inputMap: map[string]any{}, + isNil: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + compiler := &Compiler{} + result := compiler.parseHideCommentConfig(tt.inputMap) + + if tt.isNil { + assert.Nil(t, result, "Expected nil config") + return + } + + require.NotNil(t, result, "Expected non-nil config") + + assert.Equal(t, tt.expected.Max, result.Max, "Max should match") + assert.Equal(t, tt.expected.TargetRepoSlug, result.TargetRepoSlug, "TargetRepoSlug should match") + + if tt.expected.Discussion != nil { + require.NotNil(t, result.Discussion, "Discussion should not be nil") + assert.Equal(t, *tt.expected.Discussion, *result.Discussion, "Discussion value should match") + } else { + assert.Nil(t, result.Discussion, "Discussion should be nil") + } + + assert.Equal(t, tt.expected.AllowedReasons, result.AllowedReasons, "AllowedReasons should match") + assert.Equal(t, tt.expected.AllowedRepos, result.AllowedRepos, "AllowedRepos should match") + }) + } +} + +// TestParseAddCommentsConfig tests that all fields are properly parsed +func TestParseAddCommentsConfig(t *testing.T) { + tests := []struct { + name string + inputMap map[string]any + expected *AddCommentsConfig + isNil bool + }{ + { + name: "all fields parsed correctly", + inputMap: map[string]any{ + "add-comment": map[string]any{ + "max": 3, + "target": "*", + "target-repo": "owner/repo", + "allowed-repos": []any{"owner/repo1", "owner/repo2"}, + "discussion": true, + "hide-older-comments": true, + "allowed-reasons": []any{"spam", "resolved"}, + }, + }, + expected: &AddCommentsConfig{ + BaseSafeOutputConfig: BaseSafeOutputConfig{ + Max: 3, + }, + Target: "*", + TargetRepoSlug: "owner/repo", + AllowedRepos: []string{"owner/repo1", "owner/repo2"}, + Discussion: ptrBool(true), + HideOlderComments: true, + AllowedReasons: []string{"spam", "resolved"}, + }, + }, + { + name: "discussion false is preserved", + inputMap: map[string]any{ + "add-comment": map[string]any{ + "max": 1, + "discussion": false, + }, + }, + expected: &AddCommentsConfig{ + BaseSafeOutputConfig: BaseSafeOutputConfig{ + Max: 1, + }, + Discussion: ptrBool(false), + }, + }, + { + name: "no discussion field defaults to nil", + inputMap: map[string]any{ + "add-comment": map[string]any{ + "max": 2, + }, + }, + expected: &AddCommentsConfig{ + BaseSafeOutputConfig: BaseSafeOutputConfig{ + Max: 2, + }, + Discussion: nil, + }, + }, + { + name: "default max of 1 when not specified", + inputMap: map[string]any{ + "add-comment": map[string]any{}, + }, + expected: &AddCommentsConfig{ + BaseSafeOutputConfig: BaseSafeOutputConfig{ + Max: 1, + }, + }, + }, + { + name: "nil config sets default max", + inputMap: map[string]any{ + "add-comment": nil, + }, + expected: &AddCommentsConfig{ + BaseSafeOutputConfig: BaseSafeOutputConfig{ + Max: 1, + }, + }, + }, + { + name: "wildcard target-repo returns nil", + inputMap: map[string]any{ + "add-comment": map[string]any{ + "target-repo": "*", + }, + }, + isNil: true, + }, + { + name: "missing add-comment key returns nil", + inputMap: map[string]any{}, + isNil: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + compiler := &Compiler{} + result := compiler.parseCommentsConfig(tt.inputMap) + + if tt.isNil { + assert.Nil(t, result, "Expected nil config") + return + } + + require.NotNil(t, result, "Expected non-nil config") + + assert.Equal(t, tt.expected.Max, result.Max, "Max should match") + assert.Equal(t, tt.expected.Target, result.Target, "Target should match") + assert.Equal(t, tt.expected.TargetRepoSlug, result.TargetRepoSlug, "TargetRepoSlug should match") + assert.Equal(t, tt.expected.AllowedRepos, result.AllowedRepos, "AllowedRepos should match") + assert.Equal(t, tt.expected.HideOlderComments, result.HideOlderComments, "HideOlderComments should match") + assert.Equal(t, tt.expected.AllowedReasons, result.AllowedReasons, "AllowedReasons should match") + + if tt.expected.Discussion != nil { + require.NotNil(t, result.Discussion, "Discussion should not be nil") + assert.Equal(t, *tt.expected.Discussion, *result.Discussion, "Discussion value should match") + } else { + assert.Nil(t, result.Discussion, "Discussion should be nil") + } + }) + } +}