Skip to content

Commit 6097f79

Browse files
authored
[CHORE] Migrate PRojection GHA/Workflow here for reusability (#20)
* Create overture-projection.yml Signed-off-by: John McCall <john@overturemaps.org> * Update overture-projection.yml Signed-off-by: John McCall <john@overturemaps.org> * Update overture-projection.yml Signed-off-by: John McCall <john@overturemaps.org> * Add Overture PRojection GitHub Action Introduce a new GitHub Action 'overture-projection' that posts AI-generated PR review comments driven by reusable "skills". Adds action metadata (action.yml), a detailed README, multiple step scripts (load-skills, fetch-diff, select-skills, fetch-context, post-review) and library modules with unit tests for defaults, diff handling, and context processing. The action supports GitHub Models and Anthropic providers, handles skill selection, per-file context fetching/truncation, diff budgeting, and generates/upserts review comments using an installation or workflow token. Signed-off-by: John McCall <john@overturemaps.org> * Update overture-projection.yml Signed-off-by: John McCall <john@overturemaps.org> * fix: reference composite action by full repo path for reusable workflow context Signed-off-by: John McCall <john@overturemaps.org> * fix: scope app token to omf-devex and target repo only, not all org repos Signed-off-by: John McCall <john@overturemaps.org> * Update action.yml Signed-off-by: John McCall <john@overturemaps.org> * overture-projection: CRLF fixes & workflow updates Multiple fixes and workflow improvements for the overture-projection action: - Make frontmatter/markdown parsing robust to CRLF line endings (skills.js, markdown.js). - Improve fetch-diff comment to clarify file-dropping behavior order. - Fix unit test setup that clobbered global fetch in models.test.js. - Validate SKILLS_DIR presence and warn when empty/missing (load-skills.js). - Adjust COMMENT_MODE docs/default wording and fail early if PR number can't be resolved (post-review.js). - Add a dedicated unit test workflow for the action scripts (overture-projection-tests.yml). - Update main workflow to use the reusable-workflows repo, add conditional input handling for dispatch vs PR runs, and simplify header comments (overture-projection.yml). - README updates: clarify per-file context cap default (max-context-file-chars) and reference the reusable workflow commit. These changes improve cross-platform robustness, error handling, and CI ergonomics. Signed-off-by: John McCall <john@overturemaps.org> * Update action.yml Signed-off-by: John McCall <john@overturemaps.org> * Update overture-projection.yml Signed-off-by: John McCall <john@overturemaps.org> * Update action.yml Signed-off-by: John McCall <john@overturemaps.org> * Update overture-projection.yml Signed-off-by: John McCall <john@overturemaps.org> * Add concurrency, secure secrets, and permissions Enable single active run per PR with a concurrency group and cancel-in-progress behavior; move write/read permissions for PRs, issues, and models to the job scope and keep only contents: read at top-level. Improve secrets handling in the action: add explanatory masks for template-expanded inputs and set checkout persist-credentials: false to avoid leaking tokens to the checked-out workspace. Add inline justifications for unpinned action usage and org secrets usage for reviewers. Signed-off-by: John McCall <john@overturemaps.org> * Update workflows: annotations, concurrency, checkout Add zizmor lint ignore annotations in the overture-projection action to suppress template-injection/unpinned-uses warnings for intentional literal values and local script usage. Enable concurrency in the test workflow to cancel in-progress test runs for the same PR/run, and set actions/checkout persist-credentials: false in the tests job to avoid leaving credentials in the workspace. Tidy comments in the main workflow's uses/secret entries by moving lint ignores inline. Signed-off-by: John McCall <john@overturemaps.org> * Update action.yml Signed-off-by: John McCall <john@overturemaps.org> * Update action.yml Signed-off-by: John McCall <john@overturemaps.org> --------- Signed-off-by: John McCall <john@overturemaps.org>
1 parent b031ec9 commit 6097f79

25 files changed

Lines changed: 4102 additions & 0 deletions
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# Overture PRojection
2+
3+
Posts an AI-generated code review comment on a pull request. Skills drive what the model looks for — each skill is a `SKILL.md` file that provides focused review instructions for a particular concern.
4+
5+
Supports [GitHub Models](https://docs.github.com/en/github-models) (default) and [Anthropic](https://docs.anthropic.com/en/docs/about-claude/models) as model providers.
6+
7+
## How it works
8+
9+
1. **Load skills** — sparse-checkouts `omf-devex/skills/`, parses frontmatter, filters to `pr-reviewer` surface. Raw content is stored; nothing is fetched yet.
10+
2. **Fetch PR diff** — title, body, branch refs, closing issues (GraphQL), and changed file patches up to `max-diff-chars`.
11+
3. **Select skills** — a fast/cheap model reads skill descriptions and changed file paths, picks which optional skills apply, and logs its reasoning. `always-skills` bypass this step entirely.
12+
4. **Fetch context files** — only for selected skills; fetched in parallel via the GitHub App token, compressed, and capped per file at `max-context-file-chars` (defaults to 10% of the input token budget).
13+
5. **Post review** — builds system prompt from selected skills + context, trims the diff to the remaining token budget, calls the review model, and posts or updates a PR comment.
14+
15+
## Recipes
16+
17+
### GitHub Copilot (default)
18+
19+
No extra secrets needed beyond the standard workflow token.
20+
21+
```yaml
22+
permissions:
23+
contents: read
24+
pull-requests: write
25+
issues: read
26+
models: read
27+
28+
steps:
29+
- uses: OvertureMaps/workflows/.github/actions/overture-projection@030d1cf86ff0013daa6f41ba0073cf048ec2d494 # reusable-PRojection-workflow
30+
with:
31+
github-token: ${{ secrets.GITHUB_TOKEN }}
32+
app-private-key: ${{ secrets.OVERTURE_PROJECTION_APP_PEM }}
33+
```
34+
35+
**Automatic defaults** (GitHub Models gpt-4.1, 8,000 token context window):
36+
37+
| Input | Auto default |
38+
| --- | --- |
39+
| `model` | `gpt-4.1` |
40+
| `selection-model` | `gpt-4.1-mini` |
41+
| `max-input-tokens` | `6200` (= 8,000 − 1 500 output − 300 margin) |
42+
| `max-output-tokens` | `1500` |
43+
44+
### Anthropic
45+
46+
Add `ANTHROPIC_API_KEY` as a repo or org secret. All current Claude models have a 200k token context window.
47+
48+
```yaml
49+
permissions:
50+
contents: read
51+
pull-requests: write
52+
issues: read
53+
54+
steps:
55+
- uses: OvertureMaps/workflows/.github/actions/overture-projection@030d1cf86ff0013daa6f41ba0073cf048ec2d494 # reusable-PRojection-workflow
56+
with:
57+
model-provider: anthropic
58+
model: claude-opus-4-6
59+
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
60+
app-private-key: ${{ secrets.OVERTURE_PROJECTION_APP_PEM }}
61+
```
62+
63+
Token limits (`max-input-tokens`, `max-output-tokens`) default automatically to the right values for the provider — you only need to set them if you're using a model with a non-standard context window.
64+
65+
**Automatic defaults** (Anthropic 200k context window):
66+
67+
| Input | Auto default |
68+
| --- | --- |
69+
| `model` | `claude-opus-4-6` |
70+
| `selection-model` | `claude-haiku-4-6` |
71+
| `max-input-tokens` | `190000` (= 200k − 4,096 output − ~6,000 margin) |
72+
| `max-output-tokens` | `4096` |
73+
74+
Note: `models: read` permission is not required when using Anthropic.
75+
76+
## Inputs
77+
78+
### Provider
79+
80+
| Input | Default | Description |
81+
| --- | --- | --- |
82+
| `model-provider` | `github-models` | `github-models` or `anthropic` |
83+
| `model` | _(default)_ | Model ID for the review. Defaults to `gpt-4.1` (github-models) or `claude-opus-4-6` (anthropic) |
84+
| `selection-model` | _(default)_ | Model ID for skill selection. Defaults to `gpt-4.1-mini` (github-models) or `claude-haiku-4-6` (anthropic) |
85+
| `max-input-tokens` | _(default)_ | Max input tokens. Defaults to `6200` (github-models) or `190000` (anthropic). Override only for non-standard context windows |
86+
| `max-output-tokens` | _(default)_ | Max tokens the model may generate. Defaults to `1500` (github-models) or `4096` (anthropic) |
87+
| `github-token` | `github.token` | Token with `pull-requests:write`, `models:read`, and read access to `omf-devex`. Not used for model calls when `model-provider` is `anthropic` |
88+
| `anthropic-api-key` | _(empty)_ | Anthropic API key. Required when `model-provider` is `anthropic` |
89+
90+
### Auth
91+
92+
| Input | Default | Description |
93+
| --- | --- | --- |
94+
| `app-id` | `Iv23liBMB2dC9UQJ5pHL` | Overture PRojection GitHub App Client ID |
95+
| `app-private-key` | _(empty)_ | GitHub App private key (`secrets.OVERTURE_PROJECTION_APP_PEM`). Used to generate an installation token for cross-repo context file reads. Falls back to `github-token` if omitted |
96+
97+
### Behaviour
98+
99+
| Input | Default | Description |
100+
| --- | --- | --- |
101+
| `always-skills` | `pr-review` | Comma-separated skill names included on every run, bypassing model selection |
102+
| `devex-ref` | `main` | Git ref of `omf-devex` to load skills from |
103+
| `max-files` | `20` | Maximum number of changed files to fetch from the GitHub API |
104+
| `max-diff-chars` | `100000` | Fetch ceiling for diff content. The actual amount sent to the model is computed dynamically based on the remaining token budget after skills and metadata |
105+
| `max-context-file-chars` | _(default)_ | Hard cap per individual skill context file (the cross-repo files declared via `context-files:` in skill frontmatter — not the overall prompt context). Defaults to 10% of the input token budget (~2 500 chars for github-models, ~76 000 for anthropic). Set this to enforce a tighter ceiling regardless of token budget |
106+
| `comment-mode` | `update` | `update` edits the existing comment in place; `new` posts a fresh PR review each run |
107+
| `comment-tag` | `overture-projection` | Hidden HTML marker used to identify the managed comment in `update` mode |
108+
| `pr-number` | _(event)_ | PR number to review. Required for `workflow_dispatch` triggers |
109+
| `repository` | _(current repo)_ | Target repository in `owner/repo` format |
110+
| `dry-run` | `false` | Print the review body to the log without posting it |
111+
112+
## Token budget
113+
114+
The action computes the diff budget dynamically at review time:
115+
116+
```
117+
diff budget = (max-input-tokens × 4 chars/token) − system prompt chars − user prompt preamble chars
118+
```
119+
120+
Files are included whole (never truncated mid-diff); once the budget is exhausted, remaining files are listed in the review with a recommendation to split the PR.
121+
122+
`max-input-tokens` and `max-output-tokens` default automatically based on the provider (see `scripts/lib/defaults.js`). You only need to set them explicitly when using a model with a non-standard context window:
123+
124+
| Provider | `max-input-tokens` | `max-output-tokens` | Basis |
125+
| --- | --- | --- | --- |
126+
| `github-models` | `6200` | `1500` | 8,000 context − 1,500 output − 300 margin |
127+
| `anthropic` | `190000` | `4096` | 200k context − 4,096 output − ~6,000 margin |
128+
129+
## Skills
130+
131+
Skills live in `omf-devex/skills/<name>/SKILL.md`. The folder name is the skill ID — it must match the `name` frontmatter field and is what you pass to `always-skills`.
132+
133+
Only skills with `surfaces: [pr-reviewer]` (or no `surfaces` field) are loaded. Skills tagged `surfaces: [agent]` are filtered out before the selection model sees them.
134+
135+
- `always-skills` bypass selection and are always included in the system prompt.
136+
- All other `pr-reviewer` skills are passed to the selection model with their `description`; the model picks which are relevant to the PR.
137+
- `context-files` are fetched after selection, so only selected skills pay the network cost.
138+
139+
For full frontmatter field reference and authoring guidance see the [omf-devex README](../../../../README.md#skills).
140+
141+
## Required workflow permissions
142+
143+
```yaml
144+
permissions:
145+
contents: read # checkout
146+
pull-requests: write # post/update review comment
147+
issues: read # closingIssuesReferences GraphQL query
148+
models: read # GitHub Models API (not needed for anthropic provider)
149+
```

0 commit comments

Comments
 (0)