release: stamp 0.4.1

The three stamps, in one commit as the ceremony requires: VERSION goes
bare, the self-ref pin follows it, and the changelog section is the
assembler's output rather than a hand edit.

0.4.1 is the forge release. Everything in the section comes from #188's
single fragment: ceremony stops being gh-only. `lib/forge.sh` selects a
backend from the runner's own environment, `lib/forge-github.sh` and
`lib/forge-forgejo.sh` implement one call surface twice, and the
reconcilers preflight before they sweep — so a GitHub-shaped client
pointed at a Forgejo instance is a named refusal instead of a sweep that
reads nothing and reports success.

Verified on this instance before stamping: the first post-merge `labels`
run on main (7fc9afe, task 467) came back SUCCESS — the reconciler's
first green run on Forgejo, and the evidence the section's claims are
not merely asserted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
cluade-reviewer-andresmgsl 2026-08-04 10:01:21 +00:00
parent 7fc9afe45f
commit 9a229ee643
5 changed files with 62 additions and 59 deletions

View file

@ -28,7 +28,7 @@ on:
env: env:
# A called workflow arrives without its repository. Keep this literal pin # A called workflow arrives without its repository. Keep this literal pin
# aligned with the ceremony release consumed by callers (issue #9 D3). # aligned with the ceremony release consumed by callers (issue #9 D3).
CEREMONY_SELF_REF: "0.4.0" CEREMONY_SELF_REF: "0.4.1"
jobs: jobs:
scope: scope:

View file

@ -129,7 +129,7 @@ env:
# `ref:` accepts ${{ env }}; `uses:` strings do not — which is why the # `ref:` accepts ${{ env }}; `uses:` strings do not — which is why the
# shared logic arrives as script files via checkout, not as inner `uses:` # shared logic arrives as script files via checkout, not as inner `uses:`
# references. # references.
CEREMONY_SELF_REF: "0.4.0" CEREMONY_SELF_REF: "0.4.1"
VERSION_SOURCE: ${{ inputs.version-source }} VERSION_SOURCE: ${{ inputs.version-source }}
jobs: jobs:

View file

@ -9,6 +9,65 @@ Entries arrive as fragments — one `changelog.d/<issue>.md` per PR, never
an edit to this file — and the release PR assembles them into the next an edit to this file — and the release PR assembles them into the next
section here (`bin/changelog-assemble`, #112). section here (`bin/changelog-assemble`, #112).
## 0.4.1 — 2026-08-04
### Added
- `lib/forge.sh` — the forge selector: `forge_detect` names the forge from
the runner's own environment, `forge_client` names the client it needs, and
`forge_preflight` refuses loudly before any sweep when the two disagree
(#188).
- The reconcilers and `labels-scope` run that preflight first, so a
GitHub-shaped client on a Forgejo instance is a named refusal instead of a
sweep that reads nothing and reports success (#188).
- `lib/closes_references.sh` — the closing-keyword parser, sibling of
`refs_references`, so "which issues does this PR close" is answered from a
PR body rather than from GitHub's GraphQL API (#188).
- `lib/forge-github.sh` and `lib/forge-forgejo.sh` — one call surface, two
backends, selected by `forge_select`; no forge branching at the call sites
(#188).
- The forgejo backend proves each paginated gather complete against the
server's `x-total-count` and refuses loudly when it cannot — a missing
header is a refusal, not a pass (#188).
### Changed
- `issueflow-reconcile` gathers open and merged PRs over REST instead of
`gh api graphql`. Forgejo serves no GraphQL at all, so the two queries were
replaced rather than translated; both forges return `number` and `body`
from `/pulls` in the same shape (#188).
- `forge_api` owns the page size, because each forge silently ignores the
other's parameter: `per_page=100` reads 30 items on Forgejo and `limit=100`
reads 30 on GitHub, both HTTP 200. No call site names one (#188).
- Outstanding review requests are derived from the reviews on the current head
rather than from `requested_reviewers`, which Forgejo never clears — read
raw there, a PR would sit at `state:bots-reviewing` forever (#188).
### Fixed
- `labels-scope` no longer fails to compile its jq program on jq 1.6, which
the Forgejo runner image ships: `label` is a reserved word in jq's grammar,
so `$label` is a syntax error there and every scope derivation died before
reading the config (#188).
- `labels-reconcile` and `labels-scope` no longer exit 0 on a Forgejo
consumer having read zero facts — measured on `heavy-duty/rig`, where the
sweep printed `reconciled.` over an empty PR list and scope reported "no
labeler.yml" for a file that exists (#188).
- `forge_timeline` projects Forgejo's label events (`.type` / `.body` /
`.user.login`) into the GitHub shape (`.event` / `.actor.login`) so the
ruling ladder reads the same board on both forges (#188).
- `forge_pr_activity` no longer calls `/pulls/{n}/comments` on Forgejo
(HTTP 404); inline review comments come from reviews with
`comments_count > 0` (#188).
- CI installs shellcheck before linting, matching actionlint — the Forgejo
runner image does not ship it (#188).
## 0.4.0 — 2026-07-29 ## 0.4.0 — 2026-07-29
### Added ### Added

View file

@ -1 +1 @@
0.4.1-dev 0.4.1

View file

@ -1,56 +0,0 @@
### Added
- `lib/forge.sh` — the forge selector: `forge_detect` names the forge from
the runner's own environment, `forge_client` names the client it needs, and
`forge_preflight` refuses loudly before any sweep when the two disagree
(#188).
- The reconcilers and `labels-scope` run that preflight first, so a
GitHub-shaped client on a Forgejo instance is a named refusal instead of a
sweep that reads nothing and reports success (#188).
- `lib/closes_references.sh` — the closing-keyword parser, sibling of
`refs_references`, so "which issues does this PR close" is answered from a
PR body rather than from GitHub's GraphQL API (#188).
- `lib/forge-github.sh` and `lib/forge-forgejo.sh` — one call surface, two
backends, selected by `forge_select`; no forge branching at the call sites
(#188).
- The forgejo backend proves each paginated gather complete against the
server's `x-total-count` and refuses loudly when it cannot — a missing
header is a refusal, not a pass (#188).
### Changed
- `issueflow-reconcile` gathers open and merged PRs over REST instead of
`gh api graphql`. Forgejo serves no GraphQL at all, so the two queries were
replaced rather than translated; both forges return `number` and `body`
from `/pulls` in the same shape (#188).
- `forge_api` owns the page size, because each forge silently ignores the
other's parameter: `per_page=100` reads 30 items on Forgejo and `limit=100`
reads 30 on GitHub, both HTTP 200. No call site names one (#188).
- Outstanding review requests are derived from the reviews on the current head
rather than from `requested_reviewers`, which Forgejo never clears — read
raw there, a PR would sit at `state:bots-reviewing` forever (#188).
### Fixed
- `labels-scope` no longer fails to compile its jq program on jq 1.6, which
the Forgejo runner image ships: `label` is a reserved word in jq's grammar,
so `$label` is a syntax error there and every scope derivation died before
reading the config (#188).
- `labels-reconcile` and `labels-scope` no longer exit 0 on a Forgejo
consumer having read zero facts — measured on `heavy-duty/rig`, where the
sweep printed `reconciled.` over an empty PR list and scope reported "no
labeler.yml" for a file that exists (#188).
- `forge_timeline` projects Forgejo's label events (`.type` / `.body` /
`.user.login`) into the GitHub shape (`.event` / `.actor.login`) so the
ruling ladder reads the same board on both forges (#188).
- `forge_pr_activity` no longer calls `/pulls/{n}/comments` on Forgejo
(HTTP 404); inline review comments come from reviews with
`comments_count > 0` (#188).
- CI installs shellcheck before linting, matching actionlint — the Forgejo
runner image does not ship it (#188).