rubygems-release: guarantee GitHub Release for every published tag (closes ci#354) - #355
Open
opoudjis wants to merge 3 commits into
Open
rubygems-release: guarantee GitHub Release for every published tag (closes ci#354)#355opoudjis wants to merge 3 commits into
opoudjis wants to merge 3 commits into
Conversation
…loses ci#354) Adds a floor: every tag this workflow publishes carries a GitHub Release with at least auto-generated notes (PR titles since the previous tag). Closes the class where gems accumulate tags with no releases (metanorma-plugin-lutaml v0.7.35-v0.7.50 hit this before backfill; the same pattern recurs elsewhere in the wider stack). ## New input release_notes: 'auto' (default) | 'manual' - 'auto' — if no Release exists for the pushed tag, create one with auto-generated notes. - 'manual' — skip the ensure-release step entirely. For gems whose maintainers write release notes by hand at release time; the maintainer creates the Release themselves. ## Never overwrite If a Release already exists for the tag (whether created by hand with maintainer notes, or by a prior run of this workflow), the step detects it and leaves it alone. `gh release view` is used as the existence check; `gh release create` only fires on the not-exists path. ## Placement New step lives at the end of the release job, right after the "Verify gem published on rubygems.org" post-publish check and before the "Post-release event" repository_dispatch. Runs on the same SHOULD_PUBLISH / skip_push gates as the publish step itself, plus the release_notes != 'manual' opt-out. ## Auth Uses the release job's existing `contents: write` permission (inherited from the caller — every current caller template has `permissions: contents: write` per ci#339). No new secret required; `GITHUB_TOKEN` is sufficient for release creation on the workflow's own repo. Closes #354.
Introduces the opt-out mechanism opoudjis called for on ci#354 for maintainers who write GitHub Release notes by hand at release time. - `gh-actions/master/release_manual_notes.yml` — variant of `release.yml` that passes `release_notes: manual` to the reusable. - `gh-actions/master/release_wo_bundle_install_manual_notes.yml` — variant of `release_wo_bundle_install.yml` with the same opt-out. Each variant file carries a header block naming its parent, its consumer set, and how to switch back to the auto-notes floor. Same per-variant documentation discipline as the `Gemfile.grammar-build` variant added to `gh-actions/model/` in ci#353. - 20 gems mapping `release.yml` → `release_manual_notes.yml`: metanorma-cli, metanorma-core, metanorma-ogc, metanorma-cc, metanorma-ribose, metanorma-iho, metanorma-ieee, metanorma-iec, metanorma-ietf, metanorma-standoc, metanorma-iso, metanorma-taste, metanorma-itu, metanorma-generic, metanorma-bipm, metanorma-jis, metanorma-plateau, metanorma-document, isodoc, isodoc-i18n. - 1 gem mapping `release_wo_bundle_install.yml` → `release_wo_bundle_install_manual_notes.yml`: metanorma-utils. - `metanorma-nist`, `metanorma-bsi` map `release_github_packages.yml`, which calls `ghpkg-release.yml`, not `rubygems-release.yml`. ci#354's auto-notes floor lives in `rubygems-release.yml` and doesn't reach the ghpkg-release path, so those two gems are already exempt without any variant mapping. The variants land on origin main for the 21 opoudjis-maintained gems. Their next release runs pass `release_notes: manual` to the reusable (introduced in the sibling commit on this branch), the reusable skips its Ensure-GitHub-Release step, and Release + notes remain the maintainer's manual responsibility.
…et (ci#354)
Follow-up to the initial 21-gem opt-out set. Adds the non-metanorma-*
gems the maintainer confirmed as owned but that my initial predicate
missed (predicate was too narrow — matched only 'metanorma-*' + explicit
'isodoc*'/'basicdoc-models').
Added to release_manual_notes.yml (release.yml → variant):
- html2doc
- gb-agencies
- cnccs
- isoics
Added to release_wo_bundle_install_manual_notes.yml
(release_wo_bundle_install.yml → variant):
- metanorma (top-level gem — family root, not matched by 'metanorma-*'
predicate because no trailing '-<flavour>')
- mn-requirements
Total opt-out set is now 27 gems (still 2 exempt-by-construction:
metanorma-nist + metanorma-bsi via release_github_packages.yml).
Also updated the maintainer memory file (~/.claude/memory/user_maintained_gems.md
locally) to record these six explicitly, matching the discipline used
for basicdoc-models 2026-06-24. Memory update is out-of-tree from this
repo but referenced here for the paper trail.
opoudjis
force-pushed
the
feature/rubygems-release-github-release-notes
branch
from
July 21, 2026 03:30
e7309be to
631fd77
Compare
This was referenced Jul 25, 2026
ronaldtse
added a commit
that referenced
this pull request
Jul 25, 2026
Reverts the two-phase "gated-direct" release architecture added in #293. A release is now atomic: workflow_dispatch bumps + tags + publishes in one job. A green run means the gem is on rubygems.org. The idempotent push guard handles duplicate pushes (re-runs, stale do-release listeners from consumer rake.yml files). Why (see ci#370 for full postmortem): - "Publication DEFERRED" was a green check. A run that did NOT publish reported success, inverting the meaning of green. Maintainers could not tell from the run list whether a release actually shipped. - The 11-hop relay (workflow_dispatch → tag → rake → do-release → publish) required per-consumer wiring that wasn't enforced. fractor v0.1.11 failed silently because its rake.yml didn't dispatch do-release; the tag-listener preflight passed because it matched dependent-tests.yml, which also doesn't dispatch do-release. - Wrapper workflows (omnizip, other non-cimas consumers) couldn't reach override inputs on the inner shared workflow. Hard-stop with no maintainer recourse. - The original motivation (double-publish race) was already handled by gem-idempotent-push-guard-action. The relay was solving a problem already solved. - Test gating belongs at PR time (required status checks on the main branch), not as a workflow-level relay splitting publish across multiple events. What's removed: - SHOULD_PUBLISH env var and conditional — publish always runs on workflow_dispatch. - "Publication DEFERRED" summary step. - Tag-listener preflight (was looking for the wrong thing). - No-PAT fallback notice (no relay to fall back from). - "Tag current version (skip mode)" step (no relay to trigger). - release-chain.md (11-layer taxonomy of a now-defunct architecture, stubbed with a redirect to docs/rubygems-release.md). What's kept: - preflight job (bundle resolve, gem build, credentials check, OIDC Trusted Publisher exchange — useful fail-fast checks). - gem-idempotent-push-guard-action (handles duplicate publish). - Post-publish verification (polls rubygems.org). - release-passed dispatch (downstream listeners like notify.yml). - repository_dispatch: do-release listener (backward compat with consumer rake.yml files that still dispatch it; idempotent guard handles the duplicate). What's deprecated (kept as no-op for backward compat): - `gated` input — accepted but ignored. Consumer repos that pass it see no error; publish happens immediately. Same treatment for monorepo-rubygems-release.yml. README.md and docs/rubygems-release.md updated to describe the single-phase model. Docs now explicitly state the consumer model: metanorma/ci is shared infrastructure for any gem, not just cimas-managed repos. Defaults must work for both populations. Supersedes: #333 (reverted in #368), #293. Blocks: #355 (depends on SHOULD_PUBLISH; needs rework to a one-line gh release create call, no variant templates, no cimas.yml churn).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #354
Summary
Two coordinated changes: (1) the release-notes floor on
rubygems-release.yml, and (2) the opt-out variants for the 27 opoudjis-maintained gems that write their notes by hand.Part 1 — release-notes floor in
rubygems-release.ymlAdds a mechanical floor: every tag pushed by the shared workflow carries a GitHub Release with at least auto-generated notes (PR titles since the previous tag). Closes the class where a gem accumulates tags with no releases (metanorma-plugin-lutaml v0.7.35-v0.7.50 hit this before backfill; the same pattern recurs elsewhere in the stack).
New input
auto— if no Release exists for the pushed tag, create one with auto-generated notes (PR titles since the previous tag).manual— skip the ensure-release step entirely.Never overwrite
If a Release already exists for the tag (whether from a hand-written maintainer note or a prior workflow run), the step detects it via
gh release viewand leaves it alone.gh release createonly fires on the not-exists path.Placement
The new step lives at the end of the release job, right after the "Verify gem published on rubygems.org" post-publish check and before the "Post-release event"
repository_dispatch. Runs on the sameSHOULD_PUBLISH/skip_pushgates as the publish step itself, plusrelease_notes != 'manual'.Auth
Uses the release job's existing
contents: writepermission (inherited from the caller — every current caller template carriescontents: writeper ci#339). No new secret required.Part 2 — opt-out variants for 27 opoudjis-maintained gems
Per opoudjis's decision on the ticket, the floor is opt-out for gems whose maintainers write release notes by hand at release time. Introduces two variant caller templates + updates 27 cimas.yml mappings.
Variant templates (2 new files)
cimas-config/gh-actions/master/release_manual_notes.yml— variant ofrelease.ymlthat passesrelease_notes: manualto the reusable.cimas-config/gh-actions/master/release_wo_bundle_install_manual_notes.yml— variant ofrelease_wo_bundle_install.ymlwith the same opt-out.Each variant file carries a header block naming its parent template, its consumer set, and how to switch back to the auto-notes floor. Same per-variant documentation discipline established with
Gemfile.grammar-buildin ci#353.cimas.yml mapping updates (27)
release.yml→release_manual_notes.yml:metanorma-cli,metanorma-core,metanorma-ogc,metanorma-cc,metanorma-ribose,metanorma-iho,metanorma-ieee,metanorma-iec,metanorma-ietf,metanorma-standoc,metanorma-iso,metanorma-taste,metanorma-itu,metanorma-generic,metanorma-bipm,metanorma-jis,metanorma-plateau,metanorma-document,isodoc,isodoc-i18n,html2doc,gb-agencies,cnccs,isoics.release_wo_bundle_install.yml→release_wo_bundle_install_manual_notes.yml:metanorma-utils,metanorma(top-level),mn-requirements.Exempt-by-construction (no variant needed)
metanorma-nistandmetanorma-bsimaprelease_github_packages.yml, which callsghpkg-release.yml, notrubygems-release.yml. Part 1's floor lives inrubygems-release.ymland doesn't reach the ghpkg-release path. Those two gems are already exempt without any variant mapping.Non-opoudjis gems
Every gem not in the opt-out list keeps its current mapping and gets the auto-notes floor on their next release run. This is the intended default per ticket #354.
Effect after next cimas wave (~2026-07-22)
🤖