From bc2543a9f480977c2e0c3c70ceefa75436870413 Mon Sep 17 00:00:00 2001 From: Deepesh Kumar Date: Fri, 15 May 2026 10:07:48 +0530 Subject: [PATCH] Update Python publish workflow for version validation --- .github/workflows/python-publish.yml | 93 ++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 .github/workflows/python-publish.yml diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml new file mode 100644 index 0000000..f6eb432 --- /dev/null +++ b/.github/workflows/python-publish.yml @@ -0,0 +1,93 @@ +name: Publish to PyPI + +on: + release: + types: [published] + +permissions: + contents: read + +jobs: + # ── Job 1: Validate the version tag matches the package version ──────────── + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Check tag matches package version + run: | + # Extract version from __init__.py + PKG_VERSION=$(python -c "import re; content=open('contextzip/__init__.py').read(); print(re.search(r'__version__\s*=\s*[\"\'](.*?)[\"\']', content).group(1))") + # GitHub release tag (strips leading 'v' if present, e.g. v0.1.1 → 0.1.1) + TAG_VERSION="${GITHUB_REF_NAME#v}" + echo "Package version : $PKG_VERSION" + echo "Release tag : $TAG_VERSION" + if [ "$PKG_VERSION" != "$TAG_VERSION" ]; then + echo "❌ Version mismatch — update __init__.py and pyproject.toml before releasing" + exit 1 + fi + echo "✅ Versions match" + + # ── Job 2: Build the distributions ──────────────────────────────────────── + build: + runs-on: ubuntu-latest + needs: validate + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install build tool + run: pip install build + + - name: Build wheel and sdist + run: python -m build + + - name: Verify wheel contains entry_points.txt + run: | + python - << 'EOF' + import zipfile, sys, os + wheels = [f for f in os.listdir("dist") if f.endswith(".whl")] + if not wheels: + print("❌ No wheel found in dist/"); sys.exit(1) + with zipfile.ZipFile(f"dist/{wheels[0]}") as z: + names = z.namelist() + if not any("entry_points.txt" in n for n in names): + print("❌ entry_points.txt missing from wheel"); sys.exit(1) + print(f"✅ Wheel OK: {wheels[0]}") + ep = [n for n in names if "entry_points" in n][0] + print(z.read(ep).decode()) + EOF + + - name: Upload distributions + uses: actions/upload-artifact@v4 + with: + name: release-dists + path: dist/ + + # ── Job 3: Publish to PyPI via Trusted Publishing (no token needed) ──────── + publish: + runs-on: ubuntu-latest + needs: build + permissions: + id-token: write # required for trusted publishing + environment: + name: pypi + url: https://pypi.org/project/contextzip/${{ github.event.release.tag_name }} + steps: + - name: Download distributions + uses: actions/download-artifact@v4 + with: + name: release-dists + path: dist/ + + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: dist/