docs(runbook): stale "out-of-date" PR after a stacked PR is retargeted (closes #195) #196
@@ -15,6 +15,7 @@ those containers share a filesystem — or a `localhost` — breaks.
|
|||||||
| `pg_isready` passes before PostGIS is ready | add a `PostGIS_Version()` probe | the db healthchecks |
|
| `pg_isready` passes before PostGIS is ready | add a `PostGIS_Version()` probe | the db healthchecks |
|
||||||
| `upload-artifact@v4` fails ("not supported on GHES") | pin `@v3` | `.gitea/workflows/ci.yaml` (`mutation` job) |
|
| `upload-artifact@v4` fails ("not supported on GHES") | pin `@v3` | `.gitea/workflows/ci.yaml` (`mutation` job) |
|
||||||
| `upload-artifact@v3` fails with "Artifact service responded with 500" | mark the upload `continue-on-error: true` (server-side; issue #62) | `.gitea/workflows/ci.yaml` (`mutation` job) |
|
| `upload-artifact@v3` fails with "Artifact service responded with 500" | mark the upload `continue-on-error: true` (server-side; issue #62) | `.gitea/workflows/ci.yaml` (`mutation` job) |
|
||||||
|
| PR says "out-of-date" but *Update branch* fails ("Unable to update pull request") | push a new head SHA (`commit --amend --no-edit` + `push --force-with-lease`) | §10, server-side |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -289,3 +290,41 @@ re-run hides the failed one, so keep the failing job id from the original report
|
|||||||
- Remember `concurrency.cancel-in-progress: true` in `ci.yaml`: a new push to the same
|
- Remember `concurrency.cancel-in-progress: true` in `ci.yaml`: a new push to the same
|
||||||
ref, or a re-run, kills the in-flight run the same way. Check `run_attempt` before
|
ref, or a re-run, kills the in-flight run the same way. Check `run_attempt` before
|
||||||
concluding a job hung.
|
concluding a job hung.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. A retargeted stacked PR says "out-of-date" but *Update branch* fails
|
||||||
|
|
||||||
|
**Symptom** — the PR shows *This branch is out-of-date with the base branch* and
|
||||||
|
*This pull request is blocked because it's outdated* (branch protection
|
||||||
|
`block_on_outdated_branch` on `main`), yet **Update branch** answers *Unable to update
|
||||||
|
pull request* (API: `HeadBranch of PR NN is up to date`). `git merge-base` confirms the
|
||||||
|
branch sits on the tip of `main`. Seen on #194 (#195).
|
||||||
|
|
||||||
|
**Why** — Gitea 1.27 keeps two answers to "is it behind?":
|
||||||
|
|
||||||
|
- The banner and the merge block read a **stored** `pull_request.commits_behind`
|
||||||
|
(`MergeBlockedByOutdatedBranch`: `CommitsBehind > 0`).
|
||||||
|
- *Update branch* recomputes it **live** from git (`services/pull/update.go`) and refuses
|
||||||
|
when nothing is behind.
|
||||||
|
|
||||||
|
The stored count is only refreshed by a push to the head or base branch, or by a
|
||||||
|
retarget. #194 was stacked on #193; its rebased branch was force-pushed in the **same
|
||||||
|
second** that merging #193 deleted the parent branch and Gitea retargeted #194 to `main`.
|
||||||
|
The retarget compared `main` against `refs/pull/194/head` before the push queue had
|
||||||
|
updated that ref (the old head missed the squash commit → `CommitsBehind = 1`); the push
|
||||||
|
handler's own resync ran against the deleted old base and failed. Nothing pushed
|
||||||
|
afterwards, so the stale `1` stuck. Close/reopen does not recompute it.
|
||||||
|
|
||||||
|
**Fix** — give the head a new SHA with the same content; the push resyncs the count:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git commit --amend --no-edit # new committer date → new SHA
|
||||||
|
git push --force-with-lease origin <branch>
|
||||||
|
```
|
||||||
|
|
||||||
|
PR CI re-runs on the new SHA (the old statuses don't carry over).
|
||||||
|
|
||||||
|
**Avoid it** — when the parent of a stacked PR merges, let Gitea finish retargeting the
|
||||||
|
child to `main` (its timeline shows *changed target branch*) **before** pushing the
|
||||||
|
rebased child branch.
|
||||||
|
|||||||
Reference in New Issue
Block a user