-
Notifications
You must be signed in to change notification settings - Fork 0
160 lines (140 loc) · 4.83 KB
/
release.yml
File metadata and controls
160 lines (140 loc) · 4.83 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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
name: Release
on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+" # v0.1.0 -> PyPI
- "v[0-9]+.[0-9]+.[0-9]+a[0-9]+" # v0.1.0a1 -> TestPyPI
- "v[0-9]+.[0-9]+.[0-9]+b[0-9]+" # v0.1.0b1 -> TestPyPI
- "v[0-9]+.[0-9]+.[0-9]+rc[0-9]+" # v0.1.0rc1 -> TestPyPI
jobs:
validate:
name: Validate tag and version
runs-on: ubuntu-latest
outputs:
is_prerelease: ${{ steps.classify.outputs.is_prerelease }}
version: ${{ steps.classify.outputs.version }}
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v4
- name: Set up Python
run: uv python install 3.13
- name: Classify tag and verify version
id: classify
run: |
set -euo pipefail
tag="${GITHUB_REF#refs/tags/}"
version="${tag#v}"
base_version="${version%%[abr]*}" # strip a1/b1/rc1 suffix if present
echo "Tag: $tag"
echo "Version from tag: $version"
echo "Base version: $base_version"
pyproject_version=$(uv run --no-sync python -c "import tomllib, pathlib; print(tomllib.loads(pathlib.Path('pyproject.toml').read_text())['project']['version'])")
echo "Version in pyproject.toml: $pyproject_version"
# Tag must either match pyproject.toml exactly (final release) OR be a
# prerelease (a/b/rc) of the version declared in pyproject.toml. This
# lets us dry-run v0.1.0rc1 before tagging v0.1.0 without bumping
# pyproject.toml churn.
if [ "$version" != "$pyproject_version" ] && [ "$base_version" != "$pyproject_version" ]; then
echo "::error::Tag version ($version) is not a release of pyproject.toml version ($pyproject_version)"
exit 1
fi
if [[ "$version" =~ (a|b|rc)[0-9]+$ ]]; then
echo "is_prerelease=true" >> "$GITHUB_OUTPUT"
else
echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
fi
echo "version=$version" >> "$GITHUB_OUTPUT"
build:
name: Build distributions
needs: validate
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v4
- name: Set up Python
run: uv python install 3.13
- name: Build sdist and wheel
run: uv build
- name: Check artifacts
run: uv run --with twine twine check dist/*
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
publish-testpypi:
name: Publish to TestPyPI
needs: [validate, build]
if: needs.validate.outputs.is_prerelease == 'true'
runs-on: ubuntu-latest
environment:
name: testpypi
url: https://test.pypi.org/project/devol/
permissions:
id-token: write
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- name: Publish to TestPyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
publish-pypi:
name: Publish to PyPI
needs: [validate, build]
if: needs.validate.outputs.is_prerelease == 'false'
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/project/devol/
permissions:
id-token: write
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
github-release:
name: Create GitHub Release
needs: [validate, build, publish-pypi]
if: needs.validate.outputs.is_prerelease == 'false'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Download artifacts
uses: actions/download-artifact@v4
with:
name: dist
path: dist/
- name: Extract changelog section
id: changelog
run: |
set -euo pipefail
version="${{ needs.validate.outputs.version }}"
awk -v v="$version" '
/^## \[/{ if(found) exit; if($0 ~ "\\[" v "\\]") { found=1; next } }
found { print }
' CHANGELOG.md > release_notes.md || true
if [ ! -s release_notes.md ]; then
echo "No changelog section found for $version; using generic message."
echo "Release $version" > release_notes.md
fi
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
files: dist/*
body_path: release_notes.md
tag_name: ${{ github.ref_name }}
name: ${{ needs.validate.outputs.version }}
draft: false
prerelease: false