Skip to content

Compile on Ubuntu 20.04 #12

Compile on Ubuntu 20.04

Compile on Ubuntu 20.04 #12

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 --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 *