A GitHub Action for automatic package releases using autopub. Automatically publish your Python packages to PyPI when pull requests are merged.
- Simple interface: Single action with
check,prepare,build, andpublishcommands - Multiple package managers: Supports uv, Poetry, and PDM
- Automatic artifact management: Seamlessly passes release info between jobs
- GitHub integration: PR comments and GitHub releases out of the box
- Flexible publishing: Supports both PyPI trusted publishing (OIDC) and token-based authentication
- Version flexibility: Use latest stable, pre-release, or pin to a specific version
---
release type: patch
---
Fixed a bug in the authentication module that caused login failures.Release type can be major, minor, or patch following semver.
PR Check (.github/workflows/pr.yml):
name: PR Check
on:
pull_request_target:
branches: [main]
permissions:
contents: read
pull-requests: write
jobs:
check-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: "refs/pull/${{ github.event.number }}/merge"
# Only checkout the files needed for the check - faster and more secure
sparse-checkout: |
RELEASE.md
pyproject.toml
sparse-checkout-cone-mode: false
- uses: autopub/autopub-action@v1
with:
command: check
github-token: ${{ secrets.GITHUB_TOKEN }}Release (.github/workflows/release.yml):
name: Release
on:
push:
branches: [main]
permissions:
contents: write
id-token: write # Required for trusted publishing
jobs:
check:
runs-on: ubuntu-latest
outputs:
has-release: ${{ steps.check.outputs.has-release }}
steps:
- uses: actions/checkout@v4
- uses: autopub/autopub-action@v1
id: check
with:
command: check
github-token: ${{ secrets.GITHUB_TOKEN }}
release:
needs: check
if: needs.check.outputs.has-release == 'true'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.PAT_TOKEN }}
- uses: autopub/autopub-action@v1
with:
command: prepare
- uses: autopub/autopub-action@v1
with:
command: build
- uses: autopub/autopub-action@v1
with:
command: publish
github-token: ${{ secrets.PAT_TOKEN }}| Input | Required | Default | Description |
|---|---|---|---|
command |
Yes | - | Command to run: check, prepare, build, publish |
github-token |
No | ${{ github.token }} |
GitHub token for PR comments and releases |
pypi-token |
No | - | PyPI token (alternative to trusted publishing) |
autopub-version |
No | latest |
Autopub version: latest, pre-release, or specific version |
git-username |
No | autopub |
Git username for release commits |
git-email |
No | autopub@autopub |
Git email for release commits |
extra-plugins |
No | - | Additional Python packages to install for plugins (pip specs, comma or multiline) |
upload-artifact |
No | true |
Auto-upload .autopub artifact after check |
download-artifact |
No | true |
Auto-download .autopub artifact before other commands |
artifact-name |
No | autopub-data |
Name for the artifact |
publish-repository |
No | - | Named repository for publishing (configured in pyproject.toml) |
fail-on-missing |
No | false |
Fail the action if no valid RELEASE.md found during check |
| Output | Description |
|---|---|
has-release |
true if a valid RELEASE.md was found |
version |
The computed release version (available after prepare) |
release-type |
The release type: major, minor, or patch |
release-notes |
The release notes from RELEASE.md |
Validates the RELEASE.md file and prepares release information.
- Parses the release file and validates the format
- Creates
.autopub/release_info.jsonwith release metadata - Posts a comment on the PR with the changelog preview (if GitHub plugin enabled)
- Uploads the
.autopubartifact for use by subsequent jobs (only when a valid release is found andupload-artifactis enabled)
- uses: autopub/autopub-action@v1
with:
command: check
github-token: ${{ secrets.GITHUB_TOKEN }}Bumps the version and updates the changelog.
- Downloads the
.autopubartifact from the check step - Updates version in
pyproject.tomland__init__.py - Updates
CHANGELOG.mdwith the release notes
- uses: autopub/autopub-action@v1
with:
command: prepareBuilds the package using the configured package manager (uv, poetry, or pdm).
- uses: autopub/autopub-action@v1
with:
command: buildPublishes the package to PyPI and creates a GitHub release.
- Publishes to PyPI using trusted publishing or token
- Creates a git tag and pushes changes
- Creates a GitHub release with the changelog
- Posts a comment on the PR confirming the release
- uses: autopub/autopub-action@v1
with:
command: publish
github-token: ${{ secrets.BOT_TOKEN }}For basic PR check functionality, the default GITHUB_TOKEN works:
github-token: ${{ secrets.GITHUB_TOKEN }}For pushing commits and creating releases, you'll need a Personal Access Token (PAT) or a GitHub App token with write permissions:
github-token: ${{ secrets.PAT_TOKEN }}PyPI supports trusted publishing using OpenID Connect. This is the most secure option as it doesn't require storing tokens.
- Configure your PyPI project to trust your GitHub repository
- Add the
id-token: writepermission to your workflow:
permissions:
id-token: writeThe action will automatically use trusted publishing when no pypi-token is provided.
Alternatively, use a PyPI token:
- uses: autopub/autopub-action@v1
with:
command: publish
pypi-token: ${{ secrets.PYPI_TOKEN }}Configure autopub in your pyproject.toml. The configuration varies slightly depending on your package manager.
[project]
name = "my-package"
version = "1.0.0"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.autopub]
plugins = ["uv"][tool.poetry]
name = "my-package"
version = "1.0.0"
description = "My package"
authors = ["Your Name <you@example.com>"]
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[tool.autopub]
plugins = ["poetry"][project]
name = "my-package"
version = "1.0.0"
[build-system]
requires = ["pdm-backend"]
build-backend = "pdm.backend"
[tool.autopub]
plugins = ["pdm"][tool.autopub]
project-name = "My Project"
git-username = "release-bot"
git-email = "bot@example.com"
# Enable additional plugins
plugins = ["uv", "github"]
# Plugin-specific configuration
[tool.autopub.plugins.github]
include_sponsors = true
create_discussions = trueTo test the latest features before they're released:
- uses: autopub/autopub-action@v1
with:
command: check
autopub-version: pre-releaseFor reproducible builds:
- uses: autopub/autopub-action@v1
with:
command: check
autopub-version: "1.0.0"If you need custom artifact handling:
- uses: autopub/autopub-action@v1
with:
command: check
upload-artifact: false
- uses: actions/upload-artifact@v4
with:
name: my-custom-artifact
path: .autopub- uses: autopub/autopub-action@v1
with:
command: publish
git-username: "My Bot"
git-email: "bot@mycompany.com"To publish to a custom PyPI repository (e.g., a private registry), configure it according to your package manager:
# pyproject.toml
[[tool.uv.index]]
name = "private"
url = "https://my-pypi-server.com/simple/"
publish-url = "https://my-pypi-server.com/"
explicit = true # Prevents use for dependency resolution# Configure via CLI (or poetry.toml)
poetry config repositories.private https://my-pypi-server.com/# Configure via CLI
pdm config repository.private.url https://my-pypi-server.com/Then reference the repository by name in your workflow:
- uses: autopub/autopub-action@v1
with:
command: publish
publish-repository: privateTo enforce that all PRs include a RELEASE.md file:
- uses: autopub/autopub-action@v1
with:
command: check
fail-on-missing: "true"This will fail the workflow if no valid RELEASE.md is found, useful for PR checks.
Install additional autopub plugins using the extra-plugins input. Each entry is passed as
a --with argument to uvx, so full pip dependency specs are supported.
Simple plugin names (comma-separated):
- uses: autopub/autopub-action@v1
with:
command: check
extra-plugins: "my-autopub-plugin,another-plugin"Complex pip specs (multiline):
- uses: autopub/autopub-action@v1
with:
command: check
extra-plugins: |
autopub-my-plugin @ git+https://github.com/org/repo.git@main
autopub-another-plugin>=1.0.0Plugin environment variables:
Plugins that need configuration via environment variables (e.g. API keys) can receive them
through the env block on the action step:
- uses: autopub/autopub-action@v1
env:
MY_PLUGIN_API_KEY: ${{ secrets.MY_PLUGIN_API_KEY }}
with:
command: publish
extra-plugins: "autopub-my-plugin"Environment variables set at the step, job, or workflow level are all available to plugins running inside the action.
The check command returns has-release: false when:
RELEASE.mddoesn't exist- The file format is invalid
- The release type is not
major,minor, orpatch
If prepare, build, or publish fail with artifact errors:
- Ensure
checkcompleted successfully in a previous job - Verify the
artifact-namematches between jobs - Check that
upload-artifact: true(default) was used in the check step
Ensure your token has write permissions:
- Use a PAT with
contents: writescope - Or use a GitHub App installation token
- Don't use the default
GITHUB_TOKENfor pushing (it has read-only access to the repository inpull_requestevents)
AGPL-3.0 - see LICENSE for details.