mirror of
https://github.com/astral-sh/ruff
synced 2026-01-22 22:10:48 -05:00
## Summary Currently, it is possible to create a tag and then have the release fail, which is a problem since we can't edit the tag (https://github.com/charliermarsh/ruff/issues/4468). This change the release process so that the tag is created inside the release workflow. This leaves as a failure mode that we have published to pypi but then creating the tag or GitHub release doesn't work, but in this case we can restart and the pypi upload is just skipped because we use the skip existing option. The release workflow is started by a workflow dispatch with the tag instead of creating the tag yourself. You can start the release workflow without a tag to do a dry run which does not publish an artifacts. You can optionally add a git sha to the workflow run and it will verify that the release runs on the mentioned commit. This also adds docs on how to release and a small style improvement for the maturin integration. ## Test Plan Testing is hard since we can't do real releases, i've tested a minimized workflow in a separate dummy repository.
486 lines
15 KiB
YAML
486 lines
15 KiB
YAML
name: "[ruff] Release"
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
tag:
|
|
description: "The version to tag, without the leading 'v'. If omitted, will initiate a dry run skipping uploading artifact."
|
|
type: string
|
|
sha:
|
|
description: "Optionally, the full sha of the commit to be released"
|
|
type: string
|
|
push:
|
|
paths:
|
|
# When we change pyproject.toml, we want to ensure that the maturin builds still work
|
|
- pyproject.toml
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
env:
|
|
PACKAGE_NAME: ruff
|
|
PYTHON_VERSION: "3.7" # to build abi3 wheels
|
|
CARGO_INCREMENTAL: 0
|
|
CARGO_NET_RETRY: 10
|
|
CARGO_TERM_COLOR: always
|
|
RUSTUP_MAX_RETRIES: 10
|
|
|
|
jobs:
|
|
sdist:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
- uses: actions/setup-python@v4
|
|
with:
|
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
- name: "Prep README.md"
|
|
run: python scripts/transform_readme.py --target pypi
|
|
- name: "Build sdist"
|
|
uses: PyO3/maturin-action@v1
|
|
with:
|
|
command: sdist
|
|
args: --out dist
|
|
- name: "Test sdist"
|
|
run: |
|
|
rustup default $(cat rust-toolchain)
|
|
pip install dist/${{ env.PACKAGE_NAME }}-*.tar.gz --force-reinstall
|
|
ruff --help
|
|
python -m ruff --help
|
|
- name: "Upload sdist"
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: wheels
|
|
path: dist
|
|
|
|
macos-x86_64:
|
|
runs-on: macos-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
- uses: actions/setup-python@v4
|
|
with:
|
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
architecture: x64
|
|
- name: "Prep README.md"
|
|
run: python scripts/transform_readme.py --target pypi
|
|
- name: "Build wheels - x86_64"
|
|
uses: PyO3/maturin-action@v1
|
|
with:
|
|
target: x86_64
|
|
args: --release --out dist
|
|
- name: "Test wheel - x86_64"
|
|
run: |
|
|
pip install dist/${{ env.PACKAGE_NAME }}-*.whl --force-reinstall
|
|
ruff --help
|
|
python -m ruff --help
|
|
- name: "Upload wheels"
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: wheels
|
|
path: dist
|
|
- name: "Archive binary"
|
|
run: |
|
|
ARCHIVE_FILE=ruff-x86_64-apple-darwin.tar.gz
|
|
tar czvf $ARCHIVE_FILE -C target/x86_64-apple-darwin/release ruff
|
|
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
|
|
- name: "Upload binary"
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: binaries
|
|
path: |
|
|
*.tar.gz
|
|
*.sha256
|
|
|
|
macos-universal:
|
|
runs-on: macos-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
- uses: actions/setup-python@v4
|
|
with:
|
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
architecture: x64
|
|
- name: "Prep README.md"
|
|
run: python scripts/transform_readme.py --target pypi
|
|
- name: "Build wheels - universal2"
|
|
uses: PyO3/maturin-action@v1
|
|
with:
|
|
args: --release --target universal2-apple-darwin --out dist
|
|
- name: "Test wheel - universal2"
|
|
run: |
|
|
pip install dist/${{ env.PACKAGE_NAME }}-*universal2.whl --force-reinstall
|
|
ruff --help
|
|
python -m ruff --help
|
|
- name: "Upload wheels"
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: wheels
|
|
path: dist
|
|
- name: "Archive binary"
|
|
run: |
|
|
ARCHIVE_FILE=ruff-aarch64-apple-darwin.tar.gz
|
|
tar czvf $ARCHIVE_FILE -C target/aarch64-apple-darwin/release ruff
|
|
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
|
|
- name: "Upload binary"
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: binaries
|
|
path: |
|
|
*.tar.gz
|
|
*.sha256
|
|
|
|
windows:
|
|
runs-on: windows-latest
|
|
strategy:
|
|
matrix:
|
|
platform:
|
|
- target: x86_64-pc-windows-msvc
|
|
arch: x64
|
|
- target: i686-pc-windows-msvc
|
|
arch: x86
|
|
- target: aarch64-pc-windows-msvc
|
|
arch: x64
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
- uses: actions/setup-python@v4
|
|
with:
|
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
architecture: ${{ matrix.platform.arch }}
|
|
- name: "Prep README.md"
|
|
run: python scripts/transform_readme.py --target pypi
|
|
- name: "Build wheels"
|
|
uses: PyO3/maturin-action@v1
|
|
with:
|
|
target: ${{ matrix.platform.target }}
|
|
args: --release --out dist
|
|
- name: "Test wheel"
|
|
if: ${{ !startsWith(matrix.platform.target, 'aarch64') }}
|
|
shell: bash
|
|
run: |
|
|
python -m pip install dist/${{ env.PACKAGE_NAME }}-*.whl --force-reinstall
|
|
ruff --help
|
|
python -m ruff --help
|
|
- name: "Upload wheels"
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: wheels
|
|
path: dist
|
|
- name: "Archive binary"
|
|
shell: bash
|
|
run: |
|
|
ARCHIVE_FILE=ruff-${{ matrix.platform.target }}.zip
|
|
7z a $ARCHIVE_FILE ./target/${{ matrix.platform.target }}/release/ruff.exe
|
|
sha256sum $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
|
|
- name: "Upload binary"
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: binaries
|
|
path: |
|
|
*.zip
|
|
*.sha256
|
|
|
|
linux:
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
matrix:
|
|
target:
|
|
- x86_64-unknown-linux-gnu
|
|
- i686-unknown-linux-gnu
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
- uses: actions/setup-python@v4
|
|
with:
|
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
architecture: x64
|
|
- name: "Prep README.md"
|
|
run: python scripts/transform_readme.py --target pypi
|
|
- name: "Build wheels"
|
|
uses: PyO3/maturin-action@v1
|
|
with:
|
|
target: ${{ matrix.target }}
|
|
manylinux: auto
|
|
args: --release --out dist
|
|
- name: "Test wheel"
|
|
if: ${{ startsWith(matrix.target, 'x86_64') }}
|
|
run: |
|
|
pip install dist/${{ env.PACKAGE_NAME }}-*.whl --force-reinstall
|
|
ruff --help
|
|
python -m ruff --help
|
|
- name: "Upload wheels"
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: wheels
|
|
path: dist
|
|
- name: "Archive binary"
|
|
run: |
|
|
ARCHIVE_FILE=ruff-${{ matrix.target }}.tar.gz
|
|
tar czvf $ARCHIVE_FILE -C target/${{ matrix.target }}/release ruff
|
|
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
|
|
- name: "Upload binary"
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: binaries
|
|
path: |
|
|
*.tar.gz
|
|
*.sha256
|
|
|
|
linux-cross:
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
matrix:
|
|
platform:
|
|
- target: aarch64-unknown-linux-gnu
|
|
arch: aarch64
|
|
# see https://github.com/astral-sh/ruff/issues/3791
|
|
# and https://github.com/gnzlbg/jemallocator/issues/170#issuecomment-1503228963
|
|
maturin_docker_options: -e JEMALLOC_SYS_WITH_LG_PAGE=16
|
|
- target: armv7-unknown-linux-gnueabihf
|
|
arch: armv7
|
|
- target: s390x-unknown-linux-gnu
|
|
arch: s390x
|
|
- target: powerpc64le-unknown-linux-gnu
|
|
arch: ppc64le
|
|
- target: powerpc64-unknown-linux-gnu
|
|
arch: ppc64
|
|
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
- uses: actions/setup-python@v4
|
|
with:
|
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
- name: "Prep README.md"
|
|
run: python scripts/transform_readme.py --target pypi
|
|
- name: "Build wheels"
|
|
uses: PyO3/maturin-action@v1
|
|
with:
|
|
target: ${{ matrix.platform.target }}
|
|
manylinux: auto
|
|
docker-options: ${{ matrix.platform.maturin_docker_options }}
|
|
args: --release --out dist
|
|
- uses: uraimo/run-on-arch-action@v2
|
|
if: matrix.platform.arch != 'ppc64'
|
|
name: Test wheel
|
|
with:
|
|
arch: ${{ matrix.platform.arch }}
|
|
distro: ubuntu20.04
|
|
githubToken: ${{ github.token }}
|
|
install: |
|
|
apt-get update
|
|
apt-get install -y --no-install-recommends python3 python3-pip
|
|
pip3 install -U pip
|
|
run: |
|
|
pip3 install ${{ env.PACKAGE_NAME }} --no-index --find-links dist/ --force-reinstall
|
|
ruff --help
|
|
- name: "Upload wheels"
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: wheels
|
|
path: dist
|
|
- name: "Archive binary"
|
|
run: |
|
|
ARCHIVE_FILE=ruff-${{ matrix.platform.target }}.tar.gz
|
|
tar czvf $ARCHIVE_FILE -C target/${{ matrix.platform.target }}/release ruff
|
|
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
|
|
- name: "Upload binary"
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: binaries
|
|
path: |
|
|
*.tar.gz
|
|
*.sha256
|
|
|
|
musllinux:
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
matrix:
|
|
target:
|
|
- x86_64-unknown-linux-musl
|
|
- i686-unknown-linux-musl
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
- uses: actions/setup-python@v4
|
|
with:
|
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
architecture: x64
|
|
- name: "Prep README.md"
|
|
run: python scripts/transform_readme.py --target pypi
|
|
- name: "Build wheels"
|
|
uses: PyO3/maturin-action@v1
|
|
with:
|
|
target: ${{ matrix.target }}
|
|
manylinux: musllinux_1_2
|
|
args: --release --out dist
|
|
- name: "Test wheel"
|
|
if: matrix.target == 'x86_64-unknown-linux-musl'
|
|
uses: addnab/docker-run-action@v3
|
|
with:
|
|
image: alpine:latest
|
|
options: -v ${{ github.workspace }}:/io -w /io
|
|
run: |
|
|
apk add py3-pip
|
|
pip3 install ${{ env.PACKAGE_NAME }} --no-index --find-links /io/dist/ --force-reinstall
|
|
ruff --help
|
|
python -m ruff --help
|
|
- name: "Upload wheels"
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: wheels
|
|
path: dist
|
|
- name: "Archive binary"
|
|
run: |
|
|
ARCHIVE_FILE=ruff-${{ matrix.target }}.tar.gz
|
|
tar czvf $ARCHIVE_FILE -C target/${{ matrix.target }}/release ruff
|
|
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
|
|
- name: "Upload binary"
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: binaries
|
|
path: |
|
|
*.tar.gz
|
|
*.sha256
|
|
|
|
musllinux-cross:
|
|
runs-on: ubuntu-latest
|
|
strategy:
|
|
matrix:
|
|
platform:
|
|
- target: aarch64-unknown-linux-musl
|
|
arch: aarch64
|
|
maturin_docker_options: -e JEMALLOC_SYS_WITH_LG_PAGE=16
|
|
- target: armv7-unknown-linux-musleabihf
|
|
arch: armv7
|
|
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
- uses: actions/setup-python@v4
|
|
with:
|
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
- name: "Prep README.md"
|
|
run: python scripts/transform_readme.py --target pypi
|
|
- name: "Build wheels"
|
|
uses: PyO3/maturin-action@v1
|
|
with:
|
|
target: ${{ matrix.platform.target }}
|
|
manylinux: musllinux_1_2
|
|
args: --release --out dist
|
|
docker-options: ${{ matrix.platform.maturin_docker_options }}
|
|
- uses: uraimo/run-on-arch-action@v2
|
|
name: Test wheel
|
|
with:
|
|
arch: ${{ matrix.platform.arch }}
|
|
distro: alpine_latest
|
|
githubToken: ${{ github.token }}
|
|
install: |
|
|
apk add py3-pip
|
|
run: |
|
|
pip3 install ${{ env.PACKAGE_NAME }} --no-index --find-links dist/ --force-reinstall
|
|
ruff check --help
|
|
- name: "Upload wheels"
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: wheels
|
|
path: dist
|
|
- name: "Archive binary"
|
|
run: |
|
|
ARCHIVE_FILE=ruff-${{ matrix.platform.target }}.tar.gz
|
|
tar czvf $ARCHIVE_FILE -C target/${{ matrix.platform.target }}/release ruff
|
|
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
|
|
- name: "Upload binary"
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: binaries
|
|
path: |
|
|
*.tar.gz
|
|
*.sha256
|
|
|
|
release:
|
|
name: Release
|
|
runs-on: ubuntu-latest
|
|
needs:
|
|
- macos-universal
|
|
- macos-x86_64
|
|
- windows
|
|
- linux
|
|
- linux-cross
|
|
- musllinux
|
|
- musllinux-cross
|
|
# If you don't set an input it's a dry run skipping uploading artifact
|
|
if: ${{ inputs.tag }}
|
|
environment:
|
|
name: release
|
|
permissions:
|
|
# For pypi trusted publishing
|
|
id-token: write
|
|
# For GitHub release publishing
|
|
contents: write
|
|
steps:
|
|
- name: Consistency check tag
|
|
run: |
|
|
version=$(grep "version = " pyproject.toml | sed -e 's/version = "\(.*\)"/\1/g')
|
|
if [ "${{ inputs.tag }}" != "${version}" ]; then
|
|
echo "The input tag does not match the version from pyproject.toml:" >&2
|
|
echo "${{ inputs.tag }}" >&2
|
|
echo "${version}" >&2
|
|
exit 1
|
|
else
|
|
echo "Releasing ${version}"
|
|
fi
|
|
- name: Consistency check sha
|
|
if: ${{ inputs.sha }}
|
|
run: |
|
|
git_sha=$(git rev-parse HEAD)
|
|
if [ "${{ inputs.sha }}" != "${git_sha}" ]; then
|
|
echo "The specified sha does not match the git checkout" >&2
|
|
echo "${{ inputs.sha }}" >&2
|
|
echo "${git_sha}" >&2
|
|
exit 1
|
|
else
|
|
echo "Releasing ${git_sha}"
|
|
fi
|
|
- uses: actions/download-artifact@v3
|
|
with:
|
|
name: wheels
|
|
path: wheels
|
|
- name: Publish to PyPi
|
|
uses: pypa/gh-action-pypi-publish@release/v1
|
|
with:
|
|
skip-existing: true
|
|
packages-dir: wheels
|
|
verbose: true
|
|
- uses: actions/download-artifact@v3
|
|
with:
|
|
name: binaries
|
|
path: binaries
|
|
- name: git tag
|
|
run: |
|
|
git config user.email "hey@astral.sh"
|
|
git config user.name "Ruff Release CI"
|
|
git tag -m "v${{ inputs.tag }}" "v${{ inputs.tag }}"
|
|
# If there is duplicate tag, this will fail. The publish to pypi action will have been a noop (due to skip
|
|
# existing), so we make a non-destructive exit here
|
|
git push --tags
|
|
- name: "Publish to GitHub"
|
|
uses: softprops/action-gh-release@v1
|
|
with:
|
|
draft: true
|
|
files: binaries/*
|
|
tag_name: v${{ inputs.tag }}
|
|
|
|
# After the release has been published, we update downstream repositories
|
|
# This is separate because if this fails the release is still fine, we just need to do some manual workflow triggers
|
|
update-dependents:
|
|
name: Release
|
|
runs-on: ubuntu-latest
|
|
needs: release
|
|
steps:
|
|
- name: "Update pre-commit mirror"
|
|
uses: actions/github-script@v6
|
|
with:
|
|
github-token: ${{ secrets.RUFF_PRE_COMMIT_PAT }}
|
|
script: |
|
|
github.rest.actions.createWorkflowDispatch({
|
|
owner: 'astral-sh',
|
|
repo: 'ruff-pre-commit',
|
|
workflow_id: 'main.yml',
|
|
ref: 'main',
|
|
})
|