Compile on Ubuntu 20.04 #12
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 --locked | |
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 , use-cross: use-cross } | |
- { os: ubuntu-latest , target: aarch64-unknown-linux-gnu , use-cross: use-cross } | |
- { os: ubuntu-latest , target: aarch64-unknown-linux-musl , use-cross: use-cross } | |
- { os: ubuntu-latest , target: powerpc-unknown-linux-gnu , use-cross: use-cross } | |
- { os: ubuntu-latest , target: powerpc64-unknown-linux-gnu , use-cross: use-cross } | |
- { os: ubuntu-latest , target: powerpc64le-unknown-linux-gnu , use-cross: use-cross } | |
- { os: ubuntu-latest , target: riscv64gc-unknown-linux-gnu , use-cross: use-cross } | |
- { os: ubuntu-20.04 , target: x86_64-unknown-linux-gnu , deb: deb } | |
- { os: ubuntu-20.04 , target: x86_64-unknown-linux-musl , convenient: convenient } | |
- { os: macos-latest , target: x86_64-apple-darwin } | |
- { os: macos-latest , target: aarch64-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 --target ${{ matrix.target }} | |
# Bundle | |
# ------------------------------------------------------------ | |
- name: Extract crate information | |
id: crate-metadata | |
shell: bash | |
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 }}-v$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.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: Generate install script | |
id: create_script | |
run: | | |
repo='${{ github.repository }}' | |
owner_part='${{ github.repository_owner }}/' | |
repo_name="${repo:${#owner_part}}" | |
bin_env_var_name="${repo_name^^}_BIN" | |
echo "repo_name=$repo_name" >> "$GITHUB_OUTPUT" | |
echo "bin_env_var_name=$bin_env_var_name" >> "$GITHUB_OUTPUT" | |
cat > release/installer.sh << EOF | |
#!/bin/bash | |
# Yet-another SH installer for Rust binaries from GitHub releases. | |
# The binary gets installed to /usr/local/bin, or a custom location specified by $bin_env_var_name | |
set -e | |
arch=\$(uname -m) | |
os=\$(uname -s) | |
arch="\${arch/ppc64/powerpc64}" | |
case "\$os" in | |
Darwin ) os=apple-darwin ;; | |
Linux ) os=unknown-linux-gnu ;; | |
esac | |
if [ "\$arch" = "x_86_64" ] || [ "\$arch" = "aarch64" ]; then | |
if ldd --version 2>&1 | grep -q 'musl libc'; then | |
os=unknown-linux-musl | |
fi | |
fi | |
VERSION_TAG='${{ github.ref_name }}' | |
REPO='$repo' | |
NAME='$repo_name' | |
file="\$NAME-\$arch-\$os-\$VERSION_TAG.tgz" | |
url="${{ github.server_url }}/\$REPO/releases/download/\$VERSION_TAG/\$file" | |
tmpdir="\$(mktemp -d)" | |
cd "\$tmpdir" | |
if which curl > /dev/null 2>&1; then | |
curl -sfLo "\$file" "\$url" | |
elif which wget > /dev/null 2>&1; then | |
wget -q -O "\$file" "\$url" | |
else | |
>&2 echo "error: curl nor wget found" | |
exit 1 | |
fi | |
tar xf "\$file" | |
dest="\${$bin_env_var_name:-/usr/local/bin/\$NAME}" | |
mv "\${file/.tgz/}/\$NAME" "\$dest" | |
cd / | |
rm -rf "\$tmpdir" | |
EOF | |
- 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/* | |
body: | | |
## Choosing An Installer for Linux | |
The bare binary | |
[`${{ steps.create_script.outputs.repo_name }}`](${{ github.server_url }}/${{ github.repository }}/releases/download/${{ github.ref_name }}/${{ steps.create_script.outputs.repo_name }}) | |
should work on all Linux distros. Download it, then run `chmod +x ./${{ steps.create_script.outputs.repo_name }}` as usual. | |
The `unknown-linux-gnu` target is preferable for GNU/Linux with glibc version 2.31 or above. | |
In simpler words: `unknown-linux-gnu` is recommended for Arch Linux, Ubuntu 20.04, Debian 11 | |
(Bullseye), CentOS 9, RHEL 9, or newer. Older systems should download the `unknown-linux-musl` variant. | |
## Installation Script | |
A script is provided for downloading and installing the binary. | |
Install for all users (requires `sudo`): | |
```shell | |
curl --proto '=https' --tlsv1.2 -LsSf '${{ github.server_url }}/${{ github.repository }}/releases/download/${{ github.ref_name }}/installer.sh' | sudo env ${{ steps.create_script.outputs.bin_env_var_name }}=/usr/local/bin/mni2mz3 bash | |
``` | |
Install for current user: | |
```shell | |
curl --proto '=https' --tlsv1.2 -LsSf '${{ github.server_url }}/${{ github.repository }}/releases/download/${{ github.ref_name }}/installer.sh' | env ${{ steps.create_script.outputs.bin_env_var_name }}="$HOME/.local/bin/mni2mz3" bash | |
``` | |
Use in `Dockerfile` (requires `bash` and `curl`): | |
```Dockerfile | |
RUN curl --proto '=https' --tlsv1.2 -LsSf '${{ github.server_url }}/${{ github.repository }}/releases/download/${{ github.ref_name }}/installer.sh' | bash | |
``` | |
################################################# | |
# # | |
# 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 * |