Heads-up on a behavioural change to metanorma/ci/.github/workflows/rubygems-release.yml@main, which this repo's .github/workflows/release.yml calls via workflow_call.
What changed
metanorma/ci#333 (merged) adds a patch-release breaking-change heuristic guard, implementing metanorma/ci#278 Option 1. The guard runs three heuristics comparing the previous release tag against HEAD:
- Deleted files in
lib/, exe/, bin/, sig/ (proxy for Gem::Specification#files diff)
- Prism AST symbol diff — top-level modules/classes/methods present at prev tag and absent at HEAD
gem-compare vs the previously-published rubygems version (advisory)
Short-circuits on the first hit; total wall-clock added: ~5-18 s.
When it fires
Only on workflow_dispatch + next_version: patch. Automatic push: tags: v* releases are untouched. major / minor bumps are untouched (they already signal intent).
If any of your gems releases a patch that removes files or top-level symbols, the release will fail-fast with an actionable $GITHUB_STEP_SUMMARY naming what was removed.
Opt-out
A new per-run input acknowledge_breaking_in_patch: true overrides the guard. Use for legitimate cases (removing an accidentally-shipped fixture, a rename that preserves API) — recorded in run inputs for audit trail.
Example:
# Via GH web UI: "Run workflow" → set acknowledge_breaking_in_patch = true
# Via gh CLI:
gh workflow run release.yml -f next_version=patch -f acknowledge_breaking_in_patch=true
Why filing this
The guard's blast radius includes every consumer of the shared reusable workflow, including this org's <org>/support wrapper. Filing so maintainers here aren't blindsided at the next patch release. Motivation from the ticket body: a 2025-10-03 lutaml/lutaml v0.9.41 → v0.9.42 patch release deleted 196 lines of public API surface and broke the downstream metanorma-plugin-lutaml → metanorma-standoc chain — pattern this guard is designed to catch before publish.
Empirically validated against lutaml/lutaml — caught both the ticket's v0.9.42 incident and a v0.10.18 recurrence; two clean patch releases in the same window tested false-positive-free.
Reversibility: the guard is a single ~230-line Ruby script + one workflow step. If it causes problems, revert is straightforward.
🤖
Heads-up on a behavioural change to
metanorma/ci/.github/workflows/rubygems-release.yml@main, which this repo's.github/workflows/release.ymlcalls viaworkflow_call.What changed
metanorma/ci#333(merged) adds a patch-release breaking-change heuristic guard, implementingmetanorma/ci#278Option 1. The guard runs three heuristics comparing the previous release tag against HEAD:lib/,exe/,bin/,sig/(proxy forGem::Specification#filesdiff)gem-comparevs the previously-published rubygems version (advisory)Short-circuits on the first hit; total wall-clock added: ~5-18 s.
When it fires
Only on
workflow_dispatch+next_version: patch. Automaticpush: tags: v*releases are untouched.major/minorbumps are untouched (they already signal intent).If any of your gems releases a
patchthat removes files or top-level symbols, the release will fail-fast with an actionable$GITHUB_STEP_SUMMARYnaming what was removed.Opt-out
A new per-run input
acknowledge_breaking_in_patch: trueoverrides the guard. Use for legitimate cases (removing an accidentally-shipped fixture, a rename that preserves API) — recorded in run inputs for audit trail.Example:
Why filing this
The guard's blast radius includes every consumer of the shared reusable workflow, including this org's
<org>/supportwrapper. Filing so maintainers here aren't blindsided at the next patch release. Motivation from the ticket body: a 2025-10-03lutaml/lutaml v0.9.41 → v0.9.42patchrelease deleted 196 lines of public API surface and broke the downstream metanorma-plugin-lutaml → metanorma-standoc chain — pattern this guard is designed to catch before publish.Empirically validated against
lutaml/lutaml— caught both the ticket's v0.9.42 incident and a v0.10.18 recurrence; two clean patch releases in the same window tested false-positive-free.Reversibility: the guard is a single ~230-line Ruby script + one workflow step. If it causes problems, revert is straightforward.
🤖