From e1f7d99f74fe1721796df12d49c20f3dde87add4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 23 Dec 2025 22:05:51 +0000 Subject: [PATCH 1/6] Initial plan From f4f5401a892ead3d35007fd943ae74c7a9cac370 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 23 Dec 2025 22:09:59 +0000 Subject: [PATCH 2/6] docs: update ProjectOps documentation for organization-owned projects Co-authored-by: mnkiefer <8320933+mnkiefer@users.noreply.github.com> --- pkg/cli/templates/github-agentic-workflows.md | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/pkg/cli/templates/github-agentic-workflows.md b/pkg/cli/templates/github-agentic-workflows.md index f04794f4a95..30ddce78aeb 100644 --- a/pkg/cli/templates/github-agentic-workflows.md +++ b/pkg/cli/templates/github-agentic-workflows.md @@ -454,6 +454,19 @@ The YAML frontmatter supports these fields: if-no-changes: "warn" # Optional: "warn" (default), "error", or "ignore" ``` Not supported for cross-repository operations. + - `update-discussion:` - Update discussion title, body, or labels + ```yaml + safe-outputs: + update-discussion: + title: true # Optional: enable title updates + body: true # Optional: enable body updates + labels: true # Optional: enable label updates + allowed-labels: [status, type] # Optional: restrict to specific labels + max: 1 # Optional: max updates (default: 1) + target: "*" # Optional: "triggering" (default), "*", or number + target-repo: "owner/repo" # Optional: cross-repository + ``` + When using `safe-outputs.update-discussion`, the main job does **not** need `discussions: write` permission since updates are handled by a separate job with appropriate permissions. - `update-release:` - Update GitHub release descriptions ```yaml safe-outputs: @@ -463,6 +476,17 @@ The YAML frontmatter supports these fields: github-token: ${{ secrets.CUSTOM_TOKEN }} # Optional: custom token ``` Operation types: `replace`, `append`, `prepend`. + - `upload-asset:` - Publish files to orphaned git branch + ```yaml + safe-outputs: + upload-asset: + branch: "assets/${{ github.workflow }}" # Optional: branch name + max-size: 10240 # Optional: max file size in KB (default: 10MB) + allowed-exts: [.png, .jpg, .pdf] # Optional: allowed file extensions + max: 10 # Optional: max assets (default: 10) + target-repo: "owner/repo" # Optional: cross-repository + ``` + Publishes workflow artifacts to an orphaned git branch for persistent storage. Default allowed extensions include common non-executable types. Maximum file size is 50MB (51200 KB). - `create-code-scanning-alert:` - Generate SARIF security advisories ```yaml safe-outputs: @@ -486,6 +510,28 @@ The YAML frontmatter supports these fields: target-repo: "owner/repo" # Optional: cross-repository ``` Requires PAT with elevated permissions as `GH_AW_AGENT_TOKEN`. + - `assign-to-user:` - Assign users to issues or pull requests + ```yaml + safe-outputs: + assign-to-user: + assignees: [user1, user2] # Optional: restrict to specific users + max: 3 # Optional: max assignments (default: 3) + target: "*" # Optional: "triggering" (default), "*", or number + target-repo: "owner/repo" # Optional: cross-repository + ``` + When using `safe-outputs.assign-to-user`, the main job does **not** need `issues: write` or `pull-requests: write` permission since user assignment is handled by a separate job with appropriate permissions. + - `hide-comment:` - Hide comments on issues, PRs, or discussions + ```yaml + safe-outputs: + hide-comment: + max: 5 # Optional: max comments to hide (default: 5) + allowed-reasons: # Optional: restrict hide reasons + - spam + - outdated + - resolved + target-repo: "owner/repo" # Optional: cross-repository + ``` + Allowed reasons: `spam`, `abuse`, `off_topic`, `outdated`, `resolved`. When using `safe-outputs.hide-comment`, the main job does **not** need write permissions since comment hiding is handled by a separate job. - `noop:` - Log completion message for transparency (auto-enabled) ```yaml safe-outputs: From 759c63d907b17f17b77815052f7cf4adefced6a5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 23 Dec 2025 22:13:28 +0000 Subject: [PATCH 3/6] docs: update organization project token configuration requirements Co-authored-by: mnkiefer <8320933+mnkiefer@users.noreply.github.com> --- .../examples/issue-pr-events/projectops.md | 56 +++++++++++++++++-- docs/src/content/docs/reference/tokens.md | 30 ++++++++-- 2 files changed, 75 insertions(+), 11 deletions(-) diff --git a/docs/src/content/docs/examples/issue-pr-events/projectops.md b/docs/src/content/docs/examples/issue-pr-events/projectops.md index e0f9b15d65e..9664e916358 100644 --- a/docs/src/content/docs/examples/issue-pr-events/projectops.md +++ b/docs/src/content/docs/examples/issue-pr-events/projectops.md @@ -35,12 +35,17 @@ You can use either a classic or fine-grained PAT. - `read:org` (required for org Projects) - `repo` (required if accessing private repositories) -**Fine-grained PAT** settings: +**Fine-grained PAT** settings (recommended): -- Repository access: Select specific repos or "All repositories" -- Organization access: Must be granted to the target organization -- Organization permissions: Projects = Read+Write -- Important: Fine-grained PATs work by default only for public org resources. You must explicitly grant organization access and Projects permissions. +- Repository access: Select specific repos that will use the workflow +- Repository permissions: + - Contents: Read + - Issues: Read (if workflow is triggered by issues) + - Pull requests: Read (if workflow is triggered by pull requests) +- Organization permissions: + - Projects: Read & Write (required for updating projects) + +Important: Fine-grained PATs require explicit organization access. You must grant organization access and Projects permissions during token creation. Create at: [https://github.com/settings/personal-access-tokens/new](https://github.com/settings/personal-access-tokens/new) @@ -115,6 +120,47 @@ The `update-project` tool provides intelligent project management: - **Applies a tracking label**: When adding a new item, it can apply a consistent tracking label to the underlying issue/PR - **Returns outputs**: Exposes the Project item ID (`item-id`) for downstream steps +## Organization-Owned Project Configuration + +For workflows that interact with organization-owned projects and need to query GitHub information, use the following configuration: + +```yaml wrap +--- +on: + issues: + types: [opened] +permissions: + contents: read + actions: read +tools: + github: + toolsets: [default, projects] + github-token: ${{ secrets.ORG_PROJECT_WRITE }} +safe-outputs: + update-project: + github-token: ${{ secrets.ORG_PROJECT_WRITE }} +--- + +# Smart Issue Triage for Organization Project + +Analyze the issue and add it to the organization project board... +``` + +**Key requirements for the `ORG_PROJECT_WRITE` token (fine-grained PAT)**: + +- **Repository access**: Select specific repositories with the workflow +- **Repository permissions**: + - Contents: Read + - Issues: Read (as needed) + - Pull requests: Read (as needed) +- **Organization permissions**: + - Projects: Read & Write + +This configuration ensures: +1. The GitHub MCP toolset can query repository and project information +2. The `update-project` safe output can modify the organization project +3. Both operations use the same token with appropriate permissions + ## Accessing Issue Context ProjectOps workflows can access sanitized issue content through the `needs.activation.outputs.text` variable, which combines the issue title and description while removing security risks: diff --git a/docs/src/content/docs/reference/tokens.md b/docs/src/content/docs/reference/tokens.md index 721eff47cdb..20c076dfd11 100644 --- a/docs/src/content/docs/reference/tokens.md +++ b/docs/src/content/docs/reference/tokens.md @@ -216,12 +216,15 @@ You can use either a classic PAT or a fine-grained PAT: - `read:org` (required for org Projects) - `repo` (required if accessing private repositories) -2. **Option B**: Create a [fine-grained PAT](https://github.com/settings/personal-access-tokens/new) with: - - Repository access: Select specific repos or "All repositories" +2. **Option B (recommended)**: Create a [fine-grained PAT](https://github.com/settings/personal-access-tokens/new) with: + - **Repository access**: Select specific repos that will use the workflow + - **Repository permissions**: + - Contents: Read + - Issues: Read (if needed for issue-triggered workflows) + - Pull requests: Read (if needed for PR-triggered workflows) - **Organization permissions** (must be explicitly granted): - - **Organization access**: Must be granted to the target organization - - **Projects**: Read+Write (for creating and managing org Projects) - - **Important**: Fine-grained PATs work by default only for public org resources. You must explicitly grant organization access and Projects permissions. + - Projects: Read & Write (required for updating org Projects) + - **Important**: You must explicitly grant organization access during token creation 3. **Option C**: Use a GitHub App with Projects: Read+Write permission @@ -252,8 +255,19 @@ The compiler automatically sets the `GH_AW_PROJECT_GITHUB_TOKEN` environment var safe-outputs: update-project: github-token: ${{ secrets.CUSTOM_PROJECT_TOKEN }} + +# Option 3: Organization projects with GitHub tools integration +tools: + github: + toolsets: [default, projects] + github-token: ${{ secrets.ORG_PROJECT_WRITE }} +safe-outputs: + update-project: + github-token: ${{ secrets.ORG_PROJECT_WRITE }} ``` +**For organization-owned projects**, the complete configuration should include both the GitHub tools and safe outputs using the same token with appropriate permissions. + :::note[Default behavior] 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. @@ -261,7 +275,11 @@ By default, `update-project` is **update-only**: it will not create projects. If **GitHub Projects v2 PAT Requirements**: - **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. -- **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. +- **Organization-owned Projects**: Can use either a classic PAT with `project` + `read:org` scopes, **or** a fine-grained PAT with: + - Repository access to specific repositories + - Repository permissions: Contents: Read, Issues: Read, Pull requests: Read (as needed) + - Organization permissions: Projects: Read & Write + - Explicit organization access granted during token creation - **GitHub App**: Works for both user and org Projects with Projects: Read+Write permission. 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. From 752e9a0d3372dad73ef2e7cb053f75a6c2d7b32a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 23 Dec 2025 22:16:30 +0000 Subject: [PATCH 4/6] chore: sync workflow lock files Co-authored-by: mnkiefer <8320933+mnkiefer@users.noreply.github.com> --- .github/workflows/issue-classifier.lock.yml | 2 +- .github/workflows/release.lock.yml | 6 +++--- .github/workflows/stale-repo-identifier.lock.yml | 2 +- .github/workflows/super-linter.lock.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/issue-classifier.lock.yml b/.github/workflows/issue-classifier.lock.yml index 4f4a69a3e57..3be5ab9acd8 100644 --- a/.github/workflows/issue-classifier.lock.yml +++ b/.github/workflows/issue-classifier.lock.yml @@ -2241,7 +2241,7 @@ jobs: path: /tmp/gh-aw/aw_info.json if-no-files-found: warn - name: Run AI Inference - uses: actions/ai-inference@334892bb203895caaed82ec52d23c1ed9385151e # v1 + uses: actions/ai-inference@334892bb203895caaed82ec52d23c1ed9385151e # v2.0.4 env: GH_AW_MCP_CONFIG: /tmp/gh-aw/mcp-config/mcp-servers.json GH_AW_PROMPT: /tmp/gh-aw/aw-prompts/prompt.txt diff --git a/.github/workflows/release.lock.yml b/.github/workflows/release.lock.yml index 8433f151f17..ce61da11ec3 100644 --- a/.github/workflows/release.lock.yml +++ b/.github/workflows/release.lock.yml @@ -6056,13 +6056,13 @@ jobs: - name: Download Go modules run: go mod download - name: Generate SBOM (SPDX format) - uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.10 + uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.11 with: artifact-name: sbom.spdx.json format: spdx-json output-file: sbom.spdx.json - name: Generate SBOM (CycloneDX format) - uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.10 + uses: anchore/sbom-action@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.11 with: artifact-name: sbom.cdx.json format: cyclonedx-json @@ -6261,7 +6261,7 @@ jobs: fetch-depth: 0 persist-credentials: false - name: Release with gh-extension-precompile - uses: cli/gh-extension-precompile@9e2237c30f869ad3bcaed6a4be2cd43564dd421b # v2 + uses: cli/gh-extension-precompile@9e2237c30f869ad3bcaed6a4be2cd43564dd421b # v2.1.0 with: build_script_override: scripts/build-release.sh go_version_file: go.mod diff --git a/.github/workflows/stale-repo-identifier.lock.yml b/.github/workflows/stale-repo-identifier.lock.yml index a8cd91dcd02..21caadf4297 100644 --- a/.github/workflows/stale-repo-identifier.lock.yml +++ b/.github/workflows/stale-repo-identifier.lock.yml @@ -176,7 +176,7 @@ jobs: ORGANIZATION: ${{ env.ORGANIZATION }} id: stale-repos name: Run stale_repos tool - uses: github/stale-repos@a21e55567b83cf3c3f3f9085d3038dc6cee02598 # v3 + uses: github/stale-repos@a21e55567b83cf3c3f3f9085d3038dc6cee02598 # v3.0.2 - env: INACTIVE_REPOS: ${{ steps.stale-repos.outputs.inactiveRepos }} name: Save stale repos output diff --git a/.github/workflows/super-linter.lock.yml b/.github/workflows/super-linter.lock.yml index b15660af2fb..4c2fde522cd 100644 --- a/.github/workflows/super-linter.lock.yml +++ b/.github/workflows/super-linter.lock.yml @@ -6189,7 +6189,7 @@ jobs: persist-credentials: false - name: Super-linter id: super-linter - uses: super-linter/super-linter@47984f49b4e87383eed97890fe2dca6063bbd9c3 # v8.2.1 + uses: super-linter/super-linter@47984f49b4e87383eed97890fe2dca6063bbd9c3 # v8.3.1 env: CREATE_LOG_FILE: "true" DEFAULT_BRANCH: main From 92420661a29ffe692d1d09bf66e3a32662665947 Mon Sep 17 00:00:00 2001 From: Mara Nikola Kiefer <8320933+mnkiefer@users.noreply.github.com> Date: Tue, 23 Dec 2025 23:24:04 +0100 Subject: [PATCH 5/6] Update token creation instructions in projectops.md Clarified token requirements for user and organization-owned projects, specifying classic and fine-grained PATs with necessary scopes. --- .../examples/issue-pr-events/projectops.md | 21 ++++--------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/docs/src/content/docs/examples/issue-pr-events/projectops.md b/docs/src/content/docs/examples/issue-pr-events/projectops.md index 9664e916358..9215a7af6ec 100644 --- a/docs/src/content/docs/examples/issue-pr-events/projectops.md +++ b/docs/src/content/docs/examples/issue-pr-events/projectops.md @@ -15,28 +15,17 @@ Then the [`update-project`](/gh-aw/reference/safe-outputs/#project-board-updates 1. **Create a Project**: Before you wire up a workflow, you must first create the Project in the GitHub UI (user or organization level). Keep the Project URL handy (you'll need to reference it in your workflow instructions). -2. **Create a token**: The kind of token you need depends on whether the Project you created is **user-owned** or **organization-owned** -For user-owned projects, use a **classic PAT** with `read:project` scope (for queries) or `project` scope (for queries and mutations). +2. **Create a token**: The kind of token you need depends on whether the Project you created is **user-owned** or **organization-owned**. -Required scopes: +#### User-owned Projects (v2) +Use a **classic PAT** with scopes: - `project` (required for user Projects) - `repo` (required if accessing private repositories) -Create at: [https://github.com/settings/tokens/new](https://github.com/settings/tokens/new) - #### Organization-owned Projects (v2) -You can use either a classic or fine-grained PAT. - -**Classic PAT** scopes: - -- `project` (required) -- `read:org` (required for org Projects) -- `repo` (required if accessing private repositories) - -**Fine-grained PAT** settings (recommended): - +Use a **fine-grained** PAT with scopes: - Repository access: Select specific repos that will use the workflow - Repository permissions: - Contents: Read @@ -47,8 +36,6 @@ You can use either a classic or fine-grained PAT. Important: Fine-grained PATs require explicit organization access. You must grant organization access and Projects permissions during token creation. -Create at: [https://github.com/settings/personal-access-tokens/new](https://github.com/settings/personal-access-tokens/new) - ### 3) Store the token as a secret After creating your token, add it to your repository: From 616e68944cce5d4c6b5fd354ea0131383bb60f92 Mon Sep 17 00:00:00 2001 From: Mara Nikola Kiefer <8320933+mnkiefer@users.noreply.github.com> Date: Tue, 23 Dec 2025 23:31:22 +0100 Subject: [PATCH 6/6] Update projectops.md --- .../examples/issue-pr-events/projectops.md | 103 ++---------------- 1 file changed, 8 insertions(+), 95 deletions(-) diff --git a/docs/src/content/docs/examples/issue-pr-events/projectops.md b/docs/src/content/docs/examples/issue-pr-events/projectops.md index 9215a7af6ec..66fe5eb7c9e 100644 --- a/docs/src/content/docs/examples/issue-pr-events/projectops.md +++ b/docs/src/content/docs/examples/issue-pr-events/projectops.md @@ -34,8 +34,6 @@ Use a **fine-grained** PAT with scopes: - Organization permissions: - Projects: Read & Write (required for updating projects) -Important: Fine-grained PATs require explicit organization access. You must grant organization access and Projects permissions during token creation. - ### 3) Store the token as a secret After creating your token, add it to your repository: @@ -66,6 +64,10 @@ on: permissions: contents: read actions: read +tools: + github: + toolsets: [default, projects] + github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} safe-outputs: update-project: max: 1 @@ -95,8 +97,8 @@ ProjectOps workflows use the `update-project` safe output to ensure secure proje ```yaml wrap safe-outputs: update-project: - max: 10 # Optional: max project operations (default: 10) - github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} # Required: PAT with Projects access (default GITHUB_TOKEN won't work) + max: 10 + github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} ``` The `update-project` tool provides intelligent project management: @@ -122,10 +124,10 @@ permissions: tools: github: toolsets: [default, projects] - github-token: ${{ secrets.ORG_PROJECT_WRITE }} + github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} safe-outputs: update-project: - github-token: ${{ secrets.ORG_PROJECT_WRITE }} + github-token: ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }} --- # Smart Issue Triage for Organization Project @@ -133,16 +135,6 @@ safe-outputs: Analyze the issue and add it to the organization project board... ``` -**Key requirements for the `ORG_PROJECT_WRITE` token (fine-grained PAT)**: - -- **Repository access**: Select specific repositories with the workflow -- **Repository permissions**: - - Contents: Read - - Issues: Read (as needed) - - Pull requests: Read (as needed) -- **Organization permissions**: - - Projects: Read & Write - This configuration ensures: 1. The GitHub MCP toolset can query repository and project information 2. The `update-project` safe output can modify the organization project @@ -159,85 +151,6 @@ Analyze this issue to determine priority: "${{ needs.activation.outputs.text }}" **Security Note**: Always treat user content as potentially untrusted and design workflows to be resilient against prompt injection attempts. -## Common ProjectOps Patterns - -### Initiative Launch and Tracking - -Use an existing project board for a focused initiative and add related issues with tracking metadata. - -Create the initiative Project in the GitHub UI first (the `update-project` safe output does not create Projects). - -This goes beyond native GitHub automation by analyzing the codebase to generate related issues and coordinating multiple related work items. - -```aw wrap ---- -on: - workflow_dispatch: - inputs: - initiative_name: - description: "Initiative name" - required: true -permissions: - contents: read - actions: read -safe-outputs: - create-issue: - max: 20 - update-project: - max: 20 ---- - -# Launch Initiative - -Use the initiative project board: "{{inputs.initiative_name}}" - -Analyze the repository to identify tasks needed for this initiative. - -For each task: -1. Create an issue with detailed description -2. Add the issue to the initiative project board -3. Set status to "Todo" -4. Set priority based on impact -5. Apply a tracking label for reporting - -The initiative board provides a visual dashboard showing all related work. -``` - - - -### Content-Based Priority Assignment - -Analyze issue content to set priority automatically, going beyond what labels can provide: - -```aw wrap ---- -on: - issues: - types: [opened] -permissions: - contents: read - actions: read -safe-outputs: - update-project: - max: 1 ---- - -# Intelligent Priority Triage - -When an issue is created, analyze its content to set priority and effort. - -Analyze the issue description for: -- Security vulnerabilities → Priority: "Critical", add to "Security" project -- Production crashes or data loss → Priority: "High", Effort: "Medium" -- Performance degradation → Priority: "High", Effort: "Large" -- Minor bugs or improvements → Priority: "Low", Effort: "Small" - -Add to "Engineering Backlog" project with calculated priority and effort fields. -``` - -**Why use ProjectOps:** Native GitHub automation can't analyze issue content to determine priority - it only reacts to labels and status changes. - - ## Project Management Features