diff --git a/.github/actions/issue-auto-implement/README.md b/.github/actions/issue-auto-implement/README.md index b118034..755569b 100644 --- a/.github/actions/issue-auto-implement/README.md +++ b/.github/actions/issue-auto-implement/README.md @@ -5,15 +5,19 @@ Reusable composite action for label-triggered issue automation: assess (request ## How to use (quick start) 1. **Workflow** — Ensure `.github/workflows/issue-auto-implement.yml` exists and calls this action (see the workflow in this repo for the exact `on:` and `uses:`). If implement might change workflow files, see [CI/CD](#cicd-what-you-need-to-run-this-workflow) for push permission requirements. -2. **Secrets and variables** — In the repo: Settings → Secrets and variables → Actions. Add secret **`AUTO_IMPLEMENT_ANTHROPIC_API_KEY`** (Anthropic API key). For who can trigger, set **one** of: **`AUTO_IMPLEMENT_ALLOWED_TRIGGER_MIN_PERMISSION`** (e.g. `push` or `maintain`; works with default token) or **`AUTO_IMPLEMENT_ALLOWED_TRIGGER_TEAM`** (e.g. `org/team`; token needs `read:org`). +2. **Secrets and variables** — In the repo: Settings → Secrets and variables → Actions. Add secret **`AUTO_IMPLEMENT_ANTHROPIC_API_KEY`** (Anthropic API key). Optionally add **`AUTO_IMPLEMENT_GITHUB_PUSH_TOKEN`** (a PAT with `repo` scope) so CI checks run on bot-created PRs (see [CI checks on bot-created PRs](#ci-checks-on-bot-created-prs)). For who can trigger, set **one** of: **`AUTO_IMPLEMENT_ALLOWED_TRIGGER_MIN_PERMISSION`** (e.g. `push` or `maintain`; works with default token) or **`AUTO_IMPLEMENT_ALLOWED_TRIGGER_TEAM`** (e.g. `org/team`; token needs `read:org`). 3. **Trigger label** — Create the labels once so you can add them to issues. Either run the **Issue auto-implement setup** workflow (Actions → Issue auto-implement setup → Run workflow), which creates `automation/auto-implement`, `automation/needs-info`, and `automation/pr-created`; or create the trigger label **`automation/auto-implement`** manually in the repo (Settings or Issues → Labels). The main action also ensures these labels exist when it runs, but the trigger label must exist before you can add it to an issue. 4. **Trigger** — On an issue, add the label `automation/auto-implement`. The workflow runs: it assesses the issue (request more info vs implement), and if implement, runs the Claude Code CLI and opens a PR. You can also comment on the issue (to add context and re-trigger) or review the PR (to iterate). -## CI and approval for bot-created PRs +## CI checks on bot-created PRs -PRs created by the action use `GITHUB_TOKEN`, so GitHub does not trigger `pull_request` workflows on them. This action therefore triggers the **test** workflow via `workflow_dispatch` on the new branch after creating a PR, so CI checks appear. The **test** workflow must include `workflow_dispatch:` in its `on:` block. +By default, PRs created with `GITHUB_TOKEN` do not trigger `pull_request` workflows (a GitHub restriction to prevent recursive runs). To get CI checks on bot-created PRs, set the optional **`push_token`** input to a PAT or GitHub App installation token. The action uses this token for `git push` and PR creation, so GitHub sees events from a non-Actions identity and triggers all `pull_request` workflows normally. Accepted token types: -To require a human to approve workflow runs before they execute (e.g. for security), set **Settings → Actions → General → Approval for running fork pull request workflows from contributors** to **Require approval for all external contributors**. Then each bot-created PR will show workflow(s) awaiting approval until someone with write access approves. +- **Personal Access Token (classic)** — `repo` scope +- **Personal Access Token (fine-grained)** — `contents: write` + `pull-requests: write` permissions +- **GitHub App installation token** — same permissions (e.g. via `actions/create-github-app-token`) + +If `push_token` is not set, the action falls back to `github_token` and CI workflows will not trigger automatically on bot PRs. ## Extra workflow runs when the action adds labels @@ -36,6 +40,7 @@ Used by `.github/workflows/issue-auto-implement.yml`. Requires `anthropic_api_ke | `max_implement_retries` | No | 3 | Max retries on verify failure (cap 5) | | `github_allowed_trigger_team` | No* | - | Team slug (e.g. org/team); only members can trigger. Repo variable `AUTO_IMPLEMENT_ALLOWED_TRIGGER_TEAM`. Ignored if min_permission is set. Token needs read:org. | | `github_allowed_trigger_min_permission` | No* | - | Require actor has at least this repo permission: triage, push, maintain, or admin. Repo variable `AUTO_IMPLEMENT_ALLOWED_TRIGGER_MIN_PERMISSION`. Works with default GITHUB_TOKEN. | +| `push_token` | No | - | PAT or GitHub App installation token for git push and PR creation. When set, GitHub triggers `pull_request` workflows on bot PRs. Falls back to `github_token`. | | `post_pr_comment` | No | false | When true, post a comment on the issue linking to the new PR when one is created. | *One of `github_allowed_trigger_min_permission` or `github_allowed_trigger_team` must be set (via repo variables). @@ -47,7 +52,7 @@ Secrets and variables use an action-specific prefix (e.g. `AUTO_IMPLEMENT_`) so To use this action in GitHub Actions: 1. **Workflow** — Call the action from a workflow (e.g. `.github/workflows/issue-auto-implement.yml`) on `issues.labeled`, `issue_comment`, `pull_request_review`, and/or `pull_request_review_comment`. The job needs `contents: write`, `issues: write`, `pull-requests: write`. If the implement step may edit files under `.github/workflows/`, GitHub may reject the push; the workflow syntax has no `workflows` permission key. Enable **Settings → Actions → General → Allow GitHub Actions to create and approve pull requests** (or use a PAT with appropriate scope) so the run can push workflow file changes. -2. **Secrets** — Add **`AUTO_IMPLEMENT_ANTHROPIC_API_KEY`** (repo secret). Used for the assess step and passed to the Claude Code CLI in the implement step. +2. **Secrets** — Add **`AUTO_IMPLEMENT_ANTHROPIC_API_KEY`** (repo secret). Used for the assess step and passed to the Claude Code CLI in the implement step. Optionally add **`AUTO_IMPLEMENT_GITHUB_PUSH_TOKEN`** (a PAT with `repo` scope, or fine-grained with `contents: write` + `pull-requests: write`) so CI checks run on bot-created PRs. 3. **Variables (trigger gate)** — Set **one** of: - **`AUTO_IMPLEMENT_ALLOWED_TRIGGER_MIN_PERMISSION`** (repo variable): `triage`, `push`, `maintain`, or `admin`. Only users with at least this repo permission can trigger. Works with default `GITHUB_TOKEN`. - **`AUTO_IMPLEMENT_ALLOWED_TRIGGER_TEAM`** (repo variable): org/team slug (e.g. `org/team-name`). Only team members can trigger. Token must have `read:org` (use a PAT if `GITHUB_TOKEN` lacks it). @@ -59,6 +64,7 @@ No other setup is required. Optionally set `verify_commands` (default `go test . ## Secrets and variables (repo setup) - **`AUTO_IMPLEMENT_ANTHROPIC_API_KEY`** (repo secret) — Claude API key for the assess and implement steps. Add under Settings → Secrets and variables → Actions. +- **`AUTO_IMPLEMENT_GITHUB_PUSH_TOKEN`** (repo secret, optional) — PAT or GitHub App installation token for git push and PR creation. When set, GitHub triggers `pull_request` workflows on bot PRs so CI checks appear. See [CI checks on bot-created PRs](#ci-checks-on-bot-created-prs) for accepted token types. - **Trigger gate (set one):** - **`AUTO_IMPLEMENT_ALLOWED_TRIGGER_MIN_PERMISSION`** (repo variable) — Require the triggering user to have at least this repo permission: `triage`, `push`, `maintain`, or `admin`. Works with the default `GITHUB_TOKEN`. Add under Settings → Secrets and variables → Actions → Variables. - **`AUTO_IMPLEMENT_ALLOWED_TRIGGER_TEAM`** (repo variable) — GitHub Team slug (e.g. `org/team-name`) whose members may trigger. The first step checks `github.actor` against this team. The token needs `read:org`; if `GITHUB_TOKEN` lacks it, use a PAT and pass it as `github_token`. diff --git a/.github/actions/issue-auto-implement/action.yml b/.github/actions/issue-auto-implement/action.yml index 82559f5..e450d2a 100644 --- a/.github/actions/issue-auto-implement/action.yml +++ b/.github/actions/issue-auto-implement/action.yml @@ -33,6 +33,9 @@ inputs: github_allowed_trigger_min_permission: description: 'Alternative to team check: require actor has at least this repo permission (triage, push, maintain, admin). Works with default GITHUB_TOKEN. Set via repo variable AUTO_IMPLEMENT_ALLOWED_TRIGGER_MIN_PERMISSION.' required: false + push_token: + description: 'Optional PAT or GitHub App token for git push and PR creation. When provided, push and PR-creation use this token so GitHub triggers pull_request workflows (GITHUB_TOKEN does not trigger them). Falls back to github_token.' + required: false post_pr_comment: description: 'When true, post a comment on the issue linking to the new PR when one is created' required: false @@ -178,9 +181,13 @@ runs: env: ISSUE_NUMBER: ${{ steps.assess.outputs.issue_number }} GITHUB_ACTOR: ${{ github.actor }} + PUSH_TOKEN: ${{ inputs.push_token || inputs.github_token }} + REPO: ${{ github.repository }} run: | git config user.name "$GITHUB_ACTOR" git config user.email "$GITHUB_ACTOR@users.noreply.github.com" + # Use push_token for push operations so GitHub triggers pull_request workflows + git remote set-url origin "https://x-access-token:${PUSH_TOKEN}@github.com/${REPO}.git" BRANCH="auto-implement-issue-${ISSUE_NUMBER}" git fetch origin main if git show-ref --verify --quiet refs/remotes/origin/"$BRANCH"; then @@ -294,18 +301,12 @@ runs: "https://api.github.com/repos/$REPO/issues/$PR_NUMBER/comments" \ -d "$(jq -n --arg b "$BODY" '{body: $b}')" echo "Posted comment on PR #$PR_NUMBER" - # Trigger test workflow so checks appear on the updated PR - curl -s -X POST \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - "https://api.github.com/repos/$REPO/actions/workflows/test.yml/dispatches" \ - -d "$(jq -n --arg ref "$HEAD_REF" '{ref: $ref}')" - echo "Triggered test workflow on ref $HEAD_REF" - name: Create PR if: steps.assess.outputs.action == 'implement' && steps.implement_verify_loop.outcome == 'success' && github.event_name != 'pull_request_review' && github.event_name != 'pull_request_review_comment' && !(github.event_name == 'issue_comment' && github.event.issue.pull_request) shell: bash env: GITHUB_TOKEN: ${{ inputs.github_token }} + PUSH_TOKEN: ${{ inputs.push_token || inputs.github_token }} REPO: ${{ github.repository }} ISSUE_NUMBER: ${{ steps.assess.outputs.issue_number }} LABEL_PREFIX: ${{ inputs.label_prefix }} @@ -317,8 +318,9 @@ runs: TITLE="${PR_TITLE:-Implement issue #${ISSUE_NUMBER}}" BODY="${PR_BODY:-Closes #${ISSUE_NUMBER}}" PAYLOAD=$(jq -n --arg t "$TITLE" --arg b "$BODY" --arg h "$BRANCH" '{title: $t, body: $b, head: $h, base: "main"}') + # Use push_token for PR creation so GitHub triggers pull_request workflows PR_JSON=$(curl -s -X POST \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Authorization: Bearer $PUSH_TOKEN" \ -H "Accept: application/vnd.github+json" \ "https://api.github.com/repos/$REPO/pulls" \ -d "$PAYLOAD") @@ -341,10 +343,3 @@ runs: echo "Posted comment on issue #$ISSUE_NUMBER" fi fi - # Trigger test workflow on this branch so CI checks appear (PRs created by github-actions[bot] often don't trigger pull_request) - curl -s -X POST \ - -H "Authorization: Bearer $GITHUB_TOKEN" \ - -H "Accept: application/vnd.github+json" \ - "https://api.github.com/repos/$REPO/actions/workflows/test.yml/dispatches" \ - -d "$(jq -n --arg ref "$BRANCH" '{ref: $ref}')" - echo "Triggered test workflow on ref $BRANCH" diff --git a/.github/workflows/issue-auto-implement.yml b/.github/workflows/issue-auto-implement.yml index 9cb4c65..348e203 100644 --- a/.github/workflows/issue-auto-implement.yml +++ b/.github/workflows/issue-auto-implement.yml @@ -26,7 +26,6 @@ jobs: contents: write issues: write pull-requests: write - actions: write # trigger test workflow on PR branch so checks appear (PRs created by bot may not trigger pull_request) # To allow push when implement touches .github/workflows/*: repo Settings → Actions → General → # "Allow GitHub Actions to create and approve pull requests" (or use a PAT with workflow scope). No workflows: key in workflow syntax. # read:org only needed if using team check (AUTO_IMPLEMENT_ALLOWED_TRIGGER_TEAM) @@ -40,6 +39,7 @@ jobs: with: anthropic_api_key: ${{ secrets.AUTO_IMPLEMENT_ANTHROPIC_API_KEY }} github_token: ${{ secrets.GITHUB_TOKEN }} + push_token: ${{ secrets.AUTO_IMPLEMENT_GITHUB_PUSH_TOKEN }} github_allowed_trigger_min_permission: ${{ vars.AUTO_IMPLEMENT_ALLOWED_TRIGGER_MIN_PERMISSION }} github_allowed_trigger_team: ${{ vars.AUTO_IMPLEMENT_ALLOWED_TRIGGER_TEAM }} # Skip acceptance tests in verify (they need HOOKDECK_CLI_TESTING_API_KEY); unit tests use -short