Add issues: read to update-project GitHub App token permissions#27837
Add issues: read to update-project GitHub App token permissions#27837
issues: read to update-project GitHub App token permissions#27837Conversation
Agent-Logs-Url: https://github.com/github/gh-aw/sessions/1b2c460b-5a3e-433c-97bb-a8696ae7e211 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
issues: read to update-project GitHub App token permissions
There was a problem hiding this comment.
Pull request overview
This PR fixes a GitHub App permission gap that caused safe-outputs.update-project to fail with NOT_FOUND for issue-backed project items by ensuring the minted token includes issues: read.
Changes:
- Extend
update-projectsafe-output permission computation to includeissues: read. - Add regression tests covering permission computation and GitHub App token mint-step inputs for
update-project. - Document the additional GitHub App token permission requirement for
update-project.
Show a summary per file
| File | Description |
|---|---|
| pkg/workflow/safe_outputs_permissions.go | Adds issues: read to computed permissions for update-project. |
| pkg/workflow/safe_outputs_permissions_test.go | Adds a test asserting update-project now yields contents: read, organization-projects: write, and issues: read. |
| pkg/workflow/safe_outputs_app_test.go | Adds a test asserting minted GitHub App token inputs include permission-issues: read for update-project. |
| docs/src/content/docs/reference/safe-outputs.md | Documents issues: read requirement for issue-backed resolution when using github-app with update-project. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 4/4 changed files
- Comments generated: 3
| if safeOutputs.UpdateProjects != nil && !isHandlerStaged(safeOutputs.Staged, safeOutputs.UpdateProjects.Staged) { | ||
| safeOutputsPermissionsLog.Print("Adding permissions for update-project") | ||
| permissions.Merge(NewPermissionsContentsReadProjectsWrite()) | ||
| permissions.Set(PermissionIssues, PermissionRead) | ||
| } |
There was a problem hiding this comment.
create-project can also require issues: read when item_url is provided: the JS handler calls a GraphQL repository { issue(number) { id } } query to resolve the issue node ID (see actions/setup/js/create_project.cjs:getIssueNodeId). Currently only update-project adds PermissionIssues: read, so a GitHub App token minted for create-project will be scoped without issues access and may fail when adding the initial issue item. Consider adding PermissionIssues: read to the shared project permission set (e.g., NewPermissionsContentsReadProjectsWrite) or explicitly to the create-project block as well.
|
|
||
| Manages GitHub Projects boards. Requires a write-capable PAT or GitHub App token ([project token authentication](/gh-aw/patterns/project-ops/#project-token-authentication)); default `GITHUB_TOKEN` lacks Projects v2 access. Update-only by default; set `create_if_missing: true` to create boards (requires appropriate token permissions). | ||
|
|
||
| When using `github-app`, issue-backed project item resolution also requires `issues: read` on the minted token (in addition to `organization-projects: write`). |
There was a problem hiding this comment.
The new note documents update-project needing issues: read for issue-backed item resolution when using github-app, but create-project can also resolve an issue when item_url is set (it queries repository.issue to get the node id). To avoid users hitting the same permission-scoping problem on project creation, consider extending this documentation to mention the create-project + item_url case (or more generally that project item resolution requires issues: read).
| When using `github-app`, issue-backed project item resolution also requires `issues: read` on the minted token (in addition to `organization-projects: write`). | |
| When using `github-app`, issue-backed project item resolution requires `issues: read` on the minted token (in addition to `organization-projects: write`). This applies to `update-project`, and also to `create-project` when `item_url` is used to resolve an issue into a project item. |
| assert.Contains(t, stepsStr, "permission-organization-projects: write", "GitHub App token should include organization projects write permission") | ||
| assert.Contains(t, stepsStr, "permission-issues: read", "GitHub App token should include issues read permission for issue-backed project items") | ||
| assert.Contains(t, stepsStr, "permission-contents: read", "GitHub App token should include contents read permission") | ||
| } |
There was a problem hiding this comment.
This test covers the minted GitHub App token permissions for update-project, but there isn’t coverage for the analogous create-project behavior when item_url is provided (which triggers issue resolution in the handler). Adding a test that compiles a workflow with create-project + item_url and asserts permission-issues: read is present would help prevent regressions.
| } | |
| } | |
| // TestSafeOutputsAppConfigurationCreateProjectWithItemURL tests that create-project with item_url | |
| // requests issue read permission for GitHub App tokens. | |
| func TestSafeOutputsAppConfigurationCreateProjectWithItemURL(t *testing.T) { | |
| compiler := NewCompiler(WithVersion("1.0.0")) | |
| markdown := `--- | |
| on: issues | |
| safe-outputs: | |
| create-project: | |
| project: "https://github.com/orgs/my-org/projects/1" | |
| item_url: "https://github.com/my-org/my-repo/issues/123" | |
| github-app: | |
| app-id: ${{ vars.APP_ID }} | |
| private-key: ${{ secrets.APP_PRIVATE_KEY }} | |
| --- | |
| # Test Workflow | |
| Test workflow with create-project item_url permissions. | |
| ` | |
| tmpDir := t.TempDir() | |
| testFile := filepath.Join(tmpDir, "test.md") | |
| err := os.WriteFile(testFile, []byte(markdown), 0644) | |
| require.NoError(t, err, "Failed to write test file") | |
| workflowData, err := compiler.ParseWorkflowFile(testFile) | |
| require.NoError(t, err, "Failed to parse markdown content") | |
| require.NotNil(t, workflowData.SafeOutputs, "SafeOutputs should not be nil") | |
| require.NotNil(t, workflowData.SafeOutputs.CreateProjects, "CreateProjects should not be nil") | |
| job, _, err := compiler.buildConsolidatedSafeOutputsJob(workflowData, "main", testFile) | |
| require.NoError(t, err, "Failed to build safe_outputs job") | |
| require.NotNil(t, job, "Job should not be nil") | |
| stepsStr := strings.Join(job.Steps, "") | |
| assert.Contains(t, stepsStr, "permission-organization-projects: write", "GitHub App token should include organization projects write permission") | |
| assert.Contains(t, stepsStr, "permission-issues: read", "GitHub App token should include issues read permission when create-project resolves an issue from item_url") | |
| assert.Contains(t, stepsStr, "permission-contents: read", "GitHub App token should include contents read permission") | |
| } |
|
@copilot review all comments |
1 similar comment
|
@copilot review all comments |
#27868) * Plan: address PR 27837 review comments Agent-Logs-Url: https://github.com/github/gh-aw/sessions/0527ad1c-e697-431a-9eb7-f68ee108bcbe Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> * Handle PR 27837 review comments for create-project issues read Agent-Logs-Url: https://github.com/github/gh-aw/sessions/0527ad1c-e697-431a-9eb7-f68ee108bcbe Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> * Remove unrelated lockfile changes from PR branch Agent-Logs-Url: https://github.com/github/gh-aw/sessions/0527ad1c-e697-431a-9eb7-f68ee108bcbe Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
safe-outputs.update-projectcould fail withNOT_FOUNDfor issue-backed project items when usinggithub-app, because the minted token lackedissues: readdespite using issue resolution paths. This change closes that permission gap in safe-output permission computation and generated app-token inputs.Permission model update
update-projectto includeissues: readin addition to existing project permissions.update-projectbehavior changed.Regression coverage
update-projectnow yields:contents: readorganization-projects: writeissues: readpermission-organization-projects: writepermission-issues: readDocumentation update
update-projectwithgithub-apprequiresissues: readfor issue-backed item resolution.