Skip to content

Add TestPyPI dry-run publish job #12

Add TestPyPI dry-run publish job

Add TestPyPI dry-run publish job #12

Workflow file for this run

name: Wheels
on:
push:
branches: [main]
tags: ['v*']
pull_request:
workflow_dispatch:
inputs:
testpypi:
description: "Dry run: publish built wheels + sdist to TestPyPI"
type: boolean
default: false
# Cancel superseded runs on the same ref.
concurrency:
group: wheels-${{ github.ref }}
cancel-in-progress: true
jobs:
build_wheels:
name: Wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
# macOS : macos-15-intel (x86_64) + macos-15 (arm64)
# Linux : ubuntu-latest (x86_64) + ubuntu-24.04-arm (arm64)
# Windows is intentionally absent: the bundled FronTier library does not
# compile under MSVC (Unix/GCC code — POINT/boolean clash with the
# Windows SDK, GCC anonymous-struct tags). Windows users can build from
# the sdist under WSL or use the Linux wheels. See the README.
os: [macos-15-intel, macos-15, ubuntu-latest, ubuntu-24.04-arm]
steps:
# vcell-messaging / vcell-expressionparser are PRIVATE submodules, so the
# default GITHUB_TOKEN cannot fetch them. Authenticate with SUBMODULE_TOKEN
# the same way build-and-release.yml does.
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Configure git for private submodules
shell: bash
run: |
git config --global url."https://x-access-token:${{ secrets.SUBMODULE_TOKEN }}@github.com/".insteadOf "https://github.com/"
- name: Initialize submodules
shell: bash
run: git submodule update --init --recursive
- name: Build wheels
uses: pypa/cibuildwheel@v3.4.0
env:
CIBW_ARCHS: native
- uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}
path: ./wheelhouse/*.whl
retention-days: 7
make_sdist:
name: Source distribution
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Configure git for private submodules
shell: bash
run: |
git config --global url."https://x-access-token:${{ secrets.SUBMODULE_TOKEN }}@github.com/".insteadOf "https://github.com/"
- name: Initialize submodules
shell: bash
run: git submodule update --init --recursive
- name: Build sdist
run: pipx run build --sdist
- uses: actions/upload-artifact@v4
with:
name: sdist
path: dist/*.tar.gz
retention-days: 7
# Dry run: manually trigger this workflow (Actions tab → Run workflow, or
# `gh workflow run wheels.yml -f testpypi=true`) to publish to TestPyPI.
# Requires a TestPyPI trusted publisher for this repo + workflow + the
# `testpypi` environment (see README). skip-existing avoids a hard failure
# if that version was already uploaded in a previous dry run.
publish-testpypi:
name: Publish to TestPyPI (dry run)
needs: [build_wheels, make_sdist]
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch' && inputs.testpypi
environment: testpypi
permissions:
id-token: write # OIDC token for trusted publishing
steps:
- uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true
- uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
skip-existing: true
# Real publish: dormant until a v* tag is pushed AND the PyPI project has a
# trusted publisher configured for this repo + workflow (see README). Normal
# pushes/PRs only produce downloadable wheel artifacts above.
publish:
name: Publish to PyPI
needs: [build_wheels, make_sdist]
runs-on: ubuntu-latest
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
environment: pypi
permissions:
id-token: write # OIDC token for trusted publishing
steps:
- uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true
- uses: pypa/gh-action-pypi-publish@release/v1