Reusable Workflow Reference: Release Workflows¶
In a nutshell
This page documents the three shared workflows that move a package through its release lifecycle: bumping the version and opening a release PR, publishing the stable tag, and previewing the next version number on an open PR. For the PR-gate checks that run before a merge, see PR Workflows. For lint, coverage, security scans, and notifications, see Quality Workflows. Start with the gh-automations overview for the big picture, or the full Workflow Reference index.
All reusable workflows are in .github/workflows/ and are called via:
Ref: Always use
@dev.
Workflows on this page:
publish-alpha.yml¶
Runs on PR merge to dev. Bumps the version, optionally updates changelog and creates a pre-release tag, then opens a release PR to master.
Source: .github/workflows/publish-alpha.yml
Inputs¶
| Input | Type | Default | Description |
|---|---|---|---|
runner |
string | ubuntu-latest |
|
version_file |
string | "" |
Path to version.py (relative to repo root). If empty, auto-detects root or pkg/version.py. |
setup_py |
string | setup.py |
Deprecated. Version is now read from version_file directly. |
branch |
string | dev |
Development branch where changes are made |
base_branch |
string | master |
Target branch for the release PR (e.g. master/main). |
publish_prerelease |
boolean | false |
|
propose_release |
boolean | true |
|
update_changelog |
boolean | false |
|
changelog_file |
string | CHANGELOG.md |
|
changelog_max_issues |
number | 50 |
|
publish_pypi |
boolean | false |
Publish to PyPI after version bump |
notify_matrix |
boolean | false |
Send Matrix notification when a PR is merged |
matrix_channel |
string | !WjxEKjjINpyBRPFgxl:krbel.duckdns.org |
Matrix room ID to notify (default: OVOS main channel) |
matrix_homeserver |
string | matrix.org |
Matrix homeserver URL |
matrix_message |
string | "" |
Custom Matrix message. Leave empty to use the default 'PR merged' message. |
matrix_message_pool |
string | "" |
Newline-separated pool of fun messages to randomly prefix the notification. One is chosen at random and prepended to the standard message. Leave empty to skip. Example: "๐ Another one!\n๐ Shipped!" |
skip_bot_prs |
boolean | true |
Skip version bumps for PRs opened by known maintenance bots that do not change runtime code (allcontributors[bot], pre-commit-ci[bot]). Dependency-update bots (renovate[bot], dependabot[bot]) are NOT skipped since dep updates should produce a new alpha. |
Secrets¶
| Secret | Required | Description |
|---|---|---|
PYPI_TOKEN |
no | PyPI API token for publishing. Required when publish_pypi: true. |
MATRIX_TOKEN |
no | Matrix access token for notifications. Required when notify_matrix: true. |
Outputs¶
| Output | Description |
|---|---|
version |
Updated version |
changelog |
Changelog Contents |
Jobs¶
| Job | Condition | Description |
|---|---|---|
bump_version |
merged == true && not a skipped bot \|\| workflow_dispatch |
Determines bump type from PR labels, calls update_version.py, commits and pushes to branch via git-auto-commit-action@v7. Skips PRs from allcontributors[bot] and pre-commit-ci[bot] when skip_bot_prs: true. |
update_changelog |
update_changelog: true + bump_version succeeded |
Calls github-changelog-generator-action@v2.4, commits result |
tag_prerelease |
publish_prerelease: true + bump_version succeeded |
Creates GitHub pre-release via ncipollo/release-action@v1 |
propose_release |
propose_release: true + bump_version succeeded |
Creates release-X.Y.ZaN branch, opens PR to master via GitHub API |
publish_pypi |
publish_pypi: true + bump_version succeeded |
Builds with uv build, publishes via pypa/gh-action-pypi-publish@release/v1 (uses PYPI_TOKEN) |
notify |
notify_matrix: true + bump_version succeeded + PR merged |
Sends a Matrix notification directly (duplicates, does not call, notify-matrix.yml) with a canned message |
Bot guard¶
bump_version only runs when:
-
A PR was merged (
github.event.pull_request.merged == true), or -
Triggered manually (
workflow_dispatch)
This prevents spurious runs when a PR is closed without merging.
Typical usage¶
name: Release Alpha and Propose Stable
on:
workflow_dispatch:
pull_request:
types: [closed]
branches: [dev]
jobs:
publish_alpha:
if: github.event.pull_request.merged == true || github.event_name == 'workflow_dispatch'
uses: OpenVoiceOS/gh-automations/.github/workflows/publish-alpha.yml@dev
secrets: inherit
with:
branch: 'dev'
version_file: 'my_package/version.py'
update_changelog: true
publish_prerelease: true
propose_release: true
changelog_max_issues: 100
Notes¶
-
publish_pypi: trueusespypa/gh-action-pypi-publish@release/v1(pinned to stable tag). -
propose_releaseusesgit checkout -B(force-create) andgh pr createwith duplicate-check, both steps are idempotent on retry.
publish-stable.yml¶
Runs on push to master (typically triggered by merging the release PR). Removes the alpha suffix from version.py, commits, then creates a GitHub release tag.
Source: .github/workflows/publish-stable.yml
Inputs¶
| Input | Type | Default | Description |
|---|---|---|---|
runner |
string | ubuntu-latest |
|
version_file |
string | "" |
Path to version.py (relative to repo root). If empty, auto-detects root or pkg/version.py. |
setup_py |
string | setup.py |
Deprecated. Version is now read from version_file directly. |
branch |
string | master |
Stable branch where the release happens (e.g. master/main). If 'master' is requested but missing, detects default branch. |
publish_release |
boolean | true |
|
publish_pypi |
boolean | false |
Publish to PyPI after declaring stable |
sync_dev |
boolean | false |
Push master -> dev to keep branches in sync after stable release |
notify_matrix |
boolean | false |
Send Matrix notification when a stable release is published |
matrix_channel |
string | !WjxEKjjINpyBRPFgxl:krbel.duckdns.org |
Matrix room ID to notify (default: OVOS main channel) |
matrix_homeserver |
string | matrix.org |
Matrix homeserver URL |
matrix_message |
string | "" |
Custom Matrix message. Leave empty to use the default 'stable release' message. |
matrix_message_pool |
string | "" |
Newline-separated pool of fun messages to randomly prefix the notification. One is chosen at random and prepended to the standard message. Leave empty to skip. |
Secrets¶
| Secret | Required | Description |
|---|---|---|
PYPI_TOKEN |
no | PyPI API token for publishing. Required when publish_pypi: true. |
MATRIX_TOKEN |
no | Matrix access token for notifications. Required when notify_matrix: true. |
Outputs¶
| Output | Description |
|---|---|
version |
Updated version |
Jobs¶
| Job | Condition | Description |
|---|---|---|
bump_version |
github.actor != 'github-actions[bot]' |
Detects the target branch, calls remove_alpha.py, commits via git-auto-commit-action@v7 |
tag_release |
publish_release: true + bump_version succeeded |
Creates GitHub release via ncipollo/release-action@v1 |
publish_pypi |
publish_pypi: true + bump_version succeeded |
Builds and publishes to PyPI (stable) via pypa/gh-action-pypi-publish@release/v1 |
cleanup |
needs tag_release to have succeeded, so it never runs when publish_release: false |
Tidies up the short-lived release branch |
sync_dev |
sync_dev: true + bump_version succeeded |
Pushes master โ dev via ad-m/github-push-action |
notify |
notify_matrix: true + bump_version succeeded |
Sends a Matrix notification directly (duplicates, does not call, notify-matrix.yml) with configurable channel and message |
Bot guard¶
bump_version skips when github.actor == 'github-actions[bot]'. This prevents an infinite loop: the version commit pushed by git-auto-commit-action would otherwise re-trigger this workflow on push: master.
The calling repo's wrapper job also carries this guard (if: github.actor != 'github-actions[bot]') for belt-and-suspenders protection.
Typical usage¶
name: Stable Release
on:
push:
branches: [master]
workflow_dispatch:
jobs:
publish_stable:
if: github.actor != 'github-actions[bot]'
uses: OpenVoiceOS/gh-automations/.github/workflows/publish-stable.yml@dev
secrets: inherit
with:
branch: 'master'
version_file: 'my_package/version.py'
publish_release: true
sync_dev: true
release-preview.yml¶
Reads version.py, predicts the next version from PR labels and/or title using conventional commit prefixes, and posts a ๐ท๏ธ Release Preview section to the OVOS PR Checks comment. It also checks channel compatibility when a package name is resolvable.
Source: .github/workflows/release-preview.yml
Inputs¶
| Input | Type | Default | Description |
|---|---|---|---|
runner |
string | ubuntu-latest |
Runner label |
python_version |
string | 3.14 |
Python version |
package_name |
string | "" |
Package name (for channel compatibility check). If empty, attempt to read from setup.py/pyproject.toml. |
version_file |
string | "" |
Path to the version.py file (relative to repo root). If empty, auto-detects. |
pr_comment |
boolean | true |
Post a '๐ท๏ธ Release Preview' section in the shared 'OVOS PR Checks' comment on the PR. Only runs when the workflow is triggered by a pull_request event. |
Permissions¶
pull-requests: write, contents: read
Steps¶
| Step | Description |
|---|---|
| Checkout + scripts checkout | Checks out the calling repo and (on PR events) the gh-automations scripts |
| Setup Python | actions/setup-python@v6 |
| Run release check | check_release.py --version-file โฆ --output-json /tmp/release-report.json. Env vars: PR_LABELS_JSON, PR_TITLE. continue-on-error: true. |
| Format release section | Inline Python reads release-report.json โ release-section.md |
| Post release section to PR comment | Calls update_pr_comment.py with --section-id release |
| Fail job if release check failed | Re-raises only for malformed version.py (parse error) |
Bump detection rules¶
Labels take precedence over PR title. Priority: major > minor > build.
| Label | Bump |
|---|---|
breaking, breaking change |
major |
feature, enhancement |
minor |
fix, bug, bugfix |
build |
| PR title prefix | Bump |
| ----------------- | ------ |
breaking change:, feat!:, fix!: |
major |
feat:, feature: |
minor |
fix: |
build |
docs:, chore:, refactor:, test:, style:, perf:, ci:, build: |
alpha only |
| (no prefix) | alpha only |
PR comment content (with label)¶
**Current:** `1.2.3a4` โ **Next:** `1.3.0a1`
| Signal | Value |
|--------|-------|
| Label | `feature` |
| PR title | `feat: add multi-language support` |
| Bump | minor |
โ
PR title follows conventional commit format.
PR comment content (no label, no prefix)¶
**Current:** `1.2.3a4` โ **Next:** `1.2.3a5`
| Signal | Value |
|--------|-------|
| Label | _(none)_ |
| PR title | `update readme` |
| Bump | alpha |
โ ๏ธ No conventional commit prefix โ alpha-only bump.
Suggested: `fix: update the thing` or `feat: update the thing`
No version.py found: โน๏ธ No version.py found, release preview not available.
Typical usage¶
name: Release Preview
on:
pull_request:
branches: [dev]
workflow_dispatch:
jobs:
release_preview:
uses: OpenVoiceOS/gh-automations/.github/workflows/release-preview.yml@dev
secrets: inherit
Read next: Release Flow Related: Workflow Reference ยท PR Check Workflows ยท Quality Workflows