Skip to content

Update to rc12 to validate release candidate with new publishing pipe… #125

Update to rc12 to validate release candidate with new publishing pipe…

Update to rc12 to validate release candidate with new publishing pipe… #125

name: Build, test and create release packages.
on:
workflow_dispatch:
pull_request:
push:
tags:
- "[0-9]+.[0-9]+.[0-9]+"
- "[0-9]+.[0-9]+.[0-9]+rc[0-9]+"
- "[0-9]+.[0-9]+.[0-9]+.dev[0-9]+"
jobs:
test_linux:
name: Test (${{ matrix.os }}, ${{ matrix.python-version }})
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- ubuntu-latest
python-version:
- 3.9
- "3.10"
- 3.11
- 3.12
- 3.13
- 3.14
- 3.15-dev
- pypy-3.9
- pypy-3.10
- pypy-3.11
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Update pip
run: python -m pip install -U pip wheel setuptools
- name: Install tox
run: python -m pip install tox tox-gh-actions
- name: Install mypy
run: |
python -m pip install "mypy==1.19.1; python_version == '3.9'"
python -m pip install "mypy==1.20.1; python_version >= '3.10'"
- name: Test with tox
run: python -m tox
test_linux_riscv64:
name: Test (${{ matrix.os }} riscv64-${{ matrix.python-version.tox_e }})
runs-on: ${{ matrix.os }}
if: false
strategy:
matrix:
os:
- ubuntu-latest
python-version:
- {
"python_image": 3.9.23,
"tox_e": "py39, py39-without-extensions, py39-install-extensions, py39-disable-extensions",
}
- {
"python_image": 3.10.18,
"tox_e": "py310, py310-without-extensions, py310-install-extensions, py310-disable-extensions",
}
- {
"python_image": 3.11.13,
"tox_e": "py311, py311-without-extensions, py311-install-extensions, py311-disable-extensions",
}
- {
"python_image": 3.12.11,
"tox_e": "py312, py312-without-extensions, py312-install-extensions, py312-disable-extensions",
}
- {
"python_image": 3.13.7,
"tox_e": "py313, py313-without-extensions, py313-install-extensions, py313-disable-extensions",
}
- {
"python_image": 3.14.0rc2,
"tox_e": "py314, py314-without-extensions, py314-install-extensions, py314-disable-extensions",
}
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup docker/setup-qemu-action
uses: docker/setup-qemu-action@v4
- name: start python_rv64
run: docker run --platform linux/riscv64 -d --name python_rv64 -v ./:/src python:${{ matrix.python-version.python_image }} bash -c "while true; do sleep 30; done"
- name: show uname
run: docker exec python_rv64 uname -a
- name: setup venv
run: docker exec python_rv64 python -m venv /src/venv
- name: Update pip
run: docker exec python_rv64 bash -c "source /src/venv/bin/activate && python -m pip install -U pip wheel setuptools"
- name: Install tox
run: docker exec python_rv64 bash -c "source /src/venv/bin/activate && python -m pip install 'tox<4.0.0' 'tox-gh-actions<3.0.0'"
- name: Install mypy
run: |
docker exec python_rv64 bash -c "source /src/venv/bin/activate && python -m pip install 'mypy==1.19.1; python_version == \"3.9\"'"
docker exec python_rv64 bash -c "source /src/venv/bin/activate && python -m pip install 'mypy==1.20.1; python_version >= \"3.10\"'"
- name: Test with tox
run: docker exec python_rv64 bash -c "source /src/venv/bin/activate && cd /src && python -m tox -e '${{ matrix.python-version.tox_e }}'"
test_linux_no_gil:
name: Test - NO GIL (${{ matrix.os }}, ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
matrix:
os:
- ubuntu-latest
python-version:
- 3.13
- 3.14
- 3.15-dev
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Python ${{ matrix.python-version }}
uses: deadsnakes/action@v3.2.0
with:
python-version: ${{ matrix.python-version }}
nogil: true
- name: Update pip
run: python -m pip install -U pip wheel setuptools
- name: Install tox
run: python -m pip install tox tox-gh-actions
- name: Install mypy
run: |
python -m pip install "mypy==1.19.1; python_version == '3.9'"
python -m pip install "mypy==1.20.1; python_version >= '3.10'"
- name: Test with tox
run: python -m tox
test_macos:
name: Test (${{ matrix.os }}, ${{ matrix.python-version }})
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- macos-latest
python-version:
- 3.9
- "3.10"
- 3.11
- 3.12
- 3.13
- 3.14
- 3.15-dev
- pypy-3.9
- pypy-3.10
- pypy-3.11
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Update pip
run: python -m pip install -U pip wheel setuptools
- name: Install tox
run: python -m pip install tox tox-gh-actions
- name: Install mypy
run: |
python -m pip install "mypy==1.19.1; python_version == '3.9'"
python -m pip install "mypy==1.20.1; python_version >= '3.10'"
- name: Test with tox
run: python -m tox
test_windows:
name: Test (${{ matrix.os }}, ${{ matrix.python-version }})
runs-on: ${{ matrix.os }}
strategy:
matrix:
os:
- windows-latest
- windows-11-arm
python-version:
- 3.9
- "3.10"
- 3.11
- 3.12
- 3.13
- 3.14
- 3.15-dev
- pypy-3.9
- pypy-3.10
- pypy-3.11
exclude:
# setup-python only support 3.11+ for windows arm
- os: windows-11-arm
python-version: 3.9
- os: windows-11-arm
python-version: "3.10"
- os: windows-11-arm
python-version: pypy-3.9
- os: windows-11-arm
python-version: pypy-3.10
- os: windows-11-arm
python-version: pypy-3.11
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Update pip
run: python -m pip install -U pip wheel setuptools
- name: Install tox
run: python -m pip install tox tox-gh-actions
- name: Install mypy
run: |
python -m pip install "mypy==1.19.1; python_version == '3.9'"
python -m pip install "mypy==1.20.1; python_version >= '3.10'"
- name: Test with tox
run: python -m tox
sdist:
name: Build source distribution
needs:
- test_linux
- test_macos
- test_windows
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
submodules: true
- name: Set up Python 3.9
uses: actions/setup-python@v6
with:
python-version: 3.9
- name: Build full source distribution as tar.gz
run: python setup.py sdist
- name: Install the wheel package
run: pip install wheel
- name: Build pure Python source wheel
run: WRAPT_INSTALL_EXTENSIONS=false python setup.py bdist_wheel
- name: Store built wheels
uses: actions/upload-artifact@v7
with:
name: sdist
path: dist/*
bdist_wheel:
name: Build wheels (3.9+) on ${{ matrix.os }} for ${{ matrix.arch }}
needs:
- test_linux
- test_linux_no_gil
# - test_linux_riscv64
- test_macos
- test_windows
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, ubuntu-24.04-arm, windows-latest, windows-11-arm, macos-15-intel, macos-latest]
arch: [auto]
include:
- os: ubuntu-latest
arch: riscv64
steps:
- uses: actions/checkout@v6
- name: Set up QEMU
if: ${{ matrix.arch == 'riscv64' }}
uses: docker/setup-qemu-action@v4
- name: Build wheels
uses: pypa/cibuildwheel@v3.3.0
with:
output-dir: dist
env:
WRAPT_INSTALL_EXTENSIONS: true
CIBW_BUILD_VERBOSITY: 1
CIBW_ARCHS: ${{ matrix.arch }}
CIBW_ENABLE: cpython-freethreading
CIBW_PROJECT_REQUIRES_PYTHON: ">=3.9"
- uses: actions/upload-artifact@v7
with:
name: dist-${{ matrix.os }}-${{ matrix.arch }}
path: dist/*.whl
release:
name: Publish GitHub release
runs-on: ubuntu-latest
needs:
- sdist
- bdist_wheel
if: startsWith(github.ref, 'refs/tags/')
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Resolve version and prerelease status
id: meta
run: |
TAG="${GITHUB_REF_NAME}"
VERSION="${TAG}"
BASE_VERSION="$(echo "$VERSION" | sed -E 's/\.?(dev|rc)[0-9]+$//')"
ANCHOR="version-$(echo "$BASE_VERSION" | tr '.' '-')"
if [[ "$VERSION" == *dev* || "$VERSION" == *rc* ]]; then
PRERELEASE="true"
else
PRERELEASE="false"
fi
echo "tag=$TAG" >> "$GITHUB_OUTPUT"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "base_version=$BASE_VERSION" >> "$GITHUB_OUTPUT"
echo "anchor=$ANCHOR" >> "$GITHUB_OUTPUT"
echo "prerelease=$PRERELEASE" >> "$GITHUB_OUTPUT"
- name: Verify version matches tag
run: |
EXPECTED="${{ steps.meta.outputs.version }}"
ACTUAL="$(python <<'PY'
import ast
src = open('src/wrapt/__init__.py').read()
tree = ast.parse(src)
ns = {}
for node in tree.body:
if isinstance(node, ast.FunctionDef) and node.name == "_format_version":
exec(compile(ast.Module(body=[node], type_ignores=[]), '<v>', 'exec'), ns)
elif isinstance(node, ast.Assign):
names = [t.id for t in node.targets if isinstance(t, ast.Name)]
if any(n.startswith('__version') for n in names):
exec(compile(ast.Module(body=[node], type_ignores=[]), '<v>', 'exec'), ns)
print(ns['__version__'])
PY
)"
if [ "$ACTUAL" != "$EXPECTED" ]; then
echo "Tag version ($EXPECTED) does not match __version__ ($ACTUAL) in src/wrapt/__init__.py" >&2
exit 1
fi
echo "Version match: $ACTUAL"
- name: Download all built artifacts
uses: actions/download-artifact@v8
with:
path: dist
merge-multiple: true
- name: List collected artifacts
run: ls -las dist
- name: Generate SHA256SUMS
run: |
cd dist
sha256sum * > SHA256SUMS
cat SHA256SUMS
- name: Write release notes body
run: |
VERSION="${{ steps.meta.outputs.version }}"
BASE_VERSION="${{ steps.meta.outputs.base_version }}"
ANCHOR="${{ steps.meta.outputs.anchor }}"
DOCS_URL="https://wrapt.readthedocs.io/en/latest/changes.html#${ANCHOR}"
if [[ "$VERSION" == *dev* ]]; then
cat > body.md <<EOF
Development snapshot. Not normally published to PyPi
(occasionally uploaded to exercise the release pipeline).
Release notes for the upcoming ${BASE_VERSION} final (work in
progress): ${DOCS_URL}
Platform wheels and the source distribution are attached. To
test against your Python install, either grab a matching wheel
or build from the source distribution:
pip install wrapt-${VERSION}-<python>-<abi>-<platform>.whl
or
tar xf wrapt-${VERSION}.tar.gz
cd wrapt-${VERSION}
pip install .
\`SHA256SUMS\` is attached for verification of the archives.
EOF
elif [[ "$VERSION" == *rc* ]]; then
cat > body.md <<EOF
Release candidate. Release notes for the upcoming
${BASE_VERSION} final (work in progress): ${DOCS_URL}
May be installable from PyPi:
pip install wrapt==${VERSION}
If \`pip\` reports the version is unavailable, this candidate
either has not been uploaded yet or is not being published to
PyPi. Use the attached wheels or build from the source
distribution instead:
tar xf wrapt-${VERSION}.tar.gz
cd wrapt-${VERSION}
pip install .
\`SHA256SUMS\` is attached for verification of the archives.
EOF
else
cat > body.md <<EOF
Full release notes: ${DOCS_URL}
Install from PyPi (recommended):
pip install wrapt==${VERSION}
PyPi uploads follow each GitHub release; if \`pip\` reports the
version is unavailable, the matching PyPi upload may not have
happened yet.
Pre-built wheels are provided for a range of Python versions
and platforms (Linux x86_64/aarch64/riscv64, macOS x86_64 and
arm64, Windows x86_64 and arm64, plus PyPy and free-threaded
builds). The source distribution is also attached together
with \`SHA256SUMS\` for verification.
EOF
fi
cat body.md
- name: Create GitHub release
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_REPO: ${{ github.repository }}
run: |
FLAGS=()
if [[ "${{ steps.meta.outputs.prerelease }}" == "true" ]]; then
FLAGS+=("--prerelease")
fi
gh release create "${{ steps.meta.outputs.tag }}" \
--title "wrapt ${{ steps.meta.outputs.version }}" \
--notes-file body.md \
"${FLAGS[@]}" \
dist/*
publish-wrapt:
name: Publish wrapt to PyPi
runs-on: ubuntu-latest
needs:
- release
if: startsWith(github.ref, 'refs/tags/')
environment: pypi-wrapt
permissions:
id-token: write
steps:
- name: Download all built artifacts
uses: actions/download-artifact@v8
with:
path: dist
merge-multiple: true
- name: Stage wrapt sdist and wheels
run: |
mkdir -p stage
cp dist/wrapt-[0-9]*.tar.gz stage/
cp dist/wrapt-[0-9]*.whl stage/
ls -las stage
- name: Publish wrapt to PyPi
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: stage/