-
Notifications
You must be signed in to change notification settings - Fork 0
103 lines (90 loc) · 3.13 KB
/
Copy pathrelease.yml
File metadata and controls
103 lines (90 loc) · 3.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
name: Release
# Builds the wheel and sdist and publishes them to PyPI. Triggered by pushing
# a version tag (e.g. v0.2.1); also runnable manually for dry runs.
on:
push:
tags: ["v*"]
workflow_dispatch:
permissions:
contents: write
# Re-pushing a tag (or re-dispatching) cancels an in-flight run for the same
# ref so a stuck build can't pile up behind a newer attempt.
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
name: Build distribution
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
# Fail fast if the tag doesn't match pyproject.toml's version, so the
# GitHub Release name can never disagree with the version published to PyPI.
- name: Check tag matches package version
if: startsWith(github.ref, 'refs/tags/')
run: |
pkg=$(grep -m1 '^version' pyproject.toml | cut -d'"' -f2)
tag=${GITHUB_REF_NAME#v}
if [ "$pkg" != "$tag" ]; then
echo "::error::Tag v${tag} does not match pyproject.toml version ${pkg}. Bump pyproject.toml (e.g. 'make bump-patch') and re-tag."
exit 1
fi
echo "Tag and package version agree: ${pkg}"
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
python-version: "3.12"
- name: Build wheel and sdist
run: uv build
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
if-no-files-found: error
release:
name: Publish to PyPI and GitHub
needs: build
runs-on: ubuntu-latest
# Only publish for real tag pushes; workflow_dispatch runs just build + verify.
if: startsWith(github.ref, 'refs/tags/')
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: dist
path: dist
- name: List artifacts
run: ls -lR dist
# This job runs on a fresh runner that never checked out the repo or ran
# the build job's setup, so uv isn't on PATH here — `uv publish` below
# needs its own install.
- name: Install uv
uses: astral-sh/setup-uv@v5
with:
python-version: "3.12"
- name: Publish to PyPI
env:
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN }}
run: uv publish
- name: Publish GitHub Release
env:
GH_TOKEN: ${{ github.token }}
# This job doesn't check out the repo, so gh can't infer it from a local
# git remote — pass --repo explicitly on every gh call.
run: |
set -euo pipefail
tag="${GITHUB_REF_NAME}"
repo="${GITHUB_REPOSITORY}"
if gh release view "$tag" --repo "$repo" >/dev/null 2>&1; then
echo "Release $tag exists; uploading assets (clobbering)."
gh release upload "$tag" dist/* --repo "$repo" --clobber
else
echo "Creating release $tag."
gh release create "$tag" \
--repo "$repo" \
--title "$tag" \
--generate-notes \
dist/*
fi