Skip to content

Commit

Permalink
Automate publishing Python package on PyPI (#1580)
Browse files Browse the repository at this point in the history
Adds two Tox environments that help with publishing the Python package
on PyPI.

- `tox -e package` can be used for linting to help detect packaging
issues.
- `tox -e package -- upload` allows to publish the package on PyPI.
- `tox -e ensure_version_matches $GIT_TAG` verifies that the package
version matches the semantic Git tag on the current commit. This is used
by the GHA configuration to prevent a mismatch of tags and the version
of the published package.

To make publishing work, you need to add the 2 secrets `PYPI_USERNAME`
and `PYPI_PASSWORD` to [Settings ➜ Secrets ➜
Actions](https://github.com/canonical/charmcraft/settings/secrets/actions)
with the PyPI access token for the project, as described in the [Python
packaging user
guide](https://packaging.python.org/en/latest/tutorials/packaging-projects/#uploading-the-distribution-archives).

## Related

- #1579
- [Is `setup.py`
deprecated?](https://packaging.python.org/en/latest/discussions/setup-py-deprecated/)
– _The use as a command line tool is deprecated_

Co-authored-by: Alex Lowe <alex.lowe@canonical.com>
  • Loading branch information
bittner and lengau authored Jun 28, 2024
1 parent 7460a6f commit e216376
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 11 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/publish-pypi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Publish

on:
push:
tags:
- '[1-9]+.[0-9]+.[0-9]+'

env:
PIP_DISABLE_PIP_VERSION_CHECK: '1'
PY_COLORS: '1'

jobs:
pypi:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install build tools
run: pip install tox
- name: Verify package version is same as Git tag
run: tox run -qe ensure_version_matches -- $GIT_TAG
env:
GIT_TAG: ${{ github.ref_name }}
- name: Build package and upload to PyPI
run: tox run -e package -- upload
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ dmypy.json
# backups
*~
/charmcraft/_version.py
/results/

# Spread files
.spread-reuse*.yaml
13 changes: 6 additions & 7 deletions HOWTO_RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ paste, but do please pay attention to details!

- build a tarball to test

rm -rf dist/
./setup.py sdist bdist_wheel
tox -e clean
tox -e package

- try the tarball

Expand Down Expand Up @@ -89,7 +89,10 @@ paste, but do please pay attention to details!

git push --tags

- release in Github
For a new tag, this will trigger publishing a release of the Python
package on PyPI via GHA.

- release on GitHub

xdg-open https://github.com/canonical/charmcraft/tags

Expand All @@ -101,10 +104,6 @@ paste, but do please pay attention to details!

Click on "Publish release"

- release to PyPI

fades -d twine -x twine upload --verbose dist/*

- release to Snap Store (for all the archs)

snapcraft upload charmcraft_X.Y.Z_amd64.snap --release=edge,candidate
Expand Down
6 changes: 2 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
[project]
name = "charmcraft"
dynamic = ["version"]
description = "The main tool to build, upload, and develop in general the Juju charms."
dynamic = ["version", "readme"]
readme = "README.md"
dependencies = [
"craft-application~=2.0",
"craft-cli>=2.3.0",
Expand Down Expand Up @@ -83,9 +84,6 @@ requires = [
]
build-backend = "setuptools.build_meta"

[tool.setuptools.dynamic]
readme = {file = "README.md"}

[tool.setuptools_scm]
write_to = "charmcraft/_version.py"
# the version comes from the latest annotated git tag formatted as 'X.Y.Z'
Expand Down
28 changes: 28 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,31 @@ env_dir = {work_dir}/pre-commit
runner = ignore_env_name_mismatch
description = Run pre-commit on staged files or arbitrary pre-commit commands (tox run -e pre-commit -- [args])
commands = pre-commit {posargs:run}

[testenv:clean]
description = Clean up bytecode and build artifacts
skip_install = true
deps = pyclean
commands = pyclean {posargs:. --debris --erase results/* results/ --yes}

[testenv:ensure_version_matches]
description = Verify package version is same as Git tag
deps =
commands = python -c 'import os; from importlib.metadata import version; pkg, tag = os.environ["PKG_NAME"], os.environ["GIT_TAG"]; ver = version(pkg); error = f"`{ver}` != `{tag}`"; abort = f"Package version does not match the Git tag ({error}). ABORTING."; raise SystemExit(0 if ver and tag and ver == tag else abort)'
setenv =
PKG_NAME=charmcraft
GIT_TAG={posargs}

[testenv:package]
description = Build package and check metadata (or upload package)
skip_install = true
deps =
build
twine
commands =
python -m build
twine {posargs:check --strict} dist/*
passenv =
TWINE_USERNAME
TWINE_PASSWORD
TWINE_REPOSITORY_URL

0 comments on commit e216376

Please sign in to comment.