diff --git a/workflow-templates/README.md b/workflow-templates/README.md new file mode 100644 index 0000000..24745ed --- /dev/null +++ b/workflow-templates/README.md @@ -0,0 +1,50 @@ +# Workflow templates + +Suggested workflows that show up in the Actions tab when creating a new workflow in any HarperFast repo. Currently this set wires the repo into the centralized AI review chain in [`HarperFast/ai-review-prompts`](https://github.com/HarperFast/ai-review-prompts). + +## The Claude AI workflow chain + +Four templates form one cohesive system. Adopt them together for a new repo: + +| Template | What it does | +|---|---| +| `claude-review.yml` | Reviews every PR. Posts inline findings + a concise top-level summary. | +| `claude-mention.yml` | Responds to `@claude …` in PR / issue comments. Read, edit, commit, push, open PRs. | +| `claude-issue-to-pr.yml` | Label an issue with `claude-fix:{typo,docs,deps,bug}` → Claude opens a PR with the fix. | +| `validate-caller-workflows.yml` | Structural lint for the caller files. Catches shadow jobs and mutable refs. Make this a required status check on `main`. | + +Each template is a thin caller of a reusable workflow in `HarperFast/ai-review-prompts`. The reusables hold the auth gate, prompt logic, and orchestration scripts; the caller pins to a specific SHA so updates are explicit. + +## New-repo onboarding checklist + +After dropping the templates into `.github/workflows/`: + +1. **Install the `HarperFast AI Workflows` GitHub App on the repo** (org admin action). The auth gate's org-token-mint step uses the App installation token; without it, the `authorize` job fails with a 401. The App needs `Members: Read` on the org and is installed once per consumer repo (or "all repositories" at the org level). + +2. **Secrets** (per-repo until org-level lands): + - `HARPERFAST_AI_CLIENT_ID` + - `HARPERFAST_AI_APP_PRIVATE_KEY` + - `ANTHROPIC_API_KEY` + - `AI_REVIEW_LOG_TOKEN` *(optional — threads each review run into a per-PR issue in `HarperFast/ai-review-log`)* + +3. **Labels** (issue-to-PR triggers — exact spellings, lowercase, colon, no trailing space): + - `claude-fix:typo` + - `claude-fix:docs` + - `claude-fix:deps` + - `claude-fix:bug` + +4. **`.node-version`** at the repo root containing the major Node version (e.g. `24`). The mention + issue-to-PR reusables use `node-version-file:` for `actions/setup-node`. + +5. **Branch protection on `main`**: make `validate / validate` a required status check. + +6. **`AGENTS.md`** (and a `CLAUDE.md` one-liner pointing at it) at the repo root: the agent reads these for repo-specific conventions. Mirror harper / harper-pro for shape. + +7. **Customize the templates**: + - `claude-review.yml` — pick the right `review-layers:` for the repo type; fill in `repo-specific-checks:` if there are surface-area concerns the shared layers don't cover. + - `claude-mention.yml` / `claude-issue-to-pr.yml` — set `setup-bun: true` for plugin repos that test under bun. Override `pre-commit-validation:` if the repo doesn't have `npm run test:unit` / `format:check`. + +## Bumping the pin + +The `uses:` ref and the `with.ai-review-prompts-ref` input on each caller pin to the same SHA. Bumping is one motion: change both lines on each of the four files to the new SHA from `HarperFast/ai-review-prompts` `main`. The structural validator (`validate-caller-workflows.yml`) enforces that both refs are 40-char SHAs. + +Coordinate pin bumps with the [HarperFast/ai-review-prompts changelog](https://github.com/HarperFast/ai-review-prompts/commits/main). diff --git a/workflow-templates/claude-issue-to-pr.properties.json b/workflow-templates/claude-issue-to-pr.properties.json new file mode 100644 index 0000000..3b0c1f3 --- /dev/null +++ b/workflow-templates/claude-issue-to-pr.properties.json @@ -0,0 +1,6 @@ +{ + "name": "Claude Issue to PR", + "description": "Label an issue with claude-fix:{typo,docs,deps,bug} and Claude makes the focused change + opens a PR. Thin caller of HarperFast/ai-review-prompts.", + "iconName": "blank", + "categories": ["Continuous Integration"] +} diff --git a/workflow-templates/claude-issue-to-pr.yml b/workflow-templates/claude-issue-to-pr.yml new file mode 100644 index 0000000..953d0e0 --- /dev/null +++ b/workflow-templates/claude-issue-to-pr.yml @@ -0,0 +1,39 @@ +name: Claude Issue to PR + +# Thin caller of HarperFast/ai-review-prompts' `_claude-issue-to-pr.yml`. +# Labeling an issue with `claude-fix:typo`, `claude-fix:docs`, +# `claude-fix:deps`, or `claude-fix:bug` kicks Claude off to make a +# focused, label-scoped change and open a PR back. +# +# Per-repo setup: +# 1. Secrets: see `claude-review.yml`. +# 2. Add `.node-version` to the repo root. +# 3. Create the four `claude-fix:*` labels (typo / docs / deps / bug) +# — the reusable's auth-gate hard-codes this set. +# 4. Set `setup-bun: true` if your repo's tests/scripts run via bun. + +on: + issues: + types: [labeled] + +concurrency: + group: claude-issue-${{ github.event.issue.number }} + cancel-in-progress: false + +jobs: + work: + uses: HarperFast/ai-review-prompts/.github/workflows/_claude-issue-to-pr.yml@f6daed301f8a7ece74593506de38c6e80820b00b # main 2026-05-06 + with: + ai-review-prompts-ref: f6daed301f8a7ece74593506de38c6e80820b00b + # Uncomment / customize as needed: + # setup-bun: true + # repo-specific-conventions: | + # ## Repo-specific notes + # - (linter quirks, runtime engine, package conventions) + # pre-commit-validation: | + # (override only if the default label-scoped Node flow doesn't + # match this repo's scripts) + secrets: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + HARPERFAST_AI_CLIENT_ID: ${{ secrets.HARPERFAST_AI_CLIENT_ID }} + HARPERFAST_AI_APP_PRIVATE_KEY: ${{ secrets.HARPERFAST_AI_APP_PRIVATE_KEY }} diff --git a/workflow-templates/claude-mention.properties.json b/workflow-templates/claude-mention.properties.json new file mode 100644 index 0000000..fe377fb --- /dev/null +++ b/workflow-templates/claude-mention.properties.json @@ -0,0 +1,6 @@ +{ + "name": "Claude Mention Handler", + "description": "Respond to @claude mentions in PR or issue comments. Claude can read context, edit code, push commits, open PRs. Thin caller of HarperFast/ai-review-prompts.", + "iconName": "blank", + "categories": ["Continuous Integration"] +} diff --git a/workflow-templates/claude-mention.yml b/workflow-templates/claude-mention.yml new file mode 100644 index 0000000..0c65616 --- /dev/null +++ b/workflow-templates/claude-mention.yml @@ -0,0 +1,43 @@ +name: Claude Mention Handler + +# Thin caller of HarperFast/ai-review-prompts' `_claude-mention.yml`. +# Responds to `@claude …` (as the first non-whitespace token) in PR +# or issue comments. Add the word `deep` to escalate to Opus. +# +# Per-repo setup: +# 1. Secrets: see `claude-review.yml` (same set, minus the optional +# AI_REVIEW_LOG_TOKEN which mention doesn't use). +# 2. Add `.node-version` to the repo root (the reusable uses +# `node-version-file: '.node-version'` for setup-node). +# 3. Set `setup-bun: true` if your repo's tests/scripts run via bun. +# 4. Customize `repo-specific-conventions` and `pre-commit-validation` +# below if the reusable's defaults (Node-only, npm test:unit) +# don't match your scripts. + +on: + issue_comment: + types: [created] + pull_request_review_comment: + types: [created] + +concurrency: + group: claude-mention-${{ github.event.issue.number || github.event.pull_request.number }} + cancel-in-progress: false + +jobs: + mention: + uses: HarperFast/ai-review-prompts/.github/workflows/_claude-mention.yml@f6daed301f8a7ece74593506de38c6e80820b00b # main 2026-05-06 + with: + ai-review-prompts-ref: f6daed301f8a7ece74593506de38c6e80820b00b + # Uncomment / customize as needed: + # setup-bun: true + # repo-specific-conventions: | + # ## Repo-specific notes + # - (linter quirks, runtime engine, package conventions) + # pre-commit-validation: | + # (override only if the default Node-only flow doesn't match + # this repo's scripts; the default is fine for most Harper repos) + secrets: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + HARPERFAST_AI_CLIENT_ID: ${{ secrets.HARPERFAST_AI_CLIENT_ID }} + HARPERFAST_AI_APP_PRIVATE_KEY: ${{ secrets.HARPERFAST_AI_APP_PRIVATE_KEY }} diff --git a/workflow-templates/claude-review.properties.json b/workflow-templates/claude-review.properties.json new file mode 100644 index 0000000..ac68679 --- /dev/null +++ b/workflow-templates/claude-review.properties.json @@ -0,0 +1,6 @@ +{ + "name": "Claude PR Review", + "description": "Auto-review every PR with Claude. Posts inline findings + a concise top-level summary. Thin caller of HarperFast/ai-review-prompts.", + "iconName": "blank", + "categories": ["Code Quality", "Continuous Integration"] +} diff --git a/workflow-templates/claude-review.yml b/workflow-templates/claude-review.yml new file mode 100644 index 0000000..5a34ca2 --- /dev/null +++ b/workflow-templates/claude-review.yml @@ -0,0 +1,52 @@ +name: Claude PR Review + +# Thin caller of HarperFast/ai-review-prompts' `_claude-review.yml`. +# Posts inline findings + a concise top-level summary on every PR. +# Per-repo customization: review-layers + repo-specific-checks below. +# +# Per-repo setup: +# 1. Configure secrets: +# - HARPERFAST_AI_CLIENT_ID +# - HARPERFAST_AI_APP_PRIVATE_KEY +# - ANTHROPIC_API_KEY +# - AI_REVIEW_LOG_TOKEN (optional; threads run notes into a per-PR +# issue in HarperFast/ai-review-log) +# 2. Pair with `claude-mention.yml`, `claude-issue-to-pr.yml`, and +# `validate-caller-workflows.yml` from this same template set. + +on: + pull_request: + types: [opened, synchronize, reopened] + +concurrency: + group: claude-review-${{ github.event.pull_request.number }} + cancel-in-progress: true + +jobs: + review: + uses: HarperFast/ai-review-prompts/.github/workflows/_claude-review.yml@f6daed301f8a7ece74593506de38c6e80820b00b # main 2026-05-06 + with: + # Same SHA as the `uses:` ref above. The reusable uses this to + # check out HarperFast/ai-review-prompts (layer files + bash + # scripts) at the same ref as the workflow logic itself. + ai-review-prompts-ref: f6daed301f8a7ece74593506de38c6e80820b00b + # Layered review scope. Drop layers that don't apply, or add + # `repo-type/plugin` (or another repo-type layer) if relevant. + # Available layers live in HarperFast/ai-review-prompts. + review-layers: | + universal + harper/common + harper/v5 + # Markdown block injected after the layered scope. Use for + # repo-specific bullets the shared layers don't cover (e.g. an + # OAuth-only CSRF check, a Pro-only API surface). Keep it short; + # broader conventions belong in this repo's AGENTS.md. + repo-specific-checks: | + ## Repo-specific checks + + - (replace this with concrete bullets, or delete the block) + secrets: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + AI_REVIEW_LOG_TOKEN: ${{ secrets.AI_REVIEW_LOG_TOKEN }} + HARPERFAST_AI_CLIENT_ID: ${{ secrets.HARPERFAST_AI_CLIENT_ID }} + HARPERFAST_AI_APP_PRIVATE_KEY: ${{ secrets.HARPERFAST_AI_APP_PRIVATE_KEY }} diff --git a/workflow-templates/validate-caller-workflows.properties.json b/workflow-templates/validate-caller-workflows.properties.json new file mode 100644 index 0000000..aee60b5 --- /dev/null +++ b/workflow-templates/validate-caller-workflows.properties.json @@ -0,0 +1,6 @@ +{ + "name": "Validate Claude caller workflows", + "description": "Structural validation for the Claude caller workflows in this repo. Catches shadow jobs and mutable refs. Pair with the other Claude templates.", + "iconName": "blank", + "categories": ["Code Quality", "Continuous Integration"] +} diff --git a/workflow-templates/validate-caller-workflows.yml b/workflow-templates/validate-caller-workflows.yml new file mode 100644 index 0000000..927ceb4 --- /dev/null +++ b/workflow-templates/validate-caller-workflows.yml @@ -0,0 +1,25 @@ +name: Validate caller workflows + +# Thin caller of HarperFast/ai-review-prompts' +# `_validate-caller-workflows.yml`. Validates this repo's +# `.github/workflows/claude-*.yml` files for shadow jobs and +# mutable refs. +# +# Runs on every PR and every push to `main` — no `paths:` filter. +# A required status check that only fires on workflow-touching PRs +# stays permanently pending on every other PR (GitHub has no +# "required if it runs" semantic). The validator's runtime is +# trivial, so unconditional firing is the right trade-off. +# +# Make this `validate` job a REQUIRED status check on `main`. + +on: + pull_request: + push: + branches: [main] + +jobs: + validate: + uses: HarperFast/ai-review-prompts/.github/workflows/_validate-caller-workflows.yml@f6daed301f8a7ece74593506de38c6e80820b00b # main 2026-05-06 + with: + ai-review-prompts-ref: f6daed301f8a7ece74593506de38c6e80820b00b