-
Notifications
You must be signed in to change notification settings - Fork 7
feat: add copy proofread review workflow #309
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
081fdc6
feat: add copy proofread review workflow
stepskop 645d4c7
fix: use the skill indirectly
stepskop 54f712c
chore: remove readme
stepskop 67b10b5
Potential fix for pull request finding
stepskop 08d2324
Potential fix for pull request finding
stepskop 779c4be
chore: better naming
stepskop File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,171 @@ | ||
| name: copy proofread review | ||
|
|
||
| # Proofreads the public-facing copy changed in a pull request against Apify's style guide and posts | ||
| # inline suggestions. Rules come from the `apify-proofreader` skill in apify/agent-skills-internal. | ||
| # | ||
| # The caller owns the trigger. See the README for a full caller example. | ||
|
|
||
| on: | ||
| workflow_call: | ||
| inputs: | ||
| paths: | ||
| description: Newline-separated list of paths (relative to the repo root) whose copy should be reviewed. Everything else in the diff is ignored. | ||
| required: true | ||
| type: string | ||
| repoInstructions: | ||
| description: >- | ||
| Repo-specific rules for telling copy apart from code, appended to the generic ones. Use it for | ||
| conventions the model cannot infer, e.g. which argument of a helper holds the human-readable message. | ||
| required: false | ||
| default: '' | ||
| type: string | ||
|
|
||
| secrets: | ||
| anthropicApiKey: | ||
| description: Anthropic API key used by the review agent. | ||
| required: true | ||
| agentSkillsRepoGithubToken: | ||
| description: GitHub token with read access to apify/agent-skills-internal. | ||
| required: true | ||
|
|
||
| # One run per PR; a second label-add while a run is in flight cancels the stale one. | ||
| concurrency: | ||
| group: copy-proofread-review-${{ github.event.pull_request.number || github.run_id }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| proofread: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 10 | ||
| permissions: | ||
| contents: read | ||
| issues: write # remove the trigger label when done | ||
| pull-requests: write # post the review + inline comments | ||
| steps: | ||
| - name: Check the secrets are set | ||
| # `secrets: inherit` does not bind these — pass them explicitly in the caller. | ||
| env: | ||
| ANTHROPIC_API_KEY: ${{ secrets.anthropicApiKey }} | ||
| AGENT_SKILLS_TOKEN: ${{ secrets.agentSkillsRepoGithubToken }} | ||
| run: | | ||
| set -euo pipefail | ||
| missing=() | ||
| [[ -n "${ANTHROPIC_API_KEY:-}" ]] || missing+=(anthropicApiKey) | ||
| [[ -n "${AGENT_SKILLS_TOKEN:-}" ]] || missing+=(agentSkillsRepoGithubToken) | ||
| if (( ${#missing[@]} )); then | ||
| echo "::error::Missing secrets: ${missing[*]}. Pass them explicitly in the caller's \`secrets:\` block — \`secrets: inherit\` does not work here." | ||
| exit 1 | ||
| fi | ||
|
|
||
| - name: Checkout repository | ||
| uses: actions/checkout@v6 | ||
| with: | ||
| # The diff comes from `gh pr diff` (API-backed) and files are read from the working tree. | ||
| fetch-depth: 1 | ||
|
|
||
| - name: Check out the apify-proofreader skill | ||
| # Checked out here rather than under `.claude/` — claude-code-action wipes and restores `.claude/` | ||
| # from the PR base branch before running Claude. | ||
| uses: actions/checkout@v6 | ||
| with: | ||
| repository: apify/agent-skills-internal | ||
| token: ${{ secrets.agentSkillsRepoGithubToken }} | ||
| path: .agent-skills | ||
| sparse-checkout: skills/apify-proofreader | ||
| fetch-depth: 1 | ||
|
|
||
| - name: Proofread public-facing copy | ||
| uses: anthropics/claude-code-action@v1 | ||
| env: | ||
| GH_TOKEN: ${{ github.token }} | ||
| with: | ||
| anthropic_api_key: ${{ secrets.anthropicApiKey }} | ||
| github_token: ${{ github.token }} | ||
| show_full_output: true | ||
| prompt: | | ||
| You are running inside a GitHub Actions workflow on pull request #${{ github.event.pull_request.number }} | ||
| in repository ${{ github.repository }}. Your | ||
| single job: proofread the **public-facing copy** changed in this PR against Apify's style guide and | ||
| post inline suggestions. You do NOT approve, request changes, or comment on anything else. | ||
|
|
||
| ## Authority: the apify-proofreader skill | ||
| Use the `apify-proofreader` skill (checked out to .agent-skills/skills/apify-proofreader/SKILL.md by | ||
| a previous CI step) as the ONLY source of style rules. Read that SKILL.md first and apply exactly | ||
| those rules — sentence case, "Actor" capitalization, US spelling, no em/en dashes, AI-fluff removal, | ||
| etc. Do not invent rules beyond it. If the file is missing, post a single PR comment saying the | ||
| skill is not installed and stop. | ||
|
|
||
| ## Scope — ONLY these paths, and ONLY the copy within them | ||
| Consider ONLY changed hunks (lines beginning `+`) under: | ||
| ${{ inputs.paths }} | ||
| Ignore every other file in the diff. | ||
|
|
||
| ## Distinguish copy from code — comment ONLY on copy | ||
| You MUST tell code apart from human-facing copy and only flag the copy. Copy is natural language a | ||
| user reads. Everything else is code and must be reproduced byte-for-byte: identifiers, object keys, | ||
| placeholders and format syntax (`{count}`, `{actorCount, plural, ...}`, `{type, select, ...}`), markup | ||
| and JSX tags, imports, component and prop names, `className`, style objects, URLs, error codes, and | ||
| HTTP status codes. Proofread only the natural-language words around them. | ||
| If you are unsure whether something is copy or code, do NOT comment on it. | ||
| ${{ inputs.repoInstructions }} | ||
|
|
||
| ## How to post feedback — inline suggestions on changed lines only | ||
| For each real style violation on a `+` (added/changed) line: | ||
| - Use `mcp__github_inline_comment__create_inline_comment` to attach a comment to that exact line. | ||
| - Prefer a ready-to-apply suggestion. The comment body must be one short sentence naming the rule, | ||
| followed by a suggestion block that reproduces the WHOLE line with only the copy corrected and | ||
| all surrounding code/keys/placeholders/tags intact: | ||
|
|
||
| <the style rule in one sentence> | ||
| ```suggestion | ||
| <the full corrected line, code untouched> | ||
| ``` | ||
| - If the fix is ambiguous (e.g. an ambiguous numeric date/number per the skill, an unlisted brand | ||
| name, or copy whose intended meaning is unclear), leave a comment WITHOUT a suggestion block and | ||
| ask the author to revise. NEVER pack several issues into one prose paragraph — format it as one | ||
| short lead sentence, then a bulleted list with ONE issue per bullet, each quoting the offending | ||
| text first: | ||
|
|
||
| <one sentence: what you need from the author and why there's no suggestion> | ||
|
|
||
| - `"<offending text>"` — <the problem and the fix, one clause> (Rule N) | ||
| - `"<offending text>"` — <the problem and the fix, one clause> (Rule N) | ||
| - Comment only on lines that are part of this PR's diff. One comment per issue; do not repeat the | ||
| same issue on many lines — cover the first and mention the pattern once. Post each finding | ||
| exactly once: if `create_inline_comment` returns an error, fix the arguments and retry, but never | ||
| post a second, reworded version of a comment that already landed. | ||
|
|
||
| ## Finish | ||
| - After adding inline comments, post ONE top-level PR comment via `gh pr comment` listing the files | ||
| reviewed and the themes found (e.g. "3 sentence-case fixes, 1 em dash"). Keep it to a few bullets. | ||
| - Do NOT narrate your own method or scope in that comment. Never write sentences about what you | ||
| left untouched or how you distinguished copy from code (e.g. "I checked the string values only, | ||
| leaving object keys, ICU syntax, placeholders, and markup tags untouched") — that's plumbing, not | ||
| feedback. Report findings only. | ||
| - End the comment with a line crediting the rule source, exactly: | ||
| `Rules: [apify-proofreader](https://github.com/apify/agent-skills-internal/blob/main/skills/apify-proofreader/SKILL.md)` | ||
| - If you found NO violations, post a single top-level comment: "✅ Copy proofread — no style | ||
| issues found in the changed copy." plus that same `Rules:` line. Do not add inline comments in | ||
| that case. | ||
| - NEVER approve or request changes. You are only leaving comments. | ||
| claude_args: | | ||
| --max-turns 25 | ||
| --allowedTools "Read,Glob,Grep,mcp__github_inline_comment__create_inline_comment,Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr comment:*),Bash(cat:*),Bash(ls:*),Bash(grep:*),Bash(find:*)" | ||
|
|
||
| - name: Remove trigger label | ||
| # Re-adding it re-runs the review. | ||
| if: always() && github.event.label.name != '' | ||
| uses: actions/github-script@v9 | ||
| with: | ||
| github-token: ${{ github.token }} | ||
| script: | | ||
| try { | ||
| await github.rest.issues.removeLabel({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: context.payload.pull_request.number, | ||
| name: context.payload.label.name, | ||
| }); | ||
| } catch (error) { | ||
| if (error.status !== 404) throw error; | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.