Skip to content

Commit 2bfcc12

Browse files
authored
Merge pull request #88 from githubnext/copilot/update-crane-pr-comments
Require rich Crane PR update comments
2 parents f77d95e + af5cd6e commit 2bfcc12

2 files changed

Lines changed: 73 additions & 4 deletions

File tree

.github/workflows/crane.md

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,22 @@ This Step 0 produces the plan and ships it as commit #1 on the migration branch
434434
2. Parse the JSON output. The required field is `migration_score`. Optional fields (`progress`, `parity_passing`, `parity_total`, `source_tests_passing`, `target_tests_passing`, `perf_ratio`) are logged in iteration history.
435435
3. Compare `migration_score` against `best_metric` from the state file.
436436

437+
### Accepted Iteration Summary
438+
439+
For every accepted iteration, build a **single shared source** summary before updating the PR, migration issue, or repo-memory. Reuse this same summary for the PR body, PR comment, migration issue comment, and repo-memory history so reviewers see the same facts everywhere.
440+
441+
Include, when available:
442+
- Iteration number and status (`Iteration {N} accepted`).
443+
- Current milestone or focus.
444+
- Concise change summary (one line, plus up to 3 compact bullets from the accepted iteration or commit body).
445+
- Commit short SHA linked to the commit URL, ignoring a `ci: trigger checks` commit unless it is the only new commit.
446+
- Workflow run URL.
447+
- Score with best score and signed delta.
448+
- Progress or parity (`parity_passing`/`parity_total`) if reported.
449+
- CI fix-attempt count, only when greater than zero.
450+
451+
If the accepted iteration summary already exists in the state file or migration issue, prefer it. If not, fall back to the accepted commit subject and the compact `Changes:` bullets from the commit body. Keep the rendered summary short: roughly 10 bullets or 1,000 characters maximum. Never paste full diffs or long test logs; link to the commit and workflow run for details.
452+
437453
### Step 5: Accept or Reject
438454

439455
Verification is necessary but **not sufficient** for acceptance. The agent's sandbox cannot reliably install many project toolchains, so a "score improved" signal from the sandbox can mask broken commits CI would catch. Acceptance must therefore be gated on **CI green** for the pushed HEAD commit. If CI fails, attempt to fix-and-retry within the same iteration rather than reverting.
@@ -454,7 +470,15 @@ The first run (no `best_metric` yet) always counts as an improvement.
454470

455471
1. Commit the changes to the long-running branch with a commit message:
456472
- Subject: `[Crane: {migration-name}] Iteration <N>: <short description of milestone or change>`
457-
- Body (after a blank line): `Run: {run_url}`
473+
- Body (after a blank line):
474+
```markdown
475+
Changes:
476+
- <compact bullet describing the main migrated unit or behavior change>
477+
- <optional second bullet with test/parity or milestone movement>
478+
479+
Run: {run_url}
480+
```
481+
Keep `Changes:` compact and structured so later PR comments can summarize the commit when score/progress fields are unavailable.
458482
2. Push the commit to the long-running branch.
459483
3. **Find or create the PR** so CI runs and `gh pr checks` has a target. Follow these steps in order:
460484
a. Check `existing_pr` from `/tmp/gh-aw/crane.json`. If it is not null, that is the existing draft PR -- use it as `$EXISTING_PR` below; **never** call `create-pull-request`.
@@ -499,15 +523,28 @@ If `status == "failure"`, **fix and retry -- do not revert, do not accept**:
499523
2. If a draft PR does not already exist for this branch, create one -- specify `branch: crane/{migration-name}` explicitly:
500524
- Title: `[Crane: {migration-name}]`
501525
- Body: summary of the migration (source -> target, strategy), link to the migration issue, current best score and progress, AI disclosure: `[bot] *This PR is maintained by Crane. Each accepted iteration adds a commit to this branch.*`
502-
If a draft PR already exists, use `push-to-pull-request-branch` (never `create-pull-request`). Update the PR body with the latest score and a summary of the most recent accepted iteration. Add a comment to the PR summarizing the iteration: what milestone was advanced, old score, new score, fix-attempt count if `> 0`, and a link to the actions run.
526+
If a draft PR already exists, use `push-to-pull-request-branch` (never `create-pull-request`). Do not rely on the automatic `push-to-pull-request-branch` "Commit pushed" comment as the only reviewer-facing update. Update the PR body with the latest score and the shared accepted iteration summary, then emit a separate `add-comment` safe output targeted at that PR with the same short summary.
527+
528+
The PR comment is mandatory for every accepted existing-PR update and should look like:
529+
```markdown
530+
[bot] **Iteration {N} accepted** -- [Crane run]({run_url})
531+
532+
- **Commit**: [`{short_sha}`]({commit_url})
533+
- **Change**: {one-line summary}
534+
- **Milestone**: {milestone or current focus}
535+
- **Score**: {migration_score} (best: {best_metric}, delta: {+/-delta}) *(if available)*
536+
- **Progress**: {progress fraction} *(if available)*
537+
- **Tests/parity**: {parity_passing}/{parity_total} passing *(if available)*
538+
- **CI fix attempts**: {N} *(only if > 0)*
539+
```
503540
3. Ensure the migration issue exists (see [Migration Issue](#migration-issue) below) -- for file-based migrations with no migration issue yet (`selected_issue` is null in `/tmp/gh-aw/crane.json`), create one and record its number in the state file's `Issue` field.
504541
4. Update the state file `{migration-name}.md` in the repo-memory folder:
505542
- **[*] Machine State** table: reset `consecutive_errors` to 0, set `best_metric` (the new `migration_score`), increment `iteration_count`, set `last_run` to current UTC, append `"accepted"` to `recent_statuses` (keep last 10), set `paused` to false.
506543
- **[ladder] Milestones**: update the relevant milestone's status -- typically `done` if the milestone was fully completed, otherwise leave `in-progress` and update its notes. If the milestone is done, the next milestone in the list becomes the new **[target] Current Focus**.
507-
- Prepend an entry to **[chart] Iteration History** with status [+], score, **signed delta**, PR link, fix-attempt count if `> 0`, and a one-line summary of what milestone was advanced and how.
544+
- Prepend an entry to **[chart] Iteration History** using the shared accepted iteration summary: status [+], score, **signed delta**, PR link, commit SHA, run URL, fix-attempt count if `> 0`, and a one-line summary of what milestone was advanced and how.
508545
- Update **[docs] Lessons Learned** if this iteration revealed something new (e.g. a bridging trick, a parity surprise, a perf trap).
509546
- Update **[scope] Future Work** if this iteration opened new threads.
510-
5. **Update the migration issue**: edit the status comment and post a per-iteration comment.
547+
5. **Update the migration issue**: edit the status comment and post a per-iteration comment using the same shared accepted iteration summary.
511548
6. **Check halting condition** (see [Halting Condition](#halting-condition)): if `target-metric` is set, compare the new `best_metric` against it. For `higher` direction: completed when `best_metric >= target-metric`. When the target is met, mark the migration as completed.
512549

513550
**If the score did not improve**:
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from __future__ import annotations
2+
3+
from pathlib import Path
4+
5+
ROOT = Path(__file__).resolve().parents[2]
6+
CRANE_WORKFLOW = ROOT / ".github" / "workflows" / "crane.md"
7+
8+
9+
def _workflow_text() -> str:
10+
return CRANE_WORKFLOW.read_text(encoding="utf-8")
11+
12+
13+
def test_crane_acceptance_requires_shared_iteration_summary_for_pr_updates() -> None:
14+
text = _workflow_text()
15+
16+
assert "### Accepted Iteration Summary" in text
17+
assert "single shared source" in text
18+
assert "PR body, PR comment, migration issue comment, and repo-memory history" in text
19+
assert "add-comment" in text
20+
assert "push-to-pull-request-branch" in text
21+
assert "ci: trigger checks" in text
22+
assert "unless it is the only new commit" in text
23+
24+
25+
def test_crane_commit_guidance_provides_structured_summary_fallback() -> None:
26+
text = _workflow_text()
27+
28+
assert "Subject: `[Crane: {migration-name}] Iteration <N>: <short description" in text
29+
assert "Changes:" in text
30+
assert "Run: {run_url}" in text
31+
assert text.index("Changes:") < text.index("Run: {run_url}")
32+

0 commit comments

Comments
 (0)