Skip to content

Commit dd5fbd9

Browse files
authored
Clarify PAT requirements for user-owned vs org-owned Projects v2 (#7041)
1 parent 4f12952 commit dd5fbd9

4 files changed

Lines changed: 262 additions & 7 deletions

File tree

docs/src/content/docs/examples/issue-pr-events/projectops.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,46 @@ By default, `update-project` is update-only: create the Project once in the GitH
1313

1414
**Important**: GitHub Projects v2 requires a PAT or GitHub App token - the default `GITHUB_TOKEN` cannot access Projects v2. Configure [`GH_AW_PROJECT_GITHUB_TOKEN`](/gh-aw/reference/tokens/#gh_aw_project_github_token-github-projects-v2) before using `update-project`.
1515

16+
## Token Requirements for Projects v2
17+
18+
The type of Personal Access Token (PAT) you need depends on whether you're working with **user-owned** or **organization-owned** Projects:
19+
20+
### User-owned Projects (v2)
21+
22+
**Must use a classic PAT** - Fine-grained PATs do **not** work with user-owned Projects.
23+
24+
Required scopes:
25+
- `project` (required for user Projects)
26+
- `repo` (required if accessing private repositories)
27+
28+
Create at: [https://github.com/settings/tokens/new](https://github.com/settings/tokens/new)
29+
30+
### Organization-owned Projects (v2)
31+
32+
**Can use either classic or fine-grained PAT**:
33+
34+
**Option 1: Classic PAT**
35+
- `project` (required)
36+
- `read:org` (required for org Projects)
37+
- `repo` (required if accessing private repositories)
38+
39+
**Option 2: Fine-grained PAT**
40+
- Repository access: Select specific repos or "All repositories"
41+
- **Organization permissions** (must be explicitly granted):
42+
- **Organization access**: Must be granted to the target organization
43+
- **Projects**: Read+Write
44+
- **Important**: Fine-grained PATs work by default only for public org resources. You must explicitly grant organization access and Projects permissions.
45+
46+
Create at: [https://github.com/settings/personal-access-tokens/new](https://github.com/settings/personal-access-tokens/new)
47+
48+
**Setup**: After creating your PAT, add it to your repository:
49+
50+
```bash
51+
gh aw secrets set GH_AW_PROJECT_GITHUB_TOKEN --value "YOUR_PROJECT_PAT"
52+
```
53+
54+
See the [GitHub Projects v2 token reference](/gh-aw/reference/tokens/#gh_aw_project_github_token-github-projects-v2) for complete details.
55+
1656
## When to Use ProjectOps
1757

1858
ProjectOps complements [GitHub's built-in Projects automation](https://docs.github.com/en/issues/planning-and-tracking-with-projects/automating-your-project/using-the-built-in-automations) with AI-powered intelligence:

docs/src/content/docs/reference/safe-outputs.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,11 @@ safe-outputs:
360360

361361
Agent output **must include a full GitHub project URL** in the `project` field (e.g., `https://github.com/orgs/myorg/projects/42` or `https://github.com/users/username/projects/5`). Project names or numbers alone are not accepted. Can also supply `content_number`, `content_type`, `fields`, and `campaign_id`. The job adds the issue or PR to the board, updates custom fields, applies `campaign:<id>` labels, and exposes `project-id`, `project-number`, `project-url`, `campaign-id`, and `item-id` outputs. Cross-repository targeting not supported.
362362

363-
To opt in to creating missing project boards, include `create_if_missing: true` in the `update_project` output. Your token must have sufficient permissions to create projects in the organization (classic PAT with `project` + `repo` scopes, or fine-grained PAT with Projects: Read+Write, or GitHub App with Projects permissions).
363+
To opt in to creating missing project boards, include `create_if_missing: true` in the `update_project` output. Your token must have sufficient permissions:
364+
- **User-owned Projects**: Classic PAT with `project` + `repo` scopes (fine-grained PATs don't work)
365+
- **Organization-owned Projects**: Classic PAT with `project` + `read:org` scopes, or fine-grained PAT with explicit Organization access and Projects: Read+Write, or GitHub App with Projects permissions
366+
367+
See [GitHub Projects v2 token requirements](/gh-aw/reference/tokens/#gh_aw_project_github_token-github-projects-v2) for detailed setup instructions.
364368

365369
### Pull Request Creation (`create-pull-request:`)
366370

docs/src/content/docs/reference/tokens.md

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -197,13 +197,35 @@ A specialized token for GitHub Projects v2 operations used by the [`update-proje
197197

198198
**Setup**:
199199

200-
1. Create a **classic PAT** with `project` and `repo` scopes, **OR** a [fine-grained PAT](https://github.com/settings/personal-access-tokens/new) with:
200+
The required token type depends on whether you're working with **user-owned** or **organization-owned** Projects:
201+
202+
**For User-owned Projects (v2)**:
203+
204+
You **must** use a **classic PAT** with the `project` scope. Fine-grained PATs do **not** work with user-owned Projects.
205+
206+
1. Create a [classic PAT](https://github.com/settings/tokens/new) with scopes:
207+
- `project` (required for user Projects)
208+
- `repo` (required if accessing private repositories)
209+
210+
**For Organization-owned Projects (v2)**:
211+
212+
You can use either a classic PAT or a fine-grained PAT:
213+
214+
1. **Option A**: Create a **classic PAT** with `project` and `read:org` scopes:
215+
- `project` (required)
216+
- `read:org` (required for org Projects)
217+
- `repo` (required if accessing private repositories)
218+
219+
2. **Option B**: Create a [fine-grained PAT](https://github.com/settings/personal-access-tokens/new) with:
201220
- Repository access: Select specific repos or "All repositories"
202-
- Organization permissions:
203-
- Projects: Read+Write (for creating and managing org Projects)
204-
- **OR** use a GitHub App with Projects: Read+Write permission
221+
- **Organization permissions** (must be explicitly granted):
222+
- **Organization access**: Must be granted to the target organization
223+
- **Projects**: Read+Write (for creating and managing org Projects)
224+
- **Important**: Fine-grained PATs work by default only for public org resources. You must explicitly grant organization access and Projects permissions.
205225

206-
2. Add to repository secrets:
226+
3. **Option C**: Use a GitHub App with Projects: Read+Write permission
227+
228+
After creating your token, add it to repository secrets:
207229

208230
```bash wrap
209231
gh aw secrets set GH_AW_PROJECT_GITHUB_TOKEN --value "YOUR_PROJECT_PAT"
@@ -235,7 +257,12 @@ safe-outputs:
235257
:::note[Default behavior]
236258
By default, `update-project` is **update-only**: it will not create projects. If a project doesn't exist, the job fails with instructions to create it manually.
237259

238-
**Important**: The default `GITHUB_TOKEN` **cannot** be used for Projects v2 operations. You **must** configure `GH_AW_PROJECT_GITHUB_TOKEN` or provide a custom token via `safe-outputs.update-project.github-token`. GitHub Projects v2 requires GraphQL API access with a PAT (classic with `project` + `repo` scopes, or fine-grained with Projects permissions) or a GitHub App.
260+
**Important**: The default `GITHUB_TOKEN` **cannot** be used for Projects v2 operations. You **must** configure `GH_AW_PROJECT_GITHUB_TOKEN` or provide a custom token via `safe-outputs.update-project.github-token`.
261+
262+
**GitHub Projects v2 PAT Requirements**:
263+
- **User-owned Projects**: Require a **classic PAT** with the `project` scope (plus `repo` if accessing private repos). Fine-grained PATs do **not** work with user-owned Projects.
264+
- **Organization-owned Projects**: Can use either a classic PAT with `project` + `read:org` scopes, **or** a fine-grained PAT with explicit Organization access granted plus Projects: Read+Write permission. Fine-grained PATs work by default only for public org resources and must be explicitly granted organization access.
265+
- **GitHub App**: Works for both user and org Projects with Projects: Read+Write permission.
239266

240267
To opt-in to creating projects, the agent must include `create_if_missing: true` in its output, and the token must have sufficient permissions to create projects in the organization.
241268
:::
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
---
2+
description: Test ProjectOps PAT requirements with actual trial repository testing
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
test_user_projects:
7+
description: "Test user-owned Projects (requires classic PAT in GH_AW_PROJECT_GITHUB_TOKEN)"
8+
type: boolean
9+
default: "true"
10+
test_org_projects:
11+
description: "Test org-owned Projects (requires PAT with org access)"
12+
type: boolean
13+
default: "true"
14+
cleanup_trial_repos:
15+
description: "Delete trial repositories after testing"
16+
type: boolean
17+
default: "true"
18+
schedule: weekly on monday
19+
permissions:
20+
contents: read
21+
actions: read
22+
issues: read
23+
pull-requests: read
24+
name: Test ProjectOps PAT Requirements
25+
engine: copilot
26+
timeout-minutes: 45
27+
tools:
28+
bash:
29+
- "*"
30+
github:
31+
mode: remote
32+
toolsets: [default]
33+
safe-outputs:
34+
create-issue:
35+
max: 1
36+
expires: 7d
37+
labels: [documentation, projectops, testing, trialops]
38+
---
39+
40+
# Test ProjectOps PAT Requirements with TrialOps
41+
42+
This workflow performs actual integration testing of ProjectOps PAT requirements by:
43+
1. Creating trial repositories
44+
2. Testing different PAT configurations with actual GitHub Projects v2 API calls
45+
3. Verifying documented requirements match real behavior
46+
4. Cleaning up trial repositories after testing
47+
48+
## Prerequisites
49+
50+
This test requires PATs to be configured:
51+
- `GH_AW_PROJECT_GITHUB_TOKEN`: PAT for testing (should have appropriate project scopes)
52+
- The workflow will test if the configured PAT works as documented
53+
54+
## Test Execution
55+
56+
Use `gh aw trial` to test ProjectOps workflows with different PAT configurations in isolated trial repositories:
57+
58+
### Test 1: User-owned Projects with Classic PAT
59+
60+
Test if a classic PAT with `project` scope can successfully manage user-owned Projects v2.
61+
62+
**Steps**:
63+
1. Create a trial repository: `gh-aw-trial-projectops-user`
64+
2. Create a test workflow that uses `update-project` to:
65+
- Add an issue to a user-owned Project
66+
- Update project fields
67+
- Verify the operations succeed
68+
3. Run the workflow with the configured PAT
69+
4. Check if operations succeed as documented
70+
71+
**Expected Result**: Operations should succeed if using classic PAT with `project` scope
72+
73+
### Test 2: Organization-owned Projects with Classic PAT
74+
75+
Test if a classic PAT with `project` + `read:org` can manage org-owned Projects v2.
76+
77+
**Steps**:
78+
1. Create a trial repository in an organization context
79+
2. Create a test workflow that uses `update-project` to:
80+
- Add an issue to an org-owned Project
81+
- Update project fields
82+
- Verify the operations succeed
83+
3. Run with classic PAT having `project` + `read:org` scopes
84+
85+
**Expected Result**: Operations should succeed with proper org permissions
86+
87+
### Test 3: Organization-owned Projects with Fine-grained PAT
88+
89+
Test if a fine-grained PAT with explicit org access + Projects: Read+Write can manage org-owned Projects.
90+
91+
**Steps**:
92+
1. Use the same trial repository
93+
2. Test with fine-grained PAT (if configured separately)
94+
3. Verify org-owned project operations work
95+
96+
**Expected Result**: Should work if org access was explicitly granted
97+
98+
### Test 4: Document Fine-grained PAT Limitation for User Projects
99+
100+
Test and document that fine-grained PATs do NOT work with user-owned Projects.
101+
102+
**Note**: This test documents the limitation but may not be executable if we don't have a fine-grained PAT configured for comparison.
103+
104+
## Implementation
105+
106+
Execute the following tests using bash commands:
107+
108+
**Step 1**: Create a minimal test workflow that attempts ProjectOps operations
109+
110+
**Step 2**: Use `gh aw trial` command to run the workflow in an isolated trial repository
111+
112+
**Step 3**: Analyze the results to determine if the configured PAT works as documented
113+
114+
**Step 4**: Report findings in an issue
115+
116+
The AI agent will:
117+
1. Generate a test workflow dynamically
118+
2. Execute it using the gh-aw trial command with appropriate flags
119+
3. Parse the results to determine PAT permission compatibility
120+
4. Create a summary issue with findings
121+
122+
This provides real integration testing of the documented PAT requirements using actual GitHub Projects v2 API operations.
123+
124+
## Test Results Report
125+
126+
Create an issue summarizing the test results:
127+
128+
**Title**: "ProjectOps PAT TrialOps Test Results - $(date +%Y-%m-%d)"
129+
130+
**Body**:
131+
132+
### Test Summary
133+
134+
**Test Date**: $(date -u +"%Y-%m-%d %H:%M:%S UTC")
135+
**Trial Repository**: [Link to trial repo if not deleted]
136+
**Workflow Run**: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
137+
138+
### Test Configuration
139+
140+
- User-owned Projects Test: Configured via workflow dispatch input
141+
- Org-owned Projects Test: Configured via workflow dispatch input
142+
- Cleanup Trial Repos: Configured via workflow dispatch input
143+
144+
### Results
145+
146+
#### User-owned Projects
147+
- **Classic PAT with project scope**: [PASS/FAIL/NOT_TESTED]
148+
- Details: [Error messages or success confirmation]
149+
150+
- **Fine-grained PAT**: [EXPECTED_TO_FAIL/NOT_TESTED]
151+
- Details: [Confirmation of documented limitation]
152+
153+
#### Organization-owned Projects
154+
- **Classic PAT with project + read:org**: [PASS/FAIL/NOT_TESTED]
155+
- Details: [Error messages or success confirmation]
156+
157+
- **Fine-grained PAT with org access**: [PASS/FAIL/NOT_TESTED]
158+
- Details: [Error messages or success confirmation]
159+
160+
### Documentation Validation
161+
162+
- **Documentation Accuracy**: [CONFIRMED/ISSUES_FOUND]
163+
- **Issues Found**: [List any discrepancies between docs and actual behavior]
164+
165+
### Recommendations
166+
167+
[Any updates needed to documentation based on test results]
168+
169+
### Trial Artifacts
170+
171+
- Trial repository: [URL or "Deleted after test"]
172+
- Trial results JSON: [Path to local results file]
173+
- GitHub Actions logs: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
174+
175+
---
176+
177+
**Note**: These tests use actual GitHub Projects v2 API calls with configured PATs. Results may vary based on:
178+
- PAT type and scopes configured
179+
- Organization settings and policies
180+
- Project ownership (user vs org)
181+
- GitHub API rate limits
182+
183+
For manual testing, see the [TrialOps Guide](/gh-aw/guides/trialops/) and [ProjectOps Documentation](/gh-aw/examples/issue-pr-events/projectops/).
184+

0 commit comments

Comments
 (0)