Skip to content

Commit 61f3663

Browse files
authored
Fix activation permissions for pull request reactions (#26720)
1 parent 84d55b6 commit 61f3663

File tree

3 files changed

+35
-5
lines changed

3 files changed

+35
-5
lines changed

.github/workflows/smoke-copilot.lock.yml

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/workflow/activation_permissions_scope_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,37 @@ engine: copilot
7878
assert.NotContains(t, activationJobSection, "discussions: write", "activation job should not include discussions: write for PR review comment reactions")
7979
}
8080

81+
func TestActivationPermissionsPullRequestReactionRequiresPullRequestsWrite(t *testing.T) {
82+
tmpDir := testutil.TempDir(t, "activation-perms-pull-request-reaction")
83+
testFile := filepath.Join(tmpDir, "pull-request-reaction.md")
84+
testContent := `---
85+
on:
86+
reaction: eyes
87+
status-comment: false
88+
pull_request:
89+
types: [opened]
90+
engine: copilot
91+
---
92+
93+
# Pull request reaction permissions
94+
`
95+
96+
err := os.WriteFile(testFile, []byte(testContent), 0644)
97+
require.NoError(t, err, "failed to write test workflow")
98+
99+
compiler := NewCompiler()
100+
err = compiler.CompileWorkflow(testFile)
101+
require.NoError(t, err, "failed to compile workflow")
102+
103+
lockContent, err := os.ReadFile(stringutil.MarkdownToLockFile(testFile))
104+
require.NoError(t, err, "failed to read generated lock file")
105+
106+
activationJobSection := extractJobSection(string(lockContent), string(constants.ActivationJobName))
107+
assert.Contains(t, activationJobSection, "issues: write", "activation job should include issues: write for pull_request reactions")
108+
assert.Contains(t, activationJobSection, "pull-requests: write", "activation job should include pull-requests: write for pull_request reactions")
109+
assert.NotContains(t, activationJobSection, "discussions: write", "activation job should not include discussions: write for pull_request reactions")
110+
}
111+
81112
func TestActivationPermissionsReactionPullRequestsDisabled(t *testing.T) {
82113
tmpDir := testutil.TempDir(t, "activation-perms-reaction-pr-disabled")
83114
testFile := filepath.Join(tmpDir, "reaction-pr-disabled.md")

pkg/workflow/compiler_activation_job.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -744,17 +744,15 @@ func addActivationInteractionPermissionsMap(
744744
hasDiscussionCommentEvent := eventSet["discussion_comment"]
745745

746746
if hasReaction {
747-
// Reactions on issues, issue comments, and pull requests all use issues endpoints.
748-
// Both issue and pull request reactions require issues:write because PR reactions
749-
// are created via /issues/{number}/reactions.
747+
// Reactions on issues, issue comments, and pull requests use issues endpoints.
750748
needsIssuesWriteForIssueEvents := reactionIncludesIssues && (hasIssuesEvent || hasIssueCommentEvent)
751749
needsIssuesWriteForPullRequestEvents := reactionIncludesPullRequests && hasPullRequestEvent
752750
needsIssuesWriteForReaction := needsIssuesWriteForIssueEvents || needsIssuesWriteForPullRequestEvents
753751
if needsIssuesWriteForReaction {
754752
permsMap[PermissionIssues] = PermissionWrite
755753
}
756-
// Reactions on PR review comments use pull request review comment endpoints.
757-
if reactionIncludesPullRequests && hasPullRequestReviewCommentEvent {
754+
// Reactions on pull requests and PR review comments require pull-requests:write.
755+
if reactionIncludesPullRequests && (hasPullRequestEvent || hasPullRequestReviewCommentEvent) {
758756
permsMap[PermissionPullRequests] = PermissionWrite
759757
}
760758
// Reactions on discussions use GraphQL discussion APIs.

0 commit comments

Comments
 (0)