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+ jobs :
13+ build :
14+ name : Build distribution
15+ runs-on : ubuntu-latest
16+ outputs :
17+ version : ${{ steps.version.outputs.version }}
18+ permissions :
19+ contents : read
20+ steps :
21+ - uses : actions/checkout@v6
22+ with :
23+ fetch-depth : 0
24+
25+ - name : Set up Python
26+ uses : actions/setup-python@v6
27+ with :
28+ python-version : ' 3.12'
29+
30+ - name : Generate date-based version
31+ id : version
32+ env :
33+ PACKAGE_NAME : acedatacloud-scaffold
34+ run : |
35+ python - <<'PY'
36+ import json
37+ import os
38+ import urllib.request
39+ from datetime import datetime, timezone
40+
41+ package_name = os.environ['PACKAGE_NAME']
42+ date_prefix = datetime.now(timezone.utc).strftime('%Y.%-m.%-d')
43+ next_build = 0
44+
45+ try:
46+ with urllib.request.urlopen(f'https://pypi.org/pypi/{package_name}/json', timeout=10) as response:
47+ releases = json.load(response).get('releases', {})
48+ builds = []
49+ for release in releases:
50+ if not release.startswith(f'{date_prefix}.'):
51+ continue
52+ parts = release.split('.')
53+ if len(parts) != 4:
54+ continue
55+ try:
56+ builds.append(int(parts[3]))
57+ except ValueError:
58+ continue
59+ if builds:
60+ next_build = max(builds) + 1
61+ except Exception:
62+ next_build = 0
63+
64+ version = f'{date_prefix}.{next_build}'
65+ with open(os.environ['GITHUB_OUTPUT'], 'a', encoding='utf-8') as fh:
66+ fh.write(f'version={version}\n')
67+ print(f'Generated version: {version}')
68+ PY
69+
70+ - name : Update package version
71+ env :
72+ VERSION : ${{ steps.version.outputs.version }}
73+ run : |
74+ python - <<'PY'
75+ import os
76+ import pathlib
77+ import re
78+
79+ version = os.environ['VERSION']
80+ version_file = pathlib.Path('acedatacloud_scaffold/__version__.py')
81+ content = version_file.read_text(encoding='utf-8')
82+ updated = re.sub(
83+ r'^VERSION = \([^\n]+\)$',
84+ f'VERSION = ({", ".join(version.split("."))})',
85+ content,
86+ count=1,
87+ flags=re.MULTILINE,
88+ )
89+ if updated == content:
90+ raise SystemExit('Failed to update VERSION tuple in acedatacloud_scaffold/__version__.py')
91+ version_file.write_text(updated, encoding='utf-8')
92+ print(version_file.read_text(encoding='utf-8'))
93+ PY
94+
95+ - name : Install build dependencies
96+ run : |
97+ python -m pip install --upgrade pip
98+ pip install build "twine>=6.1.0,<7.0.0"
99+
100+ - name : Build package
101+ run : python -m build
102+
103+ - name : Check package metadata
104+ run : twine check dist/*
105+
106+ - name : Upload distribution artifacts
107+ uses : actions/upload-artifact@v7
108+ with :
109+ name : python-package-distributions
110+ path : dist/
111+
112+ publish-pypi :
113+ name : Publish to PyPI
114+ needs : build
115+ runs-on : ubuntu-latest
116+ environment :
117+ name : pypi
118+ url : https://pypi.org/project/acedatacloud-scaffold/${{ needs.build.outputs.version }}
119+ permissions :
120+ contents : read
121+ steps :
122+ - name : Download distribution artifacts
123+ uses : actions/download-artifact@v8
124+ with :
125+ name : python-package-distributions
126+ path : dist/
127+
128+ - name : Publish to PyPI
129+ env :
130+ TWINE_USERNAME : __token__
131+ TWINE_PASSWORD : ${{ secrets.PYPI_TOKEN }}
132+ run : |
133+ python -m pip install --upgrade pip
134+ pip install "twine>=6.1.0,<7.0.0"
135+ twine upload dist/*
136+
137+ create-release :
138+ name : Create GitHub Release
139+ if : github.event_name == 'push'
140+ needs : [build, publish-pypi]
141+ runs-on : ubuntu-latest
142+ permissions :
143+ contents : write
144+ steps :
145+ - uses : actions/checkout@v6
146+
147+ - name : Download distribution artifacts
148+ uses : actions/download-artifact@v8
149+ with :
150+ name : python-package-distributions
151+ path : dist/
152+
153+ - name : Create Release
154+ env :
155+ GITHUB_TOKEN : ${{ github.token }}
156+ run : |
157+ gh release create "v${{ needs.build.outputs.version }}" dist/* \
158+ --title "v${{ needs.build.outputs.version }}" \
159+ --generate-notes \
160+ --repo '${{ github.repository }}' || echo "Release already exists, skipping"
0 commit comments