Skip to content

Heads-up: metanorma/ci rubygems-release.yml now guards patch-release breaking changes (opt-out flag available) #54

Description

@opoudjis

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:

  1. Deleted files in lib/, exe/, bin/, sig/ (proxy for Gem::Specification#files diff)
  2. Prism AST symbol diff — top-level modules/classes/methods present at prev tag and absent at HEAD
  3. 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.

🤖

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions