|
| 1 | +--- |
| 2 | +title: Project Tracking |
| 3 | +description: Automatically track issues and pull requests in GitHub Projects boards |
| 4 | +sidebar: |
| 5 | + badge: { text: 'Project', variant: 'tip' } |
| 6 | +--- |
| 7 | + |
| 8 | +The `project` frontmatter field enables automatic tracking of workflow-created items in GitHub Projects boards. When configured, workflows automatically get project management capabilities including item addition, field updates, and status reporting. |
| 9 | + |
| 10 | +## Quick Start |
| 11 | + |
| 12 | +Add the `project` field to your workflow frontmatter to enable project tracking: |
| 13 | + |
| 14 | +```yaml |
| 15 | +--- |
| 16 | +on: |
| 17 | + issues: |
| 18 | + types: [opened] |
| 19 | +project: https://github.com/orgs/github/projects/123 |
| 20 | +safe-outputs: |
| 21 | + create-issue: |
| 22 | + max: 3 |
| 23 | +--- |
| 24 | +``` |
| 25 | + |
| 26 | +This automatically enables: |
| 27 | +- **update-project** - Add items to projects, update fields (status, priority, etc.) |
| 28 | +- **create-project-status-update** - Post status updates to project boards |
| 29 | + |
| 30 | +## Configuration Options |
| 31 | + |
| 32 | +### Simple Format (String) |
| 33 | + |
| 34 | +Use a GitHub Project URL directly: |
| 35 | + |
| 36 | +```yaml |
| 37 | +project: https://github.com/orgs/github/projects/123 |
| 38 | +``` |
| 39 | +
|
| 40 | +### Full Configuration (Object) |
| 41 | +
|
| 42 | +Customize behavior with additional options: |
| 43 | +
|
| 44 | +```yaml |
| 45 | +project: |
| 46 | + url: https://github.com/orgs/github/projects/123 |
| 47 | + scope: |
| 48 | + - owner/repo1 |
| 49 | + - owner/repo2 |
| 50 | + - org:myorg |
| 51 | + max-updates: 50 |
| 52 | + max-status-updates: 2 |
| 53 | + github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} |
| 54 | + do-not-downgrade-done-items: true |
| 55 | +``` |
| 56 | +
|
| 57 | +### Configuration Fields |
| 58 | +
|
| 59 | +| Field | Type | Default | Description | |
| 60 | +|-------|------|---------|-------------| |
| 61 | +| `url` | string | (required) | GitHub Project URL (user or organization) | |
| 62 | +| `scope` | array | current repo | Repositories/organizations this workflow can operate on (e.g., `owner/repo`, `org:name`) | |
| 63 | +| `max-updates` | integer | 100 | Maximum project updates per workflow run | |
| 64 | +| `max-status-updates` | integer | 1 | Maximum status updates per workflow run | |
| 65 | +| `github-token` | string | `GITHUB_TOKEN` | Custom token with Projects permissions | |
| 66 | +| `do-not-downgrade-done-items` | boolean | false | Prevent moving completed items backward | |
| 67 | + |
| 68 | +## Prerequisites |
| 69 | + |
| 70 | +### 1. Create a GitHub Project |
| 71 | + |
| 72 | +Create a Projects V2 board in the GitHub UI before configuring your workflow. You'll need the Project URL from the browser address bar. |
| 73 | + |
| 74 | +### 2. Set Up Authentication |
| 75 | + |
| 76 | +#### For User-Owned Projects |
| 77 | + |
| 78 | +Use a **classic PAT** with scopes: |
| 79 | +- `project` (required) |
| 80 | +- `repo` (if accessing private repositories) |
| 81 | + |
| 82 | +#### For Organization-Owned Projects |
| 83 | + |
| 84 | +Use a **fine-grained PAT** with: |
| 85 | +- Repository access: Select specific repos |
| 86 | +- Repository permissions: |
| 87 | + - Contents: Read |
| 88 | + - Issues: Read (if workflow triggers on issues) |
| 89 | + - Pull requests: Read (if workflow triggers on pull requests) |
| 90 | +- Organization permissions: |
| 91 | + - Projects: Read & Write |
| 92 | + |
| 93 | +### 3. Store the Token |
| 94 | + |
| 95 | +```bash |
| 96 | +gh aw secrets set GH_AW_PROJECT_GITHUB_TOKEN --value "YOUR_PROJECT_TOKEN" |
| 97 | +``` |
| 98 | + |
| 99 | +See the [GitHub Projects V2 token reference](/gh-aw/reference/tokens/#gh_aw_project_github_token-github-projects-v2) for complete details. |
| 100 | + |
| 101 | +## Example: Issue Triage |
| 102 | + |
| 103 | +Automatically add new issues to a project board with intelligent categorization: |
| 104 | + |
| 105 | +```aw wrap |
| 106 | +--- |
| 107 | +on: |
| 108 | + issues: |
| 109 | + types: [opened] |
| 110 | +permissions: |
| 111 | + contents: read |
| 112 | + actions: read |
| 113 | + issues: read |
| 114 | +tools: |
| 115 | + github: |
| 116 | + toolsets: [default, projects] |
| 117 | + github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} |
| 118 | +project: |
| 119 | + url: https://github.com/orgs/myorg/projects/1 |
| 120 | + max-updates: 10 |
| 121 | + github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} |
| 122 | +safe-outputs: |
| 123 | + add-comment: |
| 124 | + max: 1 |
| 125 | +--- |
| 126 | +
|
| 127 | +# Smart Issue Triage |
| 128 | +
|
| 129 | +When a new issue is created, analyze it and add to the project board. |
| 130 | +
|
| 131 | +## Task |
| 132 | +
|
| 133 | +Examine the issue title and description to determine its type: |
| 134 | +- **Bug reports** → Add to project, set status="Needs Triage", priority="High" |
| 135 | +- **Feature requests** → Add to project, set status="Backlog", priority="Medium" |
| 136 | +- **Documentation** → Add to project, set status="Todo", priority="Low" |
| 137 | +
|
| 138 | +After adding to the project board, comment on the issue confirming where it was added. |
| 139 | +``` |
| 140 | + |
| 141 | +## Example: Pull Request Tracking |
| 142 | + |
| 143 | +Track pull requests through the development workflow: |
| 144 | + |
| 145 | +```aw wrap |
| 146 | +--- |
| 147 | +on: |
| 148 | + pull_request: |
| 149 | + types: [opened, review_requested] |
| 150 | +permissions: |
| 151 | + contents: read |
| 152 | + actions: read |
| 153 | + pull-requests: read |
| 154 | +tools: |
| 155 | + github: |
| 156 | + toolsets: [default, projects] |
| 157 | + github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} |
| 158 | +project: |
| 159 | + url: https://github.com/orgs/myorg/projects/2 |
| 160 | + max-updates: 5 |
| 161 | + do-not-downgrade-done-items: true |
| 162 | +--- |
| 163 | +
|
| 164 | +# PR Project Tracker |
| 165 | +
|
| 166 | +Track pull requests in the development project board. |
| 167 | +
|
| 168 | +## Task |
| 169 | +
|
| 170 | +When a pull request is opened or reviews are requested: |
| 171 | +1. Add the PR to the project board |
| 172 | +2. Set status based on PR state: |
| 173 | + - Just opened → "In Progress" |
| 174 | + - Reviews requested → "In Review" |
| 175 | +3. Set priority based on PR labels: |
| 176 | + - Has "urgent" label → "High" |
| 177 | + - Has "enhancement" label → "Medium" |
| 178 | + - Default → "Low" |
| 179 | +``` |
| 180 | + |
| 181 | +## Automatic Safe Outputs |
| 182 | + |
| 183 | +When you configure the `project` field, the compiler automatically adds these safe-output operations if not already configured: |
| 184 | + |
| 185 | +### update-project |
| 186 | + |
| 187 | +Manages project items (add, update fields, views): |
| 188 | + |
| 189 | +```yaml |
| 190 | +# Automatically configured with project field |
| 191 | +update-project: |
| 192 | + max: 100 # Default from project.max-updates |
| 193 | + github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} |
| 194 | +``` |
| 195 | + |
| 196 | +Operations: |
| 197 | +- `create` - Create a new project |
| 198 | +- `add` - Add items to project |
| 199 | +- `update` - Update project fields (status, priority, custom fields) |
| 200 | +- `create_fields` - Create custom fields |
| 201 | +- `create_views` - Create project views |
| 202 | + |
| 203 | +### create-project-status-update |
| 204 | + |
| 205 | +Posts status updates to project boards: |
| 206 | + |
| 207 | +```yaml |
| 208 | +# Automatically configured with project field |
| 209 | +create-project-status-update: |
| 210 | + max: 1 # Default from project.max-status-updates |
| 211 | + github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} |
| 212 | +``` |
| 213 | + |
| 214 | +Use for campaign progress reports, milestone summaries, or workflow health indicators. |
| 215 | + |
| 216 | +## Overriding Auto-Configuration |
| 217 | + |
| 218 | +If you need custom configuration, define safe-outputs explicitly. Your configuration takes precedence: |
| 219 | + |
| 220 | +```yaml |
| 221 | +project: |
| 222 | + url: https://github.com/orgs/github/projects/123 |
| 223 | +safe-outputs: |
| 224 | + update-project: |
| 225 | + max: 25 # Custom max overrides project.max-updates |
| 226 | + views: |
| 227 | + - name: "Triage View" |
| 228 | + layout: board |
| 229 | + filter: "status:Needs Triage" |
| 230 | + create-project-status-update: |
| 231 | + max: 3 # Custom max overrides project.max-status-updates |
| 232 | +``` |
| 233 | + |
| 234 | +## Relationship with Campaigns |
| 235 | + |
| 236 | +The `project` field brings project tracking capabilities from [campaign orchestrators](/gh-aw/examples/campaigns/) to regular agentic workflows: |
| 237 | + |
| 238 | +**Campaign orchestrators** (campaign.md files): |
| 239 | +- Use `project-url` in campaign spec |
| 240 | +- Automatically coordinate multiple workflows |
| 241 | +- Track campaign-wide progress |
| 242 | + |
| 243 | +**Agentic workflows** (regular .md files): |
| 244 | +- Use `project` in frontmatter |
| 245 | +- Focus on single workflow operations |
| 246 | +- Track workflow-specific items |
| 247 | + |
| 248 | +Both use the same underlying safe-output operations (`update-project`, `create-project-status-update`). |
| 249 | + |
| 250 | +## Common Patterns |
| 251 | + |
| 252 | +### Progressive Status Updates |
| 253 | + |
| 254 | +Move items through workflow stages: |
| 255 | + |
| 256 | +```aw |
| 257 | +Analyze the issue and determine its current state: |
| 258 | +- If new and unreviewed → status="Needs Triage" |
| 259 | +- If reviewed and accepted → status="Todo" |
| 260 | +- If work started → status="In Progress" |
| 261 | +- If PR merged → status="Done" |
| 262 | +
|
| 263 | +Update the project item with the appropriate status. |
| 264 | +``` |
| 265 | + |
| 266 | +### Priority Assignment |
| 267 | + |
| 268 | +Set priority based on content analysis: |
| 269 | + |
| 270 | +```aw |
| 271 | +Examine the issue for urgency indicators: |
| 272 | +- Contains "critical", "urgent", "blocker" → priority="High" |
| 273 | +- Contains "important", "soon" → priority="Medium" |
| 274 | +- Default → priority="Low" |
| 275 | +
|
| 276 | +Update the project item with the assigned priority. |
| 277 | +``` |
| 278 | + |
| 279 | +### Field-Based Routing |
| 280 | + |
| 281 | +Use custom fields for workflow routing: |
| 282 | + |
| 283 | +```aw |
| 284 | +Determine the team that should handle this issue: |
| 285 | +- Security-related → team="Security" |
| 286 | +- UI/UX changes → team="Design" |
| 287 | +- API changes → team="Backend" |
| 288 | +- Default → team="General" |
| 289 | +
|
| 290 | +Update the project item with the team field. |
| 291 | +``` |
| 292 | + |
| 293 | +## Best Practices |
| 294 | + |
| 295 | +1. **Use specific project URLs** - Reference the exact project board to avoid ambiguity |
| 296 | +2. **Set reasonable limits** - Use `max-updates` to prevent runaway operations |
| 297 | +3. **Secure tokens properly** - Store project tokens as repository/organization secrets |
| 298 | +4. **Enable do-not-downgrade** - Prevent accidental status regression on completed items |
| 299 | +5. **Test with dry runs** - Use `staged: true` in safe-outputs to preview changes |
| 300 | +6. **Document field mappings** - Comment your workflow to explain project field choices |
| 301 | + |
| 302 | +## Troubleshooting |
| 303 | + |
| 304 | +### Items Not Added to Project |
| 305 | + |
| 306 | +**Symptoms**: Workflow runs successfully but items don't appear in project board |
| 307 | + |
| 308 | +**Solutions**: |
| 309 | +- Verify project URL is correct (check browser address bar) |
| 310 | +- Confirm token has Projects: Read & Write permissions |
| 311 | +- Check that organization allows Projects access for the token |
| 312 | +- Review workflow logs for safe_outputs job errors |
| 313 | + |
| 314 | +### Permission Errors |
| 315 | + |
| 316 | +**Symptoms**: Workflow fails with "Resource not accessible" or "Insufficient permissions" |
| 317 | + |
| 318 | +**Solutions**: |
| 319 | +- For organization projects: Use fine-grained PAT with organization Projects permission |
| 320 | +- For user projects: Use classic PAT with `project` scope |
| 321 | +- Ensure token is stored in correct secret name |
| 322 | +- Verify repository settings allow Actions to access secrets |
| 323 | + |
| 324 | +### Token Not Resolved |
| 325 | + |
| 326 | +**Symptoms**: Workflow fails with "invalid token" or token appears as literal string |
| 327 | + |
| 328 | +**Solutions**: |
| 329 | +- Use GitHub expression syntax: `${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }}` |
| 330 | +- Don't quote the expression in YAML |
| 331 | +- Ensure secret name matches exactly (case-sensitive) |
| 332 | +- Check secret is set at repository or organization level |
| 333 | + |
| 334 | +## See Also |
| 335 | + |
| 336 | +- [Safe Outputs Reference](/gh-aw/reference/safe-outputs/) - Complete safe-outputs documentation |
| 337 | +- [update-project](/gh-aw/reference/safe-outputs/#project-board-updates-update-project) - Detailed update-project configuration |
| 338 | +- [create-project-status-update](/gh-aw/reference/safe-outputs/#project-status-updates-create-project-status-update) - Status update configuration |
| 339 | +- [GitHub Projects V2 Tokens](/gh-aw/reference/tokens/#gh_aw_project_github_token-github-projects-v2) - Token setup guide |
| 340 | +- [Campaigns](/gh-aw/examples/campaigns/) - Campaign orchestrator documentation |
0 commit comments