-
Notifications
You must be signed in to change notification settings - Fork 42
120 lines (99 loc) · 3.43 KB
/
pypi.yml
File metadata and controls
120 lines (99 loc) · 3.43 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
name: Publish to PyPI
on:
workflow_dispatch:
release:
types: [published]
concurrency:
group: pypi-${{ github.event.release.tag_name || github.ref_name }}
cancel-in-progress: true
permissions:
contents: read
jobs:
build:
name: Build distribution
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install build tools
run: |
python -m pip install --upgrade pip
python -m pip install build twine
- name: Build sdist and wheel
run: python -m build
- name: Check distribution metadata
run: python -m twine check dist/*
- name: Upload dist artifact
uses: actions/upload-artifact@v4
with:
name: pypi-dist
path: dist/*
publish:
name: Publish Project_Chronos to PyPI
needs: build
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/project/Project_Chronos/
permissions:
id-token: write
contents: read
steps:
- name: Download dist artifact
uses: actions/download-artifact@v4
with:
name: pypi-dist
path: dist
- name: Check whether this version is already on PyPI
id: pypi_version
shell: bash
run: |
python - <<'PY' >> "$GITHUB_OUTPUT"
import glob
import re
import urllib.error
import urllib.parse
import urllib.request
import zipfile
wheels = glob.glob("dist/*.whl")
if not wheels:
raise SystemExit("No wheel artifact found in dist/")
with zipfile.ZipFile(wheels[0]) as zf:
metadata_name = next(
name for name in zf.namelist()
if name.endswith(".dist-info/METADATA")
)
metadata = zf.read(metadata_name).decode("utf-8", errors="replace")
project = version = ""
for line in metadata.splitlines():
if line.startswith("Name: "):
project = line.split(":", 1)[1].strip()
elif line.startswith("Version: "):
version = line.split(":", 1)[1].strip()
if not re.fullmatch(r"[A-Za-z0-9_.-]+", project or ""):
raise SystemExit(f"Invalid project name from wheel metadata: {project!r}")
if not version:
raise SystemExit("Missing version in wheel metadata")
url = f"https://pypi.org/pypi/{urllib.parse.quote(project)}/{urllib.parse.quote(version)}/json"
try:
with urllib.request.urlopen(url, timeout=20) as response:
exists = response.status == 200
except urllib.error.HTTPError as exc:
if exc.code == 404:
exists = False
else:
raise
print(f"project={project}")
print(f"version={version}")
print(f"exists={str(exists).lower()}")
PY
- name: Publish to PyPI
if: steps.pypi_version.outputs.exists != 'true'
uses: pypa/gh-action-pypi-publish@release/v1
- name: Skip existing PyPI version
if: steps.pypi_version.outputs.exists == 'true'
run: |
echo "${{ steps.pypi_version.outputs.project }} ${{ steps.pypi_version.outputs.version }} already exists on PyPI; skipping publish."