ci(release): add release-please for stable releases (two-lane flow)#78
Merged
Conversation
…ne flow Automate stable releases from Conventional Commits while keeping the proven tag-driven publish path untouched: - release-please-config.json / .release-please-manifest.json: python release type, package remo-cli, tags vX.Y.Z (no component prefix), seeded at 2.2.0. - .github/workflows/release-please.yml: on push to main, maintain a release PR (bump pyproject.toml + CHANGELOG.md); merging it tags vX.Y.Z, which triggers the existing release.yml (PyPI + Docker). Requires a RELEASE_PLEASE_TOKEN PAT so the created tag fires the tag-driven workflow (GITHUB_TOKEN tags don't). - CHANGELOG.md: seed; maintained by release-please from 2.3.0 onward. - CONTRIBUTING.md: document the two lanes (stable = release-please release PR; RC/beta = manual vX.Y.Z-rcN tag) plus the local "test before PyPI" gate, and list release-please.yml in the workflows table. release.yml is deliberately unchanged: the RC lane and any manual tag still publish exactly as before. Chosen over a reusable-workflow refactor because the latter has locally-untestable gotchas (metadata-action semver from a non-tag ref; OIDC environment across workflow_call). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HAPB5GA4NVUgKFsVFVJDxN
pofallon
added a commit
that referenced
this pull request
Jul 25, 2026
…s, no PyPI) (#79) * feat(skill): add /release skill to operationalize the two-lane release flow A user-invocable skill that drives remo's release process with a mandatory local "test before PyPI" gate and approval-before-publish guardrails: - stable lane: locate the release-please "chore(main): release X.Y.Z" PR, review the bump + CHANGELOG, run the validation gate on the PR head, then merge only on explicit approval (release-please tags -> release.yml publishes). - rc lane: compute X.Y.ZrcN, bump pyproject, run the validation gate, then either hand off a local wheel (no PyPI) or, only on explicit approval, tag vX.Y.Z-rcN and publish a prerelease. - Step V validation gate: full pytest + uv build + throwaway-venv smoke that the wheel's --version matches, before any tag/merge/publish. Guardrails: never push a tag/commit or merge a release PR without explicit in-turn approval; require a clean, up-to-date main; prefer local-only testing. Pairs with the release-please integration (#78). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HAPB5GA4NVUgKFsVFVJDxN * ci(dev-build): manual-dispatch workflow to publish RC/dev wheels as run artifacts Build an installable wheel in clean CI and upload it as a run artifact you can download and test on another machine — no git tag, no PyPI, no reserved version: - .github/workflows/dev-build.yml: workflow_dispatch with an optional `version` input. Stamps pyproject.toml with the base version plus a PEP 440 LOCAL segment (+g<shortsha>), which PyPI rejects outright — so a dev build can never leak to PyPI and every build is uniquely identifiable. Uploads dist/* as the `remo-wheel` artifact (30-day retention). release.yml is untouched. gh workflow run dev-build.yml [-f version=2.3.0rc1] gh run download <run-id> -n remo-wheel && uv tool install --force ./remo_cli-*.whl - /release skill: add a "CI dev build (cross-machine, no PyPI)" outcome to the RC lane alongside local-only and publish-to-PyPI. Version stamping validated locally (packaging.Version): blank -> X.Y.Z.dev<run>, label -> X.Y.ZrcN, each with a +g<sha> local segment. actionlint clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HAPB5GA4NVUgKFsVFVJDxN --------- Co-authored-by: Paul O'Fallon <505519+pofallon@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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.
Summary
Adds release-please to automate stable releases from Conventional Commits, while leaving the proven tag-driven publish path (
release.yml) completely unchanged. First of two PRs; a follow-up adds areleaseskill that drives the local pre-PyPI validation and the RC lane.The two lanes (now in CONTRIBUTING.md)
chore(main): release X.Y.ZPR that bumpspyproject.toml+CHANGELOG.md. Merging it tagsvX.Y.Z, which triggers the existingrelease.yml(PyPI + Docker). No manual bump or tag.X.Y.Zrc1, pushvX.Y.Z-rcN,release.ymlpublishes a prerelease. release-please stays out.Files
release-please-config.json+.release-please-manifest.json—release-type: python,package-name: remo-cli, tagsvX.Y.Z, seeded at2.2.0..github/workflows/release-please.yml— runs on push tomain.CHANGELOG.md— seed; release-please maintains it from 2.3.0 onward.CONTRIBUTING.md— documents both lanes + the local "test before PyPI" gate.CI infra can't be fully exercised locally (actionlint + JSON/YAML parse all pass):
RELEASE_PLEASE_TOKENsecret required. A tag created with the defaultGITHUB_TOKENdoes not triggeron: push: tags, so publish wouldn't fire. Add a PAT (contents+pull-requestswrite) as repo secretRELEASE_PLEASE_TOKEN. (This is whyrelease.ymlis untouched rather than a reusable-workflow refactor — that route has locally-untestable gotchas:docker/metadata-actioncan't derive semver from a non-tag ref; OIDCenvironmentacrossworkflow_call.)googleapis/release-please-action@v4is a floating tag (SHA unresolvable offline); pin to@<sha> # v4to match repo convention.uv.lockdrift. release-please won't runuv lock;uv.lock's project version can lagpyproject.toml(doesn't affectuv build). Noted in CONTRIBUTING.Validation:
actionlintclean across all workflows; config/manifest JSON valid. First real behavior (release PR, then publish-on-merge) can only be confirmed onmainwith the PAT set — recommend verifying the RC lane first.🤖 Generated with Claude Code