Skip to content

feat(release): add wave-level prepare-release skill + engine#160

Merged
jeronimodeleon merged 2 commits into
mainfrom
feat/prepare-release-skill
Jul 16, 2026
Merged

feat(release): add wave-level prepare-release skill + engine#160
jeronimodeleon merged 2 commits into
mainfrom
feat/prepare-release-skill

Conversation

@jeronimodeleon

Copy link
Copy Markdown
Contributor

Wave-level release-prep: /prepare-release skill + tools/prepare_release.py

Adds a standardized, reproducible way to prep a genblaze release wave — codifying the manual v0.5.0 prep (and the traps it surfaced) so the next release is one guided run instead of back-and-forth.

Why (the failure mode this fixes)

During the v0.5.0 prep, hand-editing 8 pyproject.tomls + the CHANGELOG silently missed the CLI genblaze-core floor bump — caught only by CI. A prose-only skill would reproduce that. So the mechanical work lives in a testable engine, and the skill is a thin driver over it.

tools/prepare_release.py (engine)

  • Dynamic discovery — package set from globs (libs/core, cli, libs/meta, libs/spec, libs/connectors/*); no hardcoded package list or version literal.
  • Floor sync that prevents the miss — resyncs cli's and the umbrella's genblaze-core/genblaze-s3/connector-extra floors to the local core version whether or not those packages changed (matches the test_*_core_dependency_floor_matches_local_core invariants), so a pin-only change can't ship without a version bump (the skip-existing/pin-parity trap).
  • Reserved-core-version guard — greps _RAISE_ON_FAILURE_DEFAULT_FLIP_VERSION from source and refuses to bump core onto it.
  • --check / --apply modes; --set pkg=x / --bump pkg=minor overrides; emits the ### Released package versions list for the CHANGELOG.
  • 34 substantive tests (real throwaway git repos, not mocks).

.claude/skills/prepare-release/SKILL.md (driver)

  • Safety enforced in allowed-tools, not prose: no git tag, gh release, twine upload, or make post-release — it cannot tag or publish; it goes as far as a release PR and emits the human tag/release/post-release commands.
  • ~4 steps: scope → apply + cut CHANGELOG → make pre-release (with the macOS env prereqs baked in) → open PR. Links RELEASING.md as source of truth; delegates per-package detail to /release-check. /verify-docs, /security-review, and MIGRATING-<wave>.md are conditional suggestions, not mandatory steps.

Review

Built via TDD, then a 3-lens panel (over-engineering/DRY, correctness vs RELEASING.md/release.yml, safety). No P0/P1 except the one applied fix (removed dead fixture params, commit 037fe70). The correctness reviewer verified the engine live-caught a real, previously-invisible instance of the target bug class: genblaze-nvidia's README link fix since v0.4.0 shipped with no version bump. Remaining items are non-blocking P2 cosmetics (duplicate floor-report lines per-extra; a fails-closed regex assumption in the reserved-version extractor) — noted for follow-up.

Verification: pytest tools/tests/test_prepare_release.py 34/34; ruff check/format clean; --check runs clean against the live repo.

Adds tools/prepare_release.py, a deterministic engine for the version-bump
and dependency-floor bookkeeping half of cutting a genblaze release wave,
plus .claude/skills/prepare-release/SKILL.md as a thin driver over it.

Motivated by a concrete gap: a hand-edited release-prep pass this session
bumped genblaze-core but silently missed cli's matching core-floor bump.
The script makes that impossible by discovering packages dynamically (no
hardcoded version literals or connector list) and resyncing cli's and the
umbrella's genblaze-core/genblaze-s3/connector-extra floors to the final
decided version of whatever they point at, independent of whether that
specific package changed this wave -- forcing a version bump on the pin
holder itself when needed, the same skip-existing drift class
tools/check_pin_parity.py already guards against downstream. Refuses to
land core on the version reserved for the raise_on_failure default flip.
Idempotent by construction (re-running --apply, or a hand-edit, is a
no-op for anything already past what was published at the last tag).

The skill's allowed-tools frontmatter deliberately excludes git tag, gh
release, twine upload, and make post-release -- it can prepare a
merge-ready release PR but cannot tag or publish.
Remove the connector_extras and baseline_tag fixture parameters — no test
call site ever overrode their defaults (dead speculative flexibility flagged
in panel review). Behavior unchanged; 34 tests still pass.
@jeronimodeleon
jeronimodeleon merged commit f2801b2 into main Jul 16, 2026
14 checks passed
@jeronimodeleon
jeronimodeleon deleted the feat/prepare-release-skill branch July 16, 2026 19:16
jeronimodeleon added a commit that referenced this pull request Jul 16, 2026
PR #160 re-populated the [Unreleased] block after the [0.5.0] wave header
was already cut, which fails the release workflow's changelog-gate. The
tooling ships under the v0.5.0 tag anyway (it's on main before the tag; the
tools/skill/docs aren't published to PyPI), so move the note into [0.5.0]
under ### Internal and leave [Unreleased] empty. No packaged code changed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant