Skip to content

Commit 1500b8a

Browse files
committed
fix: resolve PyPl issue with publishing multiple packages at once by publishing one package by one
1 parent ff78b0e commit 1500b8a

1 file changed

Lines changed: 37 additions & 73 deletions

File tree

.github/workflows/release.yaml

Lines changed: 37 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
name: Release
2+
run-name: Release (package=${{ inputs.package || 'all' }} ref=${{ github.ref_name }})
23

34
on:
45
push:
5-
tags:
6-
- "v*"
6+
tags: ["v*"]
77
workflow_dispatch:
88
inputs:
99
package:
@@ -24,108 +24,78 @@ on:
2424

2525
jobs:
2626
build:
27-
name: Build + test + package (monorepo)
2827
runs-on: ubuntu-latest
29-
3028
steps:
3129
- uses: actions/checkout@v4
3230
with:
3331
fetch-depth: 0
3432
persist-credentials: false
3533

36-
- name: Install uv (Python 3.12)
37-
uses: astral-sh/setup-uv@v7
34+
- uses: astral-sh/setup-uv@v7
3835
with:
3936
python-version: "3.12"
4037
enable-cache: true
4138

42-
- name: Sync (workspace + dev + all extras)
43-
run: uv sync --all-packages --all-extras --dev --locked
44-
45-
- name: Run tests
46-
run: uv run pytest
47-
48-
- name: Install build backend
49-
run: uv run python -m pip install --upgrade build
39+
- run: uv sync --all-packages --all-extras --dev --locked
40+
- run: uv run pytest
41+
- run: uv run python -m pip install --upgrade build
5042

5143
- name: Verify tag matches all package versions (tag runs only)
52-
if: startsWith(github.ref, 'refs/tags/v')
44+
if: ${{ startsWith(github.ref, 'refs/tags/v') }}
5345
run: |
5446
uv run python - << 'PY'
5547
import os, sys, pathlib, tomllib
56-
57-
tag = os.environ["GITHUB_REF_NAME"] # v0.1.0
48+
tag = os.environ["GITHUB_REF_NAME"]
5849
ver = tag[1:] if tag.startswith("v") else tag
59-
60-
pyprojects = [pathlib.Path("pyproject.toml")]
61-
pyprojects += sorted(pathlib.Path("packages").glob("*/pyproject.toml"))
62-
63-
mismatches = []
50+
pyprojects = [pathlib.Path("pyproject.toml")] + sorted(pathlib.Path("packages").glob("*/pyproject.toml"))
51+
bad = []
6452
for p in pyprojects:
65-
data = tomllib.loads(p.read_text(encoding="utf-8"))
66-
v = data.get("project", {}).get("version")
53+
v = tomllib.loads(p.read_text(encoding="utf-8")).get("project", {}).get("version")
6754
if v != ver:
68-
mismatches.append((str(p), v))
69-
70-
if mismatches:
71-
for p, v in mismatches:
55+
bad.append((str(p), v))
56+
if bad:
57+
for p, v in bad:
7258
print(f"Version mismatch: {p}: {v!r} != {ver!r}")
7359
sys.exit(1)
74-
75-
print("OK: all versions match", ver)
60+
print("OK:", ver)
7661
PY
7762
7863
- name: Build all distributions into per-package dirs
7964
run: |
8065
uv run python - << 'PY'
8166
import pathlib, tomllib, subprocess, sys
82-
8367
root = pathlib.Path(".").resolve()
84-
dist_root = root / "dist"
85-
dist_root.mkdir(exist_ok=True)
86-
87-
def project_name(pyproject: pathlib.Path) -> str:
88-
data = tomllib.loads(pyproject.read_text(encoding="utf-8"))
89-
name = data.get("project", {}).get("name")
90-
if not name:
91-
raise RuntimeError(f"Missing [project].name in {pyproject}")
92-
return name
93-
94-
# root package
95-
root_name = project_name(root / "pyproject.toml")
96-
(dist_root / root_name).mkdir(parents=True, exist_ok=True)
97-
subprocess.check_call([sys.executable, "-m", "build", "--outdir", str(dist_root / root_name), str(root)])
98-
99-
# workspace members
100-
pkgs_dir = root / "packages"
101-
if pkgs_dir.exists():
102-
for pyproject in sorted(pkgs_dir.glob("*/pyproject.toml")):
103-
pkg_dir = pyproject.parent
104-
name = project_name(pyproject)
105-
out = dist_root / name
106-
out.mkdir(parents=True, exist_ok=True)
107-
print(f"Building {name} from {pkg_dir}")
108-
subprocess.check_call([sys.executable, "-m", "build", "--outdir", str(out), str(pkg_dir)])
109-
110-
print("Built dists into:", dist_root)
68+
dist = root / "dist"
69+
dist.mkdir(exist_ok=True)
70+
71+
def name(pp):
72+
return tomllib.loads(pp.read_text(encoding="utf-8"))["project"]["name"]
73+
74+
# root
75+
root_name = name(root / "pyproject.toml")
76+
(dist / root_name).mkdir(parents=True, exist_ok=True)
77+
subprocess.check_call([sys.executable, "-m", "build", "--outdir", str(dist / root_name), str(root)])
78+
79+
# members
80+
for pp in sorted((root / "packages").glob("*/pyproject.toml")):
81+
pkg = pp.parent
82+
n = name(pp)
83+
(dist / n).mkdir(parents=True, exist_ok=True)
84+
subprocess.check_call([sys.executable, "-m", "build", "--outdir", str(dist / n), str(pkg)])
11185
PY
11286
113-
- name: Upload dists artifact
114-
uses: actions/upload-artifact@v4
87+
- uses: actions/upload-artifact@v4
11588
with:
11689
name: python-package-distributions
11790
path: dist/
11891

11992
publish:
120-
name: Publish to PyPI (Trusted Publishing)
12193
needs: [build]
12294
runs-on: ubuntu-latest
123-
12495
permissions:
12596
id-token: write
12697
contents: read
12798

128-
# One job per package (recommended; invoking pypi-publish multiple times in one job is not supported)
12999
strategy:
130100
fail-fast: false
131101
matrix:
@@ -139,25 +109,19 @@ jobs:
139109
- devqubit-cirq
140110
- devqubit-braket
141111

142-
# On tag push: publish all packages.
143-
# On manual run: publish only the selected one (or all).
144-
if: |
145-
github.event_name == 'push' ||
146-
(github.event_name == 'workflow_dispatch' && (inputs.package == 'all' || inputs.package == matrix.package))
112+
if: ${{ github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && (inputs.package == 'all' || inputs.package == matrix.package)) }}
147113

148114
environment:
149115
name: pypi
150-
url: https://pypi.org/p/${{ matrix.package }}
116+
url: https://pypi.org/project/${{ matrix.package }}/
151117

152118
steps:
153-
- name: Download dists
154-
uses: actions/download-artifact@v4
119+
- uses: actions/download-artifact@v4
155120
with:
156121
name: python-package-distributions
157122
path: dist/
158123

159-
- name: Publish ${{ matrix.package }}
160-
uses: pypa/gh-action-pypi-publish@release/v1
124+
- uses: pypa/gh-action-pypi-publish@release/v1
161125
with:
162126
packages-dir: dist/${{ matrix.package }}
163127
skip-existing: true

0 commit comments

Comments
 (0)