Skip to content

Commit 9dfeb16

Browse files
authored
Update release.yml (#15)
1 parent ac3b7db commit 9dfeb16

1 file changed

Lines changed: 42 additions & 9 deletions

File tree

.github/workflows/release.yml

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,18 @@ name: Release
22

33
on:
44
push:
5-
tags: [ 'v*.*.*' ]
6-
workflow_dispatch: {}
5+
tags: [ 'v*.*.*' ] # only runs on semver-like tags
6+
workflow_dispatch: {} # manual runs won't publish unless also with a tag
77

88
permissions:
99
contents: read
1010

1111
jobs:
1212
build-publish:
13-
# uncomment the next line ONLY if you set an Environment name on PyPI's Trusted Publisher
14-
# environment: pypi
1513
runs-on: ubuntu-latest
1614
permissions:
17-
contents: write # attach assets to GH Release
18-
id-token: write # OIDC for PyPI Trusted Publisher
15+
contents: write # attach assets to GH Release
16+
id-token: write # OIDC for PyPI Trusted Publisher
1917
steps:
2018
- name: Checkout
2119
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
@@ -25,7 +23,7 @@ jobs:
2523
with:
2624
python-version: "3.12"
2725

28-
# Install build + twine via pipx (no raw pip)
26+
# Tools via pipx (pinned; no raw pip)
2927
- name: Install pipx + tools
3028
run: |
3129
set -euxo pipefail
@@ -36,8 +34,23 @@ jobs:
3634
pipx install build==1.2.2
3735
pipx install twine==5.1.1
3836
37+
# tag (vX.Y.Z) must match pyproject.toml version (X.Y.Z)
38+
- name: Check version matches tag
39+
id: vercheck
40+
run: |
41+
TAG="${GITHUB_REF_NAME#v}"
42+
PYVER=$(python - <<'PY'
43+
import sys, tomllib, pathlib
44+
data = tomllib.loads(pathlib.Path("pyproject.toml").read_text(encoding="utf-8"))
45+
print(data["project"]["version"])
46+
PY
47+
)
48+
echo "tag=${TAG}"
49+
echo "pyproject=${PYVER}"
50+
test "$PYVER" = "$TAG" || { echo "ERROR: pyproject.toml version != tag"; exit 1; }
51+
3952
- name: Build distributions
40-
run: python -m build -o dist
53+
run: pyproject-build -o dist
4154

4255
- name: Twine check
4356
run: twine check dist/*
@@ -51,8 +64,28 @@ jobs:
5164
env:
5265
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
5366

67+
# skip if version already on PyPI (prevents "File already exists")
68+
- name: Skip if version exists on PyPI
69+
id: pypi-exists
70+
run: |
71+
PKG="decision-security"
72+
VER="${GITHUB_REF_NAME#v}"
73+
python - <<PY
74+
import json, sys, urllib.request
75+
pkg = sys.argv[1]; ver = sys.argv[2]
76+
try:
77+
with urllib.request.urlopen(f"https://pypi.org/pypi/{pkg}/json", timeout=10) as r:
78+
data = json.load(r)
79+
if ver in data.get("releases", {}):
80+
print(f"Version {ver} already on PyPI; skipping publish.")
81+
sys.exit(78) # neutral
82+
except Exception:
83+
pass
84+
PY
85+
continue-on-error: true
86+
5487
- name: Publish to PyPI (OIDC Trusted Publisher)
55-
if: startsWith(github.ref, 'refs/tags/')
88+
if: startsWith(github.ref, 'refs/tags/') && steps.pypi-exists.outcome != 'success'
5689
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
5790
with:
5891
print-hash: true

0 commit comments

Comments
 (0)