Skip to content

Commit 4fa5ad9

Browse files
committed
ci: add PyPI publish workflow (org-standard, SHA-pinned)
1 parent 645255b commit 4fa5ad9

1 file changed

Lines changed: 76 additions & 0 deletions

File tree

.github/workflows/publish.yml

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
name: Publish to PyPI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
workflow_dispatch:
7+
8+
concurrency:
9+
group: publish-${{ github.ref }}
10+
cancel-in-progress: false
11+
12+
permissions:
13+
contents: read
14+
15+
jobs:
16+
publish:
17+
if: github.ref == 'refs/heads/main'
18+
runs-on: ubuntu-latest
19+
steps:
20+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
21+
22+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
23+
with:
24+
python-version: '3.11'
25+
26+
- name: Upgrade pip and install build
27+
run: |
28+
python -m pip install --upgrade pip
29+
python -m pip install build
30+
31+
- name: Install project with dev extras
32+
if: hashFiles('tests/**') != ''
33+
run: pip install -e ".[dev]"
34+
35+
- name: Run tests
36+
if: hashFiles('tests/**') != ''
37+
run: pytest
38+
39+
- name: Read package metadata
40+
id: meta
41+
run: |
42+
PKG_NAME=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['name'])")
43+
PKG_VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
44+
echo "name=$PKG_NAME" >> "$GITHUB_OUTPUT"
45+
echo "version=$PKG_VERSION" >> "$GITHUB_OUTPUT"
46+
47+
- name: Check if version is already published
48+
id: check
49+
run: |
50+
PKG_NAME="${{ steps.meta.outputs.name }}"
51+
PKG_VERSION="${{ steps.meta.outputs.version }}"
52+
HTTP_CODE=$(curl -sS --connect-timeout 10 --max-time 20 -o /dev/null -w "%{http_code}" "https://pypi.org/pypi/$PKG_NAME/$PKG_VERSION/json")
53+
case "$HTTP_CODE" in
54+
200)
55+
echo "$PKG_NAME==$PKG_VERSION already published on PyPI, skipping."
56+
echo "should_publish=false" >> "$GITHUB_OUTPUT"
57+
;;
58+
404)
59+
echo "$PKG_NAME==$PKG_VERSION not found on PyPI, will publish."
60+
echo "should_publish=true" >> "$GITHUB_OUTPUT"
61+
;;
62+
*)
63+
echo "Unexpected PyPI response (HTTP $HTTP_CODE). Failing to avoid incorrect publish."
64+
exit 1
65+
;;
66+
esac
67+
68+
- name: Build distribution
69+
if: steps.check.outputs.should_publish == 'true'
70+
run: python -m build
71+
72+
- name: Publish to PyPI
73+
if: steps.check.outputs.should_publish == 'true'
74+
uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
75+
with:
76+
password: ${{ secrets.PYPI_API_TOKEN }}

0 commit comments

Comments
 (0)