chore: prepare for release v0.20.0 (#1238) #7
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
on: | |
push: | |
tags: | |
- "v*.*.*" | |
branches: | |
- main | |
paths-ignore: | |
- "docs/**" | |
- "mkdocs.yml" | |
- "*.md" | |
workflow_dispatch: | |
pull_request: | |
paths-ignore: | |
- "docs/**" | |
- "mkdocs.yml" | |
- "*.md" | |
name: Rust | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref }} | |
cancel-in-progress: true | |
env: | |
RUST_LOG: info | |
RUST_BACKTRACE: 1 | |
RUSTFLAGS: "-D warnings" | |
CARGO_TERM_COLOR: always | |
CICD_INTERMEDIATES_DIR: "_cicd-intermediates" | |
XDG_CACHE_HOME: ${{ github.workspace }}/.cache | |
SCCACHE_GHA_ENABLED: "true" | |
RUSTC_WRAPPER: "sccache" | |
jobs: | |
check-rustdoc-links: | |
name: Check intra-doc links | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Run sccache-cache | |
uses: mozilla-actions/sccache-action@v0.0.4 | |
- uses: actions-rust-lang/setup-rust-toolchain@v1 | |
- run: | | |
for package in $(cargo metadata --no-deps --format-version=1 | jq -r '.packages[] | .name'); do | |
cargo rustdoc -p "$package" --all-features -- -D warnings -W unreachable-pub | |
done | |
format: | |
name: Cargo Format | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
submodules: recursive | |
- uses: actions-rust-lang/setup-rust-toolchain@v1 | |
with: | |
components: rustfmt | |
- name: Run rustfmt | |
uses: actions-rust-lang/rustfmt@v1 | |
lint: | |
name: Cargo Lint | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
submodules: recursive | |
- uses: actions-rust-lang/setup-rust-toolchain@v1 | |
with: | |
components: clippy | |
- name: Run sccache-cache | |
uses: mozilla-actions/sccache-action@v0.0.4 | |
- name: Run clippy | |
run: cargo clippy | |
crate_metadata: | |
name: Extract crate metadata | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- name: Extract crate information | |
id: crate_metadata | |
run: | | |
cargo metadata --no-deps --format-version 1 | jq -r '"name=" + .packages[0].name' | tee -a $GITHUB_OUTPUT | |
cargo metadata --no-deps --format-version 1 | jq -r '"version=" + .packages[0].version' | tee -a $GITHUB_OUTPUT | |
cargo metadata --no-deps --format-version 1 | jq -r '"maintainer=" + .packages[0].authors[0]' | tee -a $GITHUB_OUTPUT | |
cargo metadata --no-deps --format-version 1 | jq -r '"homepage=" + .packages[0].homepage' | tee -a $GITHUB_OUTPUT | |
outputs: | |
name: ${{ steps.crate_metadata.outputs.name }} | |
version: ${{ steps.crate_metadata.outputs.version }} | |
maintainer: ${{ steps.crate_metadata.outputs.maintainer }} | |
homepage: ${{ steps.crate_metadata.outputs.homepage }} | |
cargo-test: | |
name: Cargo Test | ${{ matrix.name }} | |
runs-on: ${{ matrix.os }} | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
- { name: "Linux", target: x86_64-unknown-linux-musl, os: ubuntu-20.04 } | |
- { name: "macOS", target: x86_64-apple-darwin, os: macOS-latest } | |
- { name: "macOS-arm", target: aarch64-apple-darwin, os: macOS-14 } | |
- { name: "Windows", target: x86_64-pc-windows-msvc, os: windows-latest } | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: taiki-e/setup-cross-toolchain-action@v1 | |
with: | |
target: ${{ matrix.target }} | |
# - uses: Swatinem/rust-cache@v2 | |
- name: Run sccache-cache | |
uses: mozilla-actions/sccache-action@v0.0.4 | |
- name: Show version information (Rust, cargo, GCC) | |
shell: bash | |
run: | | |
gcc --version || true | |
rustup -V | |
rustup toolchain list | |
cargo -V | |
rustc -V | |
- name: "Install cargo nextest" | |
uses: taiki-e/install-action@v2 | |
with: | |
tool: cargo-nextest | |
- if: ${{ matrix.os != 'windows-latest' }} | |
uses: rui314/setup-mold@v1 | |
- name: "Cargo nextest" | |
run: | | |
cargo nextest run --retries 2 --status-level skip --failure-output immediate-final --no-fail-fast --final-status-level slow --features slow_integration_tests | |
build: | |
name: Build Binary | ${{ matrix.name }} | |
runs-on: ${{ matrix.os }} | |
needs: [ crate_metadata ] | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
- { name: "Linux-x86_64", target: x86_64-unknown-linux-musl, os: ubuntu-20.04 } | |
- { name: "Linux-aarch64", target: aarch64-unknown-linux-musl, os: ubuntu-latest } | |
- { name: "macOS-x86", target: x86_64-apple-darwin, os: macOS-latest } | |
- { name: "macOS-arm", target: aarch64-apple-darwin, os: macOS-14 } # macOS-14 is the ARM chipset | |
- { name: "Windows", target: x86_64-pc-windows-msvc, os: windows-latest } | |
- { name: "Windows-arm", target: aarch64-pc-windows-msvc, os: windows-latest } | |
env: | |
# | |
# These are some environment variables that configure the build so that the binary size is reduced. | |
# Inspiration was taken from this blog: https://arusahni.net/blog/2020/03/optimizing-rust-binary-size.html | |
# They're only enable it on main and releases. | |
# | |
# Enable Link Time Optimization (LTO) for our release builds. This increases link time but drastically reduces | |
# binary size. | |
CARGO_PROFILE_RELEASE_LTO: ${{ (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')) && 'true' || 'false' }} | |
# Use a single code gen unit, this effectively disables parallel linking but ensures that everything is linked | |
# together in a single unit which reduces the file-size at the cost of link time. | |
# Default for a release build is 16 | |
CARGO_PROFILE_RELEASE_CODEGEN_UNITS: ${{ (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')) && 1 || 16 }} | |
# Strip the binaries. This reduces the filesize of the final release. | |
CARGO_PROFILE_RELEASE_STRIP: ${{ (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')) && 'symbols' || 'false' }} | |
# Optimize the binary for size. This reduces the filesize at the cost of a slower binary. | |
CARGO_PROFILE_OPT_LEVEL: ${{ (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')) && 's' || '0' }} | |
steps: | |
- name: Checkout source code | |
uses: actions/checkout@v4 | |
- name: Install Rust toolchain | |
uses: actions-rust-lang/setup-rust-toolchain@v1 | |
with: | |
target: ${{ matrix.target }} | |
cache: false | |
- uses: taiki-e/setup-cross-toolchain-action@v1 | |
with: | |
target: ${{ matrix.target }} | |
- name: Use static CRT on Windows | |
shell: bash | |
run: echo "RUSTFLAGS=${RUSTFLAGS} -C target-feature=+crt-static" >> "${GITHUB_ENV}" | |
if: endsWith(matrix.target, 'windows-msvc') | |
# - uses: Swatinem/rust-cache@v2 | |
- name: Run sccache-cache | |
uses: mozilla-actions/sccache-action@v0.0.4 | |
- name: Setup | Install cargo-wix [Windows] | |
continue-on-error: true | |
# aarch64 is only supported in wix 4.0 development builds | |
if: startsWith(matrix.os, 'windows') && matrix.target != 'aarch64-pc-windows-msvc' | |
run: cargo install --version 0.3.4 cargo-wix | |
env: | |
# cargo-wix does not require static crt | |
RUSTFLAGS: "" | |
- name: Ensure cache directory exists | |
shell: bash | |
if: matrix.os == 'ubuntu-20.04' && matrix.use-cross | |
run: | | |
mkdir -p ${XDG_CACHE_HOME} | |
- name: Show version information (Rust, cargo, GCC) | |
shell: bash | |
run: | | |
gcc --version || true | |
rustup -V | |
rustup toolchain list | |
cargo -V | |
rustc -V | |
- name: Check for release | |
id: is-release | |
shell: bash | |
run: | | |
unset IS_RELEASE ; if [[ $GITHUB_REF =~ ^refs/tags/v[0-9].* ]]; then IS_RELEASE='true' ; fi | |
echo "IS_RELEASE=${IS_RELEASE}" >> $GITHUB_OUTPUT | |
- name: Use rustls on musl targets. | |
id: build-options | |
if: contains(matrix.target, '-musl') | |
run: | | |
echo "CARGO_BUILD_OPTIONS=${CARGO_BUILD_OPTIONS} --no-default-features --features rustls-tls" >> $GITHUB_OUTPUT | |
- name: Build | |
run: > | |
cargo build | |
--locked | |
--release | |
${{ steps.build-options.outputs.CARGO_BUILD_OPTIONS}} | |
- name: Set binary name & path | |
id: bin | |
shell: bash | |
run: | | |
# Figure out suffix of binary | |
EXE_SUFFIX="" | |
case ${{ matrix.target }} in | |
*-pc-windows-*) EXE_SUFFIX=".exe" ;; | |
esac; | |
# Setup paths | |
BIN_NAME="${{ needs.crate_metadata.outputs.name }}${EXE_SUFFIX}" | |
BIN_PATH="target/${{ matrix.target }}/release/${BIN_NAME}" | |
# Let subsequent steps know where to find the binary | |
echo "BIN_PATH=${BIN_PATH}" >> $GITHUB_OUTPUT | |
echo "BIN_NAME=${BIN_NAME}" >> $GITHUB_OUTPUT | |
echo "EXE_SUFFIX=${EXE_SUFFIX}" >> $GITHUB_OUTPUT | |
- name: Build Installer | |
continue-on-error: true | |
if: matrix.os == 'windows-latest' && matrix.target != 'aarch64-pc-windows-msvc' | |
run: > | |
cargo wix -v --no-build --nocapture -I install/windows/main.wxs | |
--target ${{ matrix.target }} | |
--output target/wix/pixi-${{ matrix.target }}.msi | |
# Here we notarize the binary with a certificate from Apple | |
# To get a certificate, go to XCode and request a Developer ID certificate for the right team. | |
# Then export the certificate from XCode and copy it as base64 into the secrets. | |
# Using e.g. `openssl base64 -in ~/Desktop/DeveloperID.p12 | tr -d '\n' | pbcopy` (to copy to clipboard). | |
# The password is the password you used to export the certificate. | |
# The ident is the ident of the certificate, which you can find in the keychain. | |
# The apple id password is a app specific password that you can get on the apple website (https://support.apple.com/en-us/HT204397) (usually a UUID looking string) | |
# The team id is the team id of the Apple Developer Team. | |
- name: Notarize binary | |
# only execute this step when releasing, or on main branch and on macOS | |
if: startsWith(matrix.os, 'macOS-') && (github.ref == 'refs/heads/main' || steps.is-release.outputs.IS_RELEASE) | |
env: | |
APPLEID_TEAMID: ${{ secrets.APPLEID_TEAMID }} | |
APPLEID_USERNAME: ${{ secrets.APPLEID_USERNAME }} | |
APPLEID_PASSWORD: ${{ secrets.APPLEID_PASSWORD }} | |
DEVELOPER_ID_CERTIFICATE: ${{ secrets.DEVELOPER_ID_CERTIFICATE }} | |
DEVELOPER_ID_PASSWORD: ${{ secrets.DEVELOPER_ID_PASSWORD }} | |
DEVELOPER_ID_IDENT: ${{ secrets.DEVELOPER_ID_IDENT }} | |
KEYCHAIN_FILENAME: app-signing.keychain-db | |
BIN_PATH: ${{ steps.bin.outputs.BIN_PATH }} | |
run: | | |
export KEYCHAIN_ENTRY="AC_PASSWORD" | |
INSTALL_CERTIFICATE_PATH="$RUNNER_TEMP/install_certificate.p12" | |
KEYCHAIN_PATH="$RUNNER_TEMP/$KEYCHAIN_FILENAME" | |
# create temporary keychain | |
export KEYCHAIN_PASSWORD=$(openssl rand -base64 32) | |
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" | |
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
echo -n "$DEVELOPER_ID_CERTIFICATE" | base64 --decode --output $INSTALL_CERTIFICATE_PATH | |
security import $INSTALL_CERTIFICATE_PATH -P "$DEVELOPER_ID_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH | |
security list-keychain -d user -s $KEYCHAIN_PATH | |
echo "Successfully imported Developer ID certificate into keychain" | |
# Add Apple Developer ID credentials to keychain | |
xcrun notarytool store-credentials "$KEYCHAIN_ENTRY" \ | |
--team-id "$APPLEID_TEAMID" \ | |
--apple-id "$APPLEID_USERNAME" \ | |
--password "$APPLEID_PASSWORD" \ | |
--keychain "$KEYCHAIN_PATH" | |
echo "Successfully added Apple Developer ID credentials to keychain" | |
echo "Now signing binary..." | |
# codesign binary | |
xcrun codesign --force --options=runtime --keychain "$KEYCHAIN_PATH" \ | |
--timestamp --sign "$DEVELOPER_ID_IDENT" --verbose "$BIN_PATH" \ | |
--identifier "dev.prefix.pixi" | |
zip pixi.zip ${BIN_PATH} | |
# notarize binary | |
xcrun notarytool submit pixi.zip --keychain-profile "$KEYCHAIN_ENTRY" --wait | |
- name: Create tarball | |
id: package | |
shell: bash | |
run: | | |
PKG_suffix=".tar.gz" ; case ${{ matrix.target }} in *-pc-windows-*) PKG_suffix=".zip" ;; esac; | |
PKG_BASENAME=${{ needs.crate_metadata.outputs.name }}-${{ matrix.target }} | |
PKG_NAME=${PKG_BASENAME}${PKG_suffix} | |
echo "PKG_NAME=${PKG_NAME}" >> $GITHUB_OUTPUT | |
PKG_STAGING="${{ env.CICD_INTERMEDIATES_DIR }}/package" | |
mkdir -p "${PKG_STAGING}" | |
# Binary | |
cp "${{ steps.bin.outputs.BIN_PATH }}" "$PKG_STAGING" | |
# README, LICENSE and CHANGELOG files | |
# cp "README.md" "LICENSE-MIT" "LICENSE-APACHE" "CHANGELOG.md" "$PKG_STAGING" | |
# base compressed package | |
pushd "${PKG_STAGING}/" >/dev/null | |
case ${{ matrix.target }} in | |
*-pc-windows-*) 7z -y a "${PKG_NAME}" ./* | tail -2 ;; | |
*) tar czf "${PKG_NAME}" ./* ;; | |
esac; | |
popd >/dev/null | |
cp "${{ steps.bin.outputs.BIN_PATH }}" "$PKG_STAGING/pixi-${{ matrix.target }}${{ steps.bin.outputs.EXE_SUFFIX }}" | |
# Let subsequent steps know where to find the compressed package | |
echo "PKG_PATH=${PKG_STAGING}/${PKG_NAME}" >> $GITHUB_OUTPUT | |
echo "BIN_PATH=$PKG_STAGING/pixi-${{ matrix.target }}${{ steps.bin.outputs.EXE_SUFFIX }}" >> $GITHUB_OUTPUT | |
- name: "Artifact upload: tarball" | |
uses: actions/upload-artifact@master | |
with: | |
name: ${{ steps.package.outputs.PKG_NAME }} | |
path: ${{ steps.package.outputs.PKG_PATH }} | |
- name: "Artifact upload: binary" | |
uses: actions/upload-artifact@master | |
with: | |
name: pixi-${{ matrix.target }}${{ steps.bin.outputs.EXE_SUFFIX }} | |
path: ${{ steps.package.outputs.BIN_PATH }} | |
- name: "Artifact upload: windows installer" | |
continue-on-error: true | |
if: matrix.os == 'windows-latest' && matrix.target != 'aarch64-pc-windows-msvc' | |
uses: actions/upload-artifact@v4 | |
with: | |
name: pixi-${{ matrix.target }}.msi | |
path: target/wix/pixi-${{ matrix.target }}.msi | |
- name: Publish packages | |
uses: softprops/action-gh-release@v2 | |
if: steps.is-release.outputs.IS_RELEASE | |
with: | |
draft: true | |
files: | | |
${{ steps.package.outputs.PKG_PATH }} | |
${{ steps.package.outputs.BIN_PATH }} | |
target/wix/pixi-${{ matrix.target }}.msi | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
downstream_tests: | |
needs: | |
- build | |
strategy: | |
fail-fast: false | |
matrix: | |
include: | |
- { target: x86_64-unknown-linux-musl, os: ubuntu-20.04 } | |
- { target: x86_64-apple-darwin, os: macOS-latest } | |
- { target: aarch64-apple-darwin, os: macOS-14 } # macOS-14 is the ARM chipset | |
- { target: x86_64-pc-windows-msvc, os: windows-latest , extension: .exe } | |
uses: ./.github/workflows/test_downstream.yml | |
with: | |
os: ${{ matrix.os }} | |
target: ${{ matrix.target }} | |
extension: ${{ matrix.extension }} |