repomatic.release.protocol module¶
The release-commit protocol, and the sets that gate CI work on it.
The release machinery writes commits and branches with fixed names, and the workflows read those names back to decide what to run. This module holds both sides of that contract: the commit-message prefixes and the branch names the machinery writes, and the path and branch sets that skip the binary build.
tests/test_workflows.py holds the workflow gates to these values.
- repomatic.release.protocol.RELEASE_BRANCH: Final[str] = 'main'¶
The branch the release workflow publishes from.
release.yamltriggers on a push to this branch alone, and a release push is one that lands release commits on it: seeis_release_push.
- repomatic.release.protocol.CHANGELOG_COMMIT_PREFIX: Final[str] = '[changelog] '¶
Marker prefix carried by every machine-authored version-machinery commit.
The one bracketed prefix commit messages may carry: release freezes, post-release bumps and manual version bumps all start with it, so a workflow can skip machinery pushes with a single
startsWith(github.event.head_commit.message, '[changelog] ')clause instead of enumerating each message shape. Conformance tests intests/test_workflows.pyhold every member ofVERSION_BUMP_COMMIT_PREFIXES,RELEASE_COMMIT_PATTERN, thebump-versiontemplate title, and the workflow gates to this prefix.
- repomatic.release.protocol.RELEASE_COMMIT_PREFIX: Final[str] = '[changelog] Release'¶
Commit-message prefix of the release commit.
The coarser sibling of
RELEASE_COMMIT_PATTERN: where that one validates and extracts a version, this is a prefix test. A prefix is deliberately weaker than the full pattern here, because the question is “does this push carry a release” rather than “which version is it”, and answering it must not depend on the version number parsing.A rebase-merged release pull request ends on the post-release bump, so the head commit of a release push carries
POST_RELEASE_COMMIT_PREFIXinstead:RELEASE_PUSH_PREFIXESnames both.
- repomatic.release.protocol.POST_RELEASE_COMMIT_PREFIX: Final[str] = '[changelog] Post-release bump '¶
Message prefix of the post-release bump, the last commit of a release push.
The bump reopens the development cycle: see
post_release_commit_message(). GitHub names a push, and each run it starts, after the newest commit it carries. The release pull request is rebase-merged, so that commit is the post-release bump, not the release commit before it.
- repomatic.release.protocol.RELEASE_PUSH_PREFIXES: Final[tuple[str, ...]] = ('[changelog] Release', '[changelog] Post-release bump ')¶
Head-commit-message prefixes of a push that carries a release.
The concurrency groups of
release.yamlandtests.yamltest them, so the run of a release push lands in a group of its own that no later push cancels.repomatic.github.runs.cancel_superseded_runs()applies the same test from the API side, which is the half GitHub’s own concurrency mechanism cannot cover: a manual sweep of a branch’s live runs enters no concurrency group at all.
- repomatic.release.protocol.RELEASE_COMMIT_PATTERN: Final[Pattern[str]] = re.compile('^\\[changelog\\]\\ Release v(?P<version>[0-9]+\\.[0-9]+\\.[0-9]+)$')¶
Pre-compiled regex for release commit messages.
Matches the full message and captures the version number. Use
fullmatchto validate a commit is a release commit, ormatch/searchwith.group("version")to extract the version string.A rebase merge preserves the original commit messages, so release commits match this pattern. A squash merge replaces them with the PR title (like
Release ``v1.2.3(#42)``), which does not match. This mismatch is the mechanism by which squash merges are safely skipped: thecreate-tagjob only processes commits matching this pattern, so no tag, PyPI publish, or GitHub release is created from a squash merge. Thesquashed-releasejob of_release-build.yamldetects this and opens an issue to notify the maintainer.
- repomatic.release.protocol.SQUASHED_RELEASE_PREFIX: Final[str] = 'Release `v'¶
Head-commit-message prefix of a release pull request merged by squashing.
A squash merge replaces the freeze and unfreeze commits with one commit named after the pull request, whose title the
prepare-releasetemplate writes asRelease ``vX.Y.Z. The ``squashed-releasejob gates on this prefix, andsquashed_release_pr()reads the pull request reference that follows it.
- repomatic.release.protocol.release_commit_message(version)[source]¶
The message of the freeze commit that releases version.
RELEASE_COMMIT_PATTERNmatches what this returns, which is how the release workflow finds the commit to tag.
- repomatic.release.protocol.post_release_commit_message(released, current)[source]¶
The message of the commit that bumps released to the next version.
- repomatic.release.protocol.squashed_release_pr(message)[source]¶
Read the pull request reference off a squash-merged release commit.
- repomatic.release.protocol.bump_branch(part)[source]¶
The pull request branch a bump of the version part opens.
- Parameters:
part (
str) – A member ofBUMP_PARTS.- Return type:
- repomatic.release.protocol.RELEASE_PR_BRANCH: Final[str] = 'prepare-release'¶
The head branch of the release pull request.
Named after the
prepare-releasejob and template that open it, like every automation branch.
- repomatic.release.protocol.VERSION_BUMP_BRANCHES: Final[frozenset[str]] = frozenset({'major-version-increment', 'minor-version-increment', 'prepare-release'})¶
PR branches that carry only automated version-bump and lockfile churn.
Members are bot-authored draft PRs created by the
bump-versionandprepare-releasejobs inchangelog.yaml. Their working tree is byte-identical tomainexcept for the version string inpyproject.toml,**/__init__.py,changelog.md,citation.cff, anduv.lock. Heavy PR-time workflows (tests.yaml,lint.yaml,labels.yaml) list these branches underpull_request.branches-ignoreso the matrix doesn’t burn CI minutes for a guaranteed-passing run.Note
These branches are not binary-neutral: the rewritten version string is baked into the Nuitka binary, so they are deliberately absent from
SKIP_BINARY_BUILD_BRANCHES. Post-merge release artifacts onmainare still produced.
- repomatic.release.protocol.MANUAL_VERSION_BUMP_COMMIT_PREFIXES: Final[frozenset[str]] = frozenset({'[changelog] Bump major version to ', '[changelog] Bump minor version to '})¶
Head-commit-message prefixes for user-initiated version bumps.
Members are the
bump-versionjob’s[changelog] Bump $part version to \``v$version\commit messages (rendered from thebump-versiontemplate’s title), carryingCHANGELOG_COMMIT_PREFIXlike every other version-machinery commit. These merges land as a single commit onmainand carry no other payload, so workflows can short-circuit on them safely.The release-cycle prefix
[changelog] Post-release bumpis deliberately absent from this set because theprepare-releasemerge bundles the post-release-bump commit with the actual release commit ([changelog] Release vX.Y.Z) in a single push. Workflows that gate on the head commit message (tests.yaml,release.yaml::compile-binaries) must run on those pushes to test the release commit and build its binary, so they consult only this subset.
- repomatic.release.protocol.VERSION_BUMP_COMMIT_PREFIXES: Final[frozenset[str]] = frozenset({'[changelog] Bump major version to ', '[changelog] Bump minor version to ', '[changelog] Post-release bump '})¶
Full set of head-commit-message prefixes that mark a version-bump push.
Combines
MANUAL_VERSION_BUMP_COMMIT_PREFIXESwith thePOST_RELEASE_COMMIT_PREFIXproduced byprepare-releasemerges. Every member starts withCHANGELOG_COMMIT_PREFIX, so workflows without a release-artifact dependency (lint.yaml,autofix.yaml) gate theirmetadatajob on that single prefix and the entire job graph skips for any push generated by the version-bump PR family. Workflows that do produce release artifacts on the same push useMANUAL_VERSION_BUMP_COMMIT_PREFIXESinstead.
- repomatic.release.protocol.BINARY_AFFECTING_PATHS: Final[tuple[str, ...]] = ('.github/workflows/_release-engine.yaml', '.github/workflows/release.yaml', 'pyproject.toml', 'tests/', 'uv.lock')¶
Path prefixes that always affect compiled binaries, regardless of the project.
binary_affecting_pathsadds the project’s own source directories to these.The release workflow entries cover both layouts: upstream keeps the
_release-engine.yamllane (which defines the Nuitka compile and binary self-test jobs) in-repo, while downstream repos call the engine cross-repo from their generatedrelease.yaml, so a pin bump there rightly triggers a rebuild.
- repomatic.release.protocol.SKIP_BINARY_BUILD_BRANCHES: Final[frozenset[str]] = frozenset({'format-images', 'format-json', 'format-markdown', 'format-shell', 'sync-gitignore', 'sync-mailmap', 'update-dep-graph'})¶
Autofix branches whose changes cannot affect compiled binaries.
Members are PR branch names produced by autofix jobs that touch only repository housekeeping (
.mailmap,.gitignore, JSON, Markdown, images, shell scripts, dependency graph). The binary output is unchanged, soskip_binary_buildreturnsTruewhen the PR head branch matches a member, saving an expensive Nuitka compilation.Note
This set is intentionally disjoint from
VERSION_BUMP_BRANCHES: version-bump branches do change binaries (they rewrite the version string baked into the build), so they belong to a different policy.