Skip to content

Commit 1c446c4

Browse files
committed
Fix PR prompt improvements
1 parent acb22b1 commit 1c446c4

1 file changed

Lines changed: 109 additions & 44 deletions

File tree

.github/prompts/fix-pr-ci-failures.md

Lines changed: 109 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -13,36 +13,85 @@ Do not stop a given execution until you have worked through all phases below.
1313
## Phase 0: Validate
1414

1515
1. Verify we're not on a protected branch: `git branch --show-current` should not be `main`
16-
2. Check that the branch is up-to-date with remote: `git fetch && git status` - exit and warn if behind
16+
2. Check that the branch is up-to-date with remote: `git fetch && git status` - exit if `git status` reports the branch is `behind` or has `diverged` from remote.
1717
3. Get the current branch name using `git branch --show-current`
1818
4. Find the PR for this branch using `gh pr list --head <branch-name> --json number,title` and extract the PR number
19-
5. Use `gh pr view <pr-number> --json statusCheckRollup --jq '.statusCheckRollup[] | select(.conclusion == "FAILURE") | {name: .name, detailsUrl: .detailsUrl}'` to get the list of all failed CI jobs
19+
5. Use `gh pr view <pr-number> --json statusCheckRollup --jq '.statusCheckRollup[] | select(.conclusion == "FAILURE") | {name: .name, detailsUrl: .detailsUrl, databaseId: .databaseId}'` to get the list of all failed CI jobs
2020
6. Check if there are actually CI failures to fix - if all jobs passed, exit early
2121

2222
## Phase 1: Gather Information
2323

24-
**Phase 1 is for gathering information ONLY. Do NOT analyze failures or look at any code during this phase.**
25-
**Your only goal in Phase 1 is to collect: job names, job IDs, log files, and failed task names.**
26-
27-
1. Delete any existing CI-PLAN.md file: `rm -f CI-PLAN.md`
28-
2. Get repository info: `gh repo view --json owner,name`
29-
3. For unique job type that failed
30-
- **Important**: Ignore duplicate jobs that only differ by parameters inside of parenthesis. For example:
31-
- In `abc / def (x, y, z)`, the job is `abc / def` while x, y, and z are parameters
32-
- **Strategy**: Download logs for 1-2 representative jobs first to identify patterns (e.g., one "build" job, one "test0" job)
33-
- Compilation failures typically repeat across all jobs, so you don't need every log file
34-
- Retrieve logs for selected representative jobs:
35-
- Get the job ID from the failed run by examining the PR status checks JSON
36-
- Download logs using: `cd /tmp && gh auth token | xargs -I {} curl -sSfL -H "Authorization: token {}" -o <job-name>.log "https://api.github.com/repos/<owner>/<repo>/actions/jobs/<job-id>/logs"`
37-
- Example: `cd /tmp && gh auth token | xargs -I {} curl -sSfL -H "Authorization: token {}" -o test0-java8-indy-false.log "https://api.github.com/repos/open-telemetry/opentelemetry-java-instrumentation/actions/jobs/53713949850/logs"`
38-
- The GitHub API responds with an HTTP 302 redirect to blob storage; `-L` (already included) ensures the download follows the redirect and saves the final log contents.
39-
- Find all gradle tasks that failed:
40-
- Search for failed tasks: `grep "Task.*FAILED" /tmp/<job-name>.log`
41-
- Look for test failures: `grep "FAILED" /tmp/<job-name>.log | grep -E "(Test|test)"`
42-
- Example output: `> Task :instrumentation:cassandra:cassandra-4.0:javaagent:test FAILED`
43-
- Extract error context:
44-
- For compilation errors: `grep -B 5 -A 20 "error:" /tmp/<job-name>.log`
45-
- For task failures: `grep -B 2 -A 15 "Task.*FAILED" /tmp/<job-name>.log`
24+
**Phase 1 is for gathering raw log data and identifying failed tasks.**
25+
**Allowed in Phase 1: downloading logs, grepping logs for error context, listing failed tasks. You may also read source files when strictly needed to classify a failure as real vs. flaky/infra.**
26+
**Not allowed in Phase 1: editing code, or designing / planning fixes. Defer fix design to Phase 3.**
27+
28+
### Working directory discipline
29+
30+
- Always `cd` back to the repository root before running any `git`, `gh pr`, or `./gradlew` command. Log downloads in `/tmp` put the shell outside the repo and subsequent `git` commands will fail with `fatal: not a git repository`.
31+
- Prefer one-shot invocations: `(cd /tmp && <download command>)` in a subshell, so the outer shell's cwd is preserved.
32+
33+
### Prevent CI-PLAN.md from being committed
34+
35+
Before creating `CI-PLAN.md`, add it to the repo-local ignore list so it can't be accidentally staged:
36+
37+
```
38+
grep -qxF CI-PLAN.md .git/info/exclude || echo CI-PLAN.md >> .git/info/exclude
39+
rm -f CI-PLAN.md
40+
```
41+
42+
### Collect failure logs
43+
44+
1. Get repository info: `gh repo view --json owner,name`
45+
2. Identify unique failing jobs:
46+
- **Ignore pure duplicates** that only differ by matrix parameters inside parentheses (e.g., `common / test0 (8, hotspot, indy false)` vs `(11, hotspot, indy false)`).
47+
- **Do sample axes that plausibly change behavior**: different JDK majors, indy true vs false, any `-deny-unsafe` / security-manager variants, and latest-deps vs pinned. Grab one representative per meaningfully distinct axis, not just one per job name prefix.
48+
- **Flaky / infra failures**: if a failure looks like a network timeout, cache miss, runner OOM, or anything clearly unrelated to PR code, note it in `CI-PLAN.md` under "Notes" and do not invent a code fix for it.
49+
3. Download logs for the selected representatives. Two equally-valid options:
50+
51+
**Option A: `gh run view`** (avoids putting the token in process argv):
52+
53+
```
54+
# For a single job's failing log only:
55+
gh run view --job <job-id> --log-failed > /tmp/<job-name>.log
56+
57+
# Or all failed steps across the whole run in one file:
58+
gh run view <run-id> --log-failed > /tmp/run-<run-id>-failed.log
59+
```
60+
61+
**Option B: REST API** — use this on Windows/Git Bash, where `gh run view --log-failed` often fails with `stream error: stream ID 1; CANCEL; received from peer`:
62+
63+
```
64+
(cd /tmp && curl -sSfL \
65+
-H "Authorization: token $(gh auth token)" \
66+
-o <job-name>.log \
67+
"https://api.github.com/repos/<owner>/<repo>/actions/jobs/<job-id>/logs")
68+
```
69+
70+
Token safety:
71+
- Do NOT pipe `gh auth token` through `xargs` — that places the token in `argv` where other local processes can see it.
72+
- Inlining it via `-H "Authorization: token $(gh auth token)"` also exposes it in the `curl` process's `argv` (visible to `ps` on multi-user systems). Acceptable on a single-user dev box; avoid on shared machines.
73+
74+
4. For each downloaded log, extract failed Gradle tasks and error context:
75+
- Failed tasks: `grep "Task.*FAILED" /tmp/<job-name>.log`
76+
- Test failures: `grep "FAILED" /tmp/<job-name>.log | grep -E "(Test|test)"`
77+
- Compilation error context: `grep -B 5 -A 20 "error:" /tmp/<job-name>.log`
78+
- Task failure context: `grep -B 2 -A 15 "Task.*FAILED" /tmp/<job-name>.log`
79+
80+
### Fan-out shortcut
81+
82+
Large PRs often produce dozens of failures that all stem from a single upstream
83+
task (e.g., one `compileJava` failure cascades into every test matrix cell).
84+
After downloading the first 2-3 representatives, if they all report the
85+
**same failed upstream Gradle task with identical error text**, stop sampling —
86+
one fix will resolve all axes. Record the full list of failing jobs in
87+
`CI-PLAN.md` but don't waste time downloading each one's log.
88+
89+
### Searching the repo
90+
91+
Use `rg` (ripgrep) for repo-wide text searches. It respects `.gitignore` by
92+
default, so `build/`, `.gradle/`, and similar generated directories are skipped
93+
automatically. Plain `grep -r` / `grep -rn` will descend into those
94+
directories and may hang on large builds. `git grep` is also acceptable.
4695

4796
## Phase 2: Create CI-PLAN.md
4897

@@ -66,33 +115,49 @@ Do not stop a given execution until you have worked through all phases below.
66115
- Seen in: <job-name-1>, <job-name-2>, ...
67116
- Log files: /tmp/<file1>.log, /tmp/<file2>.log
68117

118+
## Suspected Flaky / Infra Failures (skipped)
119+
- <job-name>: <reason>
120+
69121
## Notes
70122
[Any patterns or observations about the failures]
71123
```
72124

73125
## Phase 3: Fix Issues
74126

75-
**Important**: Do not commit CI-PLAN.md - it's only for tracking work during the session
76-
77-
- Work through the CI-PLAN.md, checking items off as you complete them
78-
- For each failed task:
79-
- Analyze the failure
80-
- Implement the fix
81-
- To fix spotless failures: Run `./gradlew :<failed-module-path>:spotlessApply`
82-
- **Test locally before committing**:
83-
- For markdown lint failures: `mise run lint:markdown`
84-
- For compilation errors: `./gradlew <failed-task-path>`
85-
- For test failures: Run the whole module's test task (e.g., `./gradlew :instrumentation:module-name:javaagent:test`) instead of just the individual failing test, as there are often other tests in the module that also need to be fixed
86-
- Verify the fix resolves the issue
87-
- Update the checkbox in CI-PLAN.md
88-
- Commit each logical fix as a separate commit
89-
- Reminder: do not commit CI-PLAN.md
90-
- Do not git push in this phase
127+
**Important**: Do not commit `CI-PLAN.md` — it's only for tracking work during the session. Phase 1 already added it to `.git/info/exclude`; do not use `git add -A` or `git commit -a` (either could still pick it up if the ignore entry was missed).
128+
129+
### Gradle execution rules (repo-specific)
130+
131+
- Never pipe Gradle output through `grep`, `tail`, `head`, or any other command. Piping masks Gradle's exit code, so a failing build silently appears to succeed.
132+
- Run Gradle with no timeout (`timeout 0`) and wait for completion — builds and tests can take several minutes.
133+
- Never use `--rerun-tasks`. Use `--rerun` when a task must be forced to re-execute.
134+
135+
### Per-task workflow
136+
137+
Work through `CI-PLAN.md`, checking items off as you complete them. For each failed task:
138+
139+
- Analyze the failure using the logs (now you may open source files).
140+
- Implement the fix.
141+
- Spotless failures: `./gradlew :<failed-module-path>:spotlessApply`
142+
- **Test locally before committing**:
143+
- Markdown lint: `mise run lint:markdown`
144+
- Compilation errors: `./gradlew <failed-task-path>`
145+
- Test failures: run the whole module's test task (e.g., `./gradlew :instrumentation:module-name:javaagent:test`) rather than just the single failing test — related tests in the module often need fixing too.
146+
- Verify the fix resolves the issue.
147+
- Update the checkbox in `CI-PLAN.md`.
148+
- Commit each logical fix as a **separate commit**:
149+
- Use explicit pathspecs: `git commit -- path/one path/two -m "..."`.
150+
- Note that `git mv` auto-stages the rename — don't re-run `git add` on the moved paths.
151+
- If `git mv` or earlier edits have already staged unrelated changes, `git reset` first and stage only the files for the current logical fix.
152+
- Do not commit `CI-PLAN.md`.
153+
- Do not `git push` in this phase.
91154

92155
## Phase 4: Validate and Push
93156

94-
- Once all fixes are committed, push the changes: `git push` (or `git push -f` if needed)
157+
- Delete `CI-PLAN.md` (`rm -f CI-PLAN.md`) and confirm `git status` is clean of it.
158+
- Push the changes with plain `git push`.
159+
- Only use `git push -f` / `--force-with-lease` if you rewrote history during the session (rebase, amend, reorder). Additive fix commits do not require a force push.
95160
- Provide a summary of:
96-
- What failures were found
97-
- What fixes were applied
98-
- Which commits were created
161+
- What failures were found (including any skipped as flaky/infra).
162+
- What fixes were applied.
163+
- Which commits were created.

0 commit comments

Comments
 (0)