Skip to content

Commit a3400f1

Browse files
committed
Publish to PyPI via GitHub CI
1 parent fe7dd6d commit a3400f1

File tree

3 files changed

+85
-19
lines changed

3 files changed

+85
-19
lines changed

.github/workflows/publish.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Publish
2+
3+
on:
4+
release:
5+
types: [created]
6+
7+
env:
8+
FORCE_COLOR: 1
9+
10+
jobs:
11+
publish:
12+
environment:
13+
name: pypi
14+
url: https://pypi.org/p/packaging
15+
permissions:
16+
id-token: write
17+
18+
runs-on: ubuntu-latest
19+
20+
steps:
21+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
22+
23+
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
24+
name: Install Python
25+
with:
26+
python-version: "3.12"
27+
cache: "pip"
28+
allow-prereleases: false
29+
30+
- name: Build distribution via nox
31+
run: pipx run nox --error-on-missing-interpreters -s release_build
32+
33+
- name: Publish distribution to PyPI
34+
uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # release/v1
35+
with:
36+
print-hash: true

docs/development/release-process.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ Release Process
1111

1212
$ nox -s release -- YY.N
1313

14-
You will need the password for your GPG key as well as an API token for PyPI.
14+
This creates and pushes a new tag for the release
1515

1616
#. Add a `release on GitHub <https://github.com/pypa/packaging/releases>`__.
1717

18+
This triggers a CI workflow which builds and publishes the package to PyPI
19+
1820
#. Notify the other project owners of the release.
1921

2022
.. note::

noxfile.py

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import tempfile
1313
import textwrap
1414
import time
15-
import webbrowser
1615
from pathlib import Path
1716

1817
import nox
@@ -141,8 +140,48 @@ def release(session):
141140
next_version = f"{major}.{minor + 1}.dev0"
142141
_bump(session, version=next_version, file=version_file, kind="development")
143142

144-
# Checkout the git tag.
145-
session.run("git", "checkout", "-q", release_version, external=True)
143+
# Push the commits and tag.
144+
# NOTE: The following fails if pushing to the branch is not allowed. This can
145+
# happen on GitHub, if the main branch is protected, there are required
146+
# CI checks and "Include administrators" is enabled on the protection.
147+
session.run("git", "push", "upstream", "main", release_version, external=True)
148+
149+
150+
@nox.session
151+
def release_build(session):
152+
package_name = "packaging"
153+
154+
# Parse version from command-line arguments, if provided, otherwise get
155+
# from Git tag.
156+
try:
157+
release_version = _get_version_from_arguments(session.posargs)
158+
except ValueError as e:
159+
if session.posargs:
160+
session.error(f"Invalid arguments: {e}")
161+
162+
release_version = session.run(
163+
"git", "describe", "--exact-match", silent=True, external=True
164+
)
165+
release_version = release_version.strip()
166+
session.debug(f"version: {release_version}")
167+
checkout = False
168+
else:
169+
checkout = True
170+
171+
# Check state of working directory.
172+
_check_working_directory_state(session)
173+
174+
# Ensure there are no uncommitted changes.
175+
result = subprocess.run(
176+
["git", "status", "--porcelain"], capture_output=True, encoding="utf-8"
177+
)
178+
if result.stdout:
179+
print(result.stdout, end="", file=sys.stderr)
180+
session.error("The working tree has uncommitted changes")
181+
182+
# Checkout the git tag, if provided.
183+
if checkout:
184+
session.run("git", "checkout", "-q", release_version, external=True)
146185

147186
session.install("build", "twine")
148187

@@ -162,24 +201,13 @@ def release(session):
162201
diff = "\n".join(diff_generator)
163202
session.error(f"Got the wrong files:\n{diff}")
164203

165-
# Get back out into main.
166-
session.run("git", "checkout", "-q", "main", external=True)
204+
# Get back out into main, if we checked out before.
205+
if checkout:
206+
session.run("git", "checkout", "-q", "main", external=True)
167207

168-
# Check and upload distribution files.
208+
# Check distribution files.
169209
session.run("twine", "check", *files)
170210

171-
# Push the commits and tag.
172-
# NOTE: The following fails if pushing to the branch is not allowed. This can
173-
# happen on GitHub, if the main branch is protected, there are required
174-
# CI checks and "Include administrators" is enabled on the protection.
175-
session.run("git", "push", "upstream", "main", release_version, external=True)
176-
177-
# Upload the distribution.
178-
session.run("twine", "upload", *files)
179-
180-
# Open up the GitHub release page.
181-
webbrowser.open("https://github.com/pypa/packaging/releases")
182-
183211

184212
@nox.session
185213
def update_licenses(session: nox.Session) -> None:

0 commit comments

Comments
 (0)