Skip to content

Release engineering

Release engineering #4

Workflow file for this run

# Publish to crates.io and pypi.org, also cross-compile binaries which are uploaded to GitHub releases.
#
# Notes
# - not using https://github.com/taiki-e/upload-rust-binary-action because it builds after release, we prefer build before release
# - not using https://opensource.axo.dev/cargo-dist/ because
# - https://github.com/axodotdev/cargo-dist/issues/551
# - no ppc64le support, https://github.com/axodotdev/cargo-dist/issues/74
# - no deb support, no pypi support
name: Release
on:
push:
tags:
- v[0-9]+.*
jobs:
#################################################
# #
# CRATES.IO BUILD #
# #
#################################################
crate:
runs-on: ubuntu-latest
name: Publish to crates.io
steps:
- name: Git checkout
uses: actions/checkout@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Publish to crates.io
run: cargo publish
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
#################################################
# #
# CROSS COMPILE BINARIES #
# #
#################################################
build:
strategy:
fail-fast: false
matrix:
include:
- { os: ubuntu-latest , target: armv7-unknown-linux-gnueabihf , deb: false , use-cross: use-cross }
- { os: ubuntu-latest , target: aarch64-unknown-linux-gnu , deb: true , use-cross: use-cross }
- { os: ubuntu-latest , target: aarch64-unknown-linux-musl , deb: false , use-cross: use-cross }
- { os: ubuntu-latest , target: powerpc-unknown-linux-gnu , deb: true , use-cross: use-cross }
- { os: ubuntu-latest , target: powerpc64-unknown-linux-gnu , deb: true , use-cross: use-cross }
- { os: ubuntu-latest , target: powerpc64le-unknown-linux-gnu , deb: true , use-cross: use-cross }
- { os: ubuntu-latest , target: riscv64gc-unknown-linux-gnu , deb: false , use-cross: use-cross }
- { os: ubuntu-latest , target: x86_64-unknown-linux-gnu , deb: true , use-cross: use-cross }
- { os: ubuntu-latest , target: x86_64-unknown-linux-musl , deb: false , use-cross: use-cross, convenient: true }
- { os: macos-latest , target: x86_64-apple-darwin }
- { os: macos-latest , target: aarch64-apple-darwin }
- { os: macos-latest , target: universal-apple-darwin }
- { os: windows-latest , target: x86_64-pc-windows-gnu }
- { os: windows-latest , target: x86_64-pc-windows-msvc }
runs-on: ${{ matrix.os }}
steps:
# Build
# ------------------------------------------------------------
- name: Git checkout
uses: actions/checkout@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Install cross-compilation tools
if: matrix.use-cross
uses: taiki-e/setup-cross-toolchain-action@v1
with:
target: ${{ matrix.target }}
- name: Setup rust cache
uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.target }}
- name: Build
run: cargo build --release
# Bundle
# ------------------------------------------------------------
- name: Extract crate information
id: crate-metadata
run: |
name="$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[0].name')"
version="$(cargo metadata --no-deps --format-version 1 | jq -r '.packages[0].version')"
echo "name=$name" >> "$GITHUB_OUTPUT"
echo "version=$version" >> "$GITHUB_OUTPUT"
echo "bin_name=$name-${{ matrix.target }}-$version" >> "$GITHUB_OUTPUT"
- name: Bundle release (Windows)
if: matrix.os == 'windows-latest'
shell: bash
run: |
mkdir '${{ steps.crate-metadata.outputs.bin_name }}'
cp -v 'target/${{ matrix.target }}/release/${{ steps.crate-metadata.outputs.name }}.exe' '${{ steps.crate-metadata.outputs.bin_name }}'
7z a '${{ steps.crate-metadata.outputs.bin_name }}.zip' '${{ steps.crate-metadata.outputs.bin_name }}'
echo "ASSET='${{ steps.crate-metadata.outputs.bin_name }}'.zip" >> $GITHUB_ENV
- name: Bundle release (Linux and macOS)
if: matrix.os != 'windows-latest'
shell: bash
run: |
mkdir -v '${{ steps.crate-metadata.outputs.bin_name }}'
cp -v 'target/${{ matrix.target }}/release/${{ steps.crate-metadata.outputs.name }}' '${{ steps.crate-metadata.outputs.bin_name }}'
tarball='${{ steps.crate-metadata.outputs.bin_name }}.tgz'
tar -czvf "$tarball" '${{ steps.crate-metadata.outputs.bin_name }}'
echo "ASSET=$tarball" >> $GITHUB_ENV
- name: Create release directory for artifact, move file
shell: bash
run: |
mkdir -v release
mv -v '${{ env.ASSET }}' release/
- name: Copy "convenience" binary to release directory
if: matrix.convenient
shell: bash
run: cp -v 'target/${{ matrix.triple.target }}/release/${{ steps.crate-metadata.outputs.name }}' release/
- name: Build Debian release
id: deb
if: matrix.deb
run: |
cargo install cargo-deb --version 2.0.0 --locked
cargo deb --no-build --target ${{ matrix.target }}
cp -v ./target/${{ matrix.target }}/debian/*.deb release/
- name: Test installation of .deb
if: steps.deb.conclusion != 'skipped'
run: sudo dpkg -i release/*.deb
- name: Save release as artifact
uses: actions/upload-artifact@v3
with:
retention-days: 3
name: release
path: release
upload-release:
name: upload-release
runs-on: ubuntu-latest
needs: [ build ]
steps:
# Create Release
# ------------------------------------------------------------
- name: Get release artifacts
uses: actions/download-artifact@v3
with:
name: release
path: release
- name: Print out all release files
run: |
echo "Generated $(ls ./release | wc -l) files:"
ls ./release
- name: Upload all saved release files
uses: softprops/action-gh-release@c9b46fe7aad9f02afd89b12450b780f52dacfb2d
with:
draft: true
fail_on_unmatched_files: true
files: |
./release/*
#################################################
# #
# BUILD FOR PYPI USING MATURIN #
# #
#################################################
maturin-linux:
runs-on: ubuntu-latest
strategy:
matrix:
target: [x86_64, aarch64, armv7]
steps:
- uses: actions/checkout@v4
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.target }}
args: --release --strip --locked --out dist
sccache: 'true'
manylinux: auto
- name: Upload wheels
uses: actions/upload-artifact@v3
with:
name: wheels
path: dist
maturin-windows:
runs-on: windows-latest
strategy:
matrix:
target: [x64]
steps:
- uses: actions/checkout@v4
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.target }}
args: --release --strip --locked --out dist
sccache: 'true'
- name: Upload wheels
uses: actions/upload-artifact@v3
with:
name: wheels
path: dist
maturin-macos:
runs-on: macos-latest
strategy:
matrix:
target: [x86_64, aarch64]
steps:
- uses: actions/checkout@v4
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.target }}
args: --release --strip --locked --out dist
sccache: 'true'
- name: Upload wheels
uses: actions/upload-artifact@v3
with:
name: wheels
path: dist
maturin-sdist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build sdist
uses: PyO3/maturin-action@v1
with:
command: sdist
args: --out dist
- name: Upload sdist
uses: actions/upload-artifact@v3
with:
name: wheels
path: dist
maturin-release:
name: Release
runs-on: ubuntu-latest
needs: [maturin-linux, maturin-windows, maturin-macos, maturin-sdist]
steps:
- uses: actions/download-artifact@v3
with:
name: wheels
- name: Publish to PyPI
uses: PyO3/maturin-action@v1
env:
MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
with:
command: upload
args: --skip-existing *