Repository navigation
182 lines (170 loc) · 5.57 KB
/
Copy pathpublish.yml
File metadata and controls
182 lines (170 loc) · 5.57 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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
name: Publish
on:
workflow_dispatch:
inputs:
tag:
description: "Release tag to publish, for example v0.1.0"
required: true
type: string
permissions:
contents: read
jobs:
release-tag:
name: Resolve release tag
runs-on: ubuntu-latest
outputs:
tag: ${{ steps.release-tag.outputs.tag }}
version: ${{ steps.release-tag.outputs.version }}
steps:
- name: Resolve release tag
id: release-tag
run: |
tag="${{ inputs.tag }}"
if [[ ! "$tag" =~ ^v0\.[0-9]+\.[0-9]+$ ]]; then
echo "Refusing to publish tag '$tag'. Expected exact v0.MINOR.PATCH semver."
exit 1
fi
echo "tag=$tag" >> "$GITHUB_OUTPUT"
echo "version=${tag#v}" >> "$GITHUB_OUTPUT"
release-metadata:
name: Validate release metadata
needs: release-tag
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
ref: ${{ needs.release-tag.outputs.tag }}
- name: Match package versions to release tag
env:
RELEASE_VERSION: ${{ needs.release-tag.outputs.version }}
run: |
python - <<'PY'
import os
import tomllib
from pathlib import Path
expected = os.environ["RELEASE_VERSION"]
with Path("pyproject.toml").open("rb") as file:
root = tomllib.load(file)["project"]
cli_dependency = next(
item for item in root["dependencies"] if item.startswith("sqlclean-cli==")
).partition("==")[2]
with Path("packages/sqlclean-cli/pyproject.toml").open("rb") as file:
cli_package_version = tomllib.load(file)["project"]["version"]
with Path("Cargo.toml").open("rb") as file:
workspace_version = tomllib.load(file)["workspace"]["package"]["version"]
manifests = [
("root project", root["version"]),
("root CLI dependency", cli_dependency),
("CLI package", cli_package_version),
("Cargo workspace", workspace_version),
]
mismatches = [f"{label}={version}" for label, version in manifests if version != expected]
if mismatches:
raise SystemExit(
f"Release tag version {expected} does not match: {', '.join(mismatches)}"
)
PY
wheels:
name: Build wheel (${{ matrix.platform.name }})
needs: [release-tag, release-metadata]
runs-on: ${{ matrix.platform.runner }}
strategy:
fail-fast: false
matrix:
platform:
- name: linux-x86_64
runner: ubuntu-latest
target: x86_64
- name: linux-aarch64
runner: ubuntu-24.04-arm
target: aarch64
- name: macos-x86_64
runner: macos-latest
target: x86_64
- name: macos-arm64
runner: macos-latest
target: aarch64
- name: windows-x86_64
runner: windows-latest
target: x86_64
steps:
- uses: actions/checkout@v5
with:
ref: ${{ needs.release-tag.outputs.tag }}
- uses: actions/setup-python@v6
with:
python-version: "3.12"
- uses: dtolnay/rust-toolchain@master
with:
toolchain: 1.95.0
# sqlclean-cli ships one standalone Rust executable and links no libpython,
# so maturin tags it py3-none-<platform>. The tag is asserted before release.
- name: Build native CLI wheel
uses: PyO3/maturin-action@v1
with:
command: build
args: --release --out ../../dist
target: ${{ matrix.platform.target }}
manylinux: auto
working-directory: packages/sqlclean-cli
- name: Assert native CLI wheel is interpreter-agnostic
shell: bash
run: bash .github/scripts/assert_cli_wheel_tags.sh dist
- uses: actions/upload-artifact@v5
with:
name: wheel-${{ matrix.platform.name }}
path: dist
sdist:
name: Build sdists and Python wheel
needs: [release-tag, release-metadata]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
ref: ${{ needs.release-tag.outputs.tag }}
- uses: dtolnay/rust-toolchain@master
with:
toolchain: 1.95.0
- uses: astral-sh/setup-uv@v6
with:
version: "0.12.9"
# The sqlclean package is pure Python, so one wheel serves every platform.
- name: Build Python package sdist and wheel
run: uv build --sdist --wheel --out-dir dist
- name: Build native CLI sdist
uses: PyO3/maturin-action@v1
with:
command: sdist
args: --out ../../dist
working-directory: packages/sqlclean-cli
- uses: actions/upload-artifact@v5
with:
name: sdist
path: dist
pypi:
name: Publish to PyPI
needs:
- release-tag
- wheels
- sdist
runs-on: ubuntu-latest
environment: pypi
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v5
with:
ref: ${{ needs.release-tag.outputs.tag }}
- uses: actions/download-artifact@v5
with:
path: dist
merge-multiple: true
- name: Assert native CLI wheels are interpreter-agnostic
shell: bash
run: bash .github/scripts/assert_cli_wheel_tags.sh dist
- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist
skip-existing: true