Skip to content

Bump cibuildwheel from 2.17.0 to 2.18.1, increase minimum macOS requirement to Catalina to ensure binary compatibility #1941

Bump cibuildwheel from 2.17.0 to 2.18.1, increase minimum macOS requirement to Catalina to ensure binary compatibility

Bump cibuildwheel from 2.17.0 to 2.18.1, increase minimum macOS requirement to Catalina to ensure binary compatibility #1941

Workflow file for this run

name: Build PyPop
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
on:
workflow_dispatch:
pull_request:
paths-ignore:
- '**.md'
- '**.rst'
- 'CITATION.cff'
- '.zenodo.json'
- 'website/**'
- '.github/dependabot.yml'
- '.github/release-drafter.yml'
- '.github/ISSUE_TEMPLATE/**'
- '.github/workflows/documentation.yaml'
- '.github/workflows/buildjet_arm64.yml'
- '.github/workflows/release-drafter.yml'
- '.github/workflows/codeql.yml'
- '.gitattributes'
push:
paths-ignore:
- '**.md'
- '**.rst'
- 'CITATION.cff'
- '.zenodo.json'
- 'website/**'
- '.github/dependabot.yml'
- '.github/release-drafter.yml'
- '.github/ISSUE_TEMPLATE/**'
- '.github/workflows/documentation.yaml'
- '.github/workflows/buildjet_arm64.yml'
- '.github/workflows/release-drafter.yml'
- '.github/workflows/codeql.yml'
- '.gitattributes'
release:
types:
- published
jobs:
skip_publish_zenodo:
name: Non publication, Zenodo skip
runs-on: ubuntu-latest
# FIXME: this is the default action, the logical inverse of the
# below "if" in publish_zenodo: a bit hacky, but it works
if: (github.event_name == 'release' && github.event.action == 'published' && github.event.release.prerelease == false) == false
steps:
- name: Skip Zenodo step unless publishing release
run: |
echo "Not a publication release, skipping Zenodo"
echo "github.ref: ${{ toJson(github.ref) }}"
echo "github.event_name: ${{ toJson(github.event_name) }}"
echo "github.event.action: ${{ toJson(github.event.action) }}"
publish_zenodo:
name: Production release, Zenodo publication
runs-on: ubuntu-latest
# "else" we *are* publishing something, only works for non-pre-releases on the main branch
if: github.event.release.target_commitish == 'main' && github.event_name == 'release' && github.event.action == 'published' && github.event.release.prerelease == false
steps:
- name: Checkout the contents of your repository
uses: actions/checkout@v4
- name: Upsert the version and related ids in the metadata in .zenodo.json
run: |
echo "GITHUB_REF_NAME = $GITHUB_REF_NAME | GITHUB_REF = $GITHUB_REF | GITHUB_EVENT_PATH = $GITHUB_EVENT_PATH"
echo "github.event.release.target_commitish = ${{ github.event.release.target_commitish }}"
# convert semver to Python-style version
VERSION_PYTHON_STYLE=$(GITHUB_REF_NAME=$GITHUB_REF_NAME python -c 'import os; from packaging import version; print(str(version.Version(os.getenv("GITHUB_REF_NAME"))))')
echo "VERSION_PYTHON_STYLE = $VERSION_PYTHON_STYLE"
# cp .zenodo.json .zenodo.orig.json
# update the 'related_identifiers' to use exact tree and pypi packaage
cat .zenodo.json | jq "(.related_identifiers[] | (select (.relation == \"isSourceOf\" and .resource_type == \"software\")) | select (.identifier | startswith(\"https://pypi.org/project/pypop-genomics\")).identifier) |= \"https://pypi.org/project/pypop-genomics/$VERSION_PYTHON_STYLE\"" | jq "(.related_identifiers[] | (select (.relation == \"isSupplementTo\" and .resource_type == \"software\")) | select (.identifier | startswith(\"https://github.com/alexlancaster/pypop\")).identifier) |= \"https://github.com/alexlancaster/pypop/tree/$GITHUB_REF_NAME\"" > .zenodo.mod.json
# update the version number
echo "{\"version\": \"$GITHUB_REF_NAME\"}" | cat .zenodo.mod.json - | jq -s add > .zenodo.json
# debugging only
cat .zenodo.json
rm .zenodo.mod.json
- name: Upsert the version in the metadata in CITATION.cff
run: |
yq -i ".version = \"$GITHUB_REF_NAME\"" CITATION.cff
- name: Push changes back to repo files
run: |
git fetch origin
git config --global user.name "ci-pypop"
git config --global user.email "username@users.noreply.github.com"
git checkout -b $GITHUB_REF_NAME-with-upserting-changes-pre-upload
git add .zenodo.json CITATION.cff
git commit -m "Upserted version into CITATION.cff and into .zenodo.json"
git checkout ${{ github.event.release.target_commitish }}
git merge $GITHUB_REF_NAME-with-upserting-changes-pre-upload
git push origin ${{ github.event.release.target_commitish }}
# FIXME: removing files marked with 'export-ignore' 'set' in .gitattributes
# before zenodraft creates the zipball using https://stackoverflow.com/a/30573319
# to ensure that we handle filenames with potential ':' or newlines
git ls-files -z|git check-attr --stdin -z export-ignore |sed -zne 'x;n;n;s/^set$//;t print;b;:print;x;p'|xargs --null rm
# FIXME: need to also remove orphaned empty directories resulting from above
find . -empty -type d -delete
- name: Create a draft snapshot of your repository contents as a new
version in test collection on Zenodo using metadata
from repository file .zenodo.json
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ZENODO_ACCESS_TOKEN: ${{ secrets.ZENODO_ACCESS_TOKEN }}
uses: zenodraft/action@0.13.3
# uses: alexlancaster/zenodraft-action@0.10.2
with:
concept: 10080667
metadata: .zenodo.json
publish: false
sandbox: false
compression: zip
upsert-doi: true
upsert-location: doi
verbose: true
generate-wheels-matrix:
# Create a matrix of all architectures & versions to build.
# This enables the next step to run cibuildwheel in parallel.
# From https://iscinumpy.dev/post/cibuildwheel-2-10-0/#only-210
name: Generate wheels matrix
runs-on: ubuntu-latest
outputs:
include: ${{ steps.set-matrix.outputs.include }}
steps:
- uses: actions/checkout@v4
- name: Install cibuildwheel
# Nb. keep cibuildwheel version pin consistent with job below
run: pipx install cibuildwheel==2.18.1
- id: set-matrix
run: |
echo "CI_ONLY" $CI_ONLY
if [ "$CI_ONLY" == "true" ]; then
MATRIX="[{'only':'cp312-manylinux_x86_64','os':'ubuntu-20.04'},{'only':'cp312-win_amd64','os':'windows-2019'}, {'only':'cp312-macosx_x86_64','os':'macos-12'}, {'only':'cp312-macosx_arm64','os':'macos-14'}]"
else
MATRIX=$(
{
cibuildwheel --print-build-identifiers --platform linux \
| jq -nRc '{"only": inputs, "os": "ubuntu-20.04"}' \
&& cibuildwheel --print-build-identifiers --platform macos --archs x86_64 \
| jq -nRc '{"only": inputs, "os": "macos-12"}' \
&& cibuildwheel --print-build-identifiers --platform macos --archs arm64 \
| jq -nRc '{"only": inputs, "os": "macos-14"}' \
&& cibuildwheel --print-build-identifiers --platform windows \
| jq -nRc '{"only": inputs, "os": "windows-2019"}'
} | jq -sc
)
fi
echo "include=$MATRIX" >> $GITHUB_OUTPUT
echo "platform matrix:" $MATRIX
env:
# only generate all wheels on releases, pull requests or commits to the main branch
# otherwise just generate a test wheel Python 3.12 for 4 platform
CI_ONLY: ${{ github.event_name != 'release' && github.event_name != 'pull_request' && github.ref_name != 'main' && github.event_name != 'workflow_dispatch' }}
build_wheels:
name: Build wheels on ${{ matrix.only }}
# depend on zenodo, to make sure updated CITATION.cff gets into builds
# this only results in changes upon production releases
needs: [publish_zenodo, skip_publish_zenodo, generate-wheels-matrix]
# trying solution here: https://github.com/actions/runner/issues/491#issuecomment-1507495166
# so that it works if either job in "needs" completes
if: always() && !cancelled() && !failure()
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.generate-wheels-matrix.outputs.include) }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
# FIXME: if on a release, use the tag name, not original SHA because it might be changed (somewhat hacky)
ref: ${{ (github.event_name == 'release' && github.event.action == 'published') && github.ref_name || '' }}
- name: Set up QEMU
if: runner.os == 'Linux'
uses: docker/setup-qemu-action@v3
with:
platforms: all
- name: Build and test wheels
uses: pypa/cibuildwheel@v2.18.1
env:
# FIXME: only run the slow tests when doing regular pushes, or manual - not for PRs
CIBW_TEST_COMMAND: "pytest -v {package}/tests ${{ (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && '--runslow' || '' }}"
with:
only: ${{ matrix.only }}
package-dir: .
output-dir: wheelhouse
config-file: "{package}/pyproject.toml"
- uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.only }}
path: ./wheelhouse/*.whl
# path: ./wheelhouse/* use if more than wheels are wanted
build_sdist:
name: Build source distribution
# depend on zenodo, to make sure updated CITATION.cff gets into builds
needs: [publish_zenodo, skip_publish_zenodo]
if: always() && !cancelled() && !failure()
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: # FIXME: if on a release, use the tag name, not original SHA because it might be changed (somewhat hacky)
ref: ${{ (github.event_name == 'release' && github.event.action == 'published') && github.ref_name || '' }}
- name: Build sdist
run: pipx run build --sdist
- uses: actions/upload-artifact@v4
with:
name: sdist
path: dist/*.tar.gz
upload_gh_release:
name: Upload binary wheels and sdist to GH release page
needs: [build_wheels, build_sdist]
runs-on: ubuntu-latest
# alternatively, to publish when a GitHub Release is created, use the following rule:
if: github.event_name == 'release' && github.event.action == 'published' && always() && !cancelled() && !failure()
steps:
- uses: actions/download-artifact@v4
with:
# unpacks default artifact into dist/
path: dist
merge-multiple: true
- uses: softprops/action-gh-release@v2
name: Uploading binaries to release page
with:
files: dist/*
upload_test_pypi:
name: Upload to Test_PyPI
needs: [build_wheels, build_sdist]
runs-on: ubuntu-latest
environment: test_pypi
permissions:
id-token: write
# drop requirement of 'main', release to test_pypi to test releases
if: github.event_name == 'release' && github.event.action == 'published' && always() && !cancelled() && !failure()
steps:
- uses: actions/download-artifact@v4
with:
# unpacks default artifact into dist/
path: dist
merge-multiple: true
- uses: pypa/gh-action-pypi-publish@release/v1
with:
repository_url: https://test.pypi.org/legacy/
upload_pypi:
name: Upload to PyPI
needs: [build_wheels, build_sdist]
runs-on: ubuntu-latest
environment: pypi
permissions:
id-token: write
if: github.event.release.target_commitish == 'main' && github.event_name == 'release' && github.event.action == 'published' && always() && !cancelled() && !failure()
steps:
- uses: actions/download-artifact@v4
with:
# unpacks default artifact into dist/
path: dist
merge-multiple: true
- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1