fix: issue 1792 #4076
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
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.5 | |
- 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.5 | |
- name: Run clippy | |
run: cargo clippy --all-targets --workspace | |
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[] | select(.name == "pixi") | .name)' | tee -a $GITHUB_OUTPUT | |
cargo metadata --no-deps --format-version 1 | jq -r '"version=" + (.packages[] | select(.name == "pixi") | .version)' | tee -a $GITHUB_OUTPUT | |
cargo metadata --no-deps --format-version 1 | jq -r '"maintainer=" + (.packages[] | select(.name == "pixi") | .authors[0])' | tee -a $GITHUB_OUTPUT | |
cargo metadata --no-deps --format-version 1 | jq -r '"homepage=" + (.packages[] | select(.name == "pixi") | .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 }} | |
timeout-minutes: 60 | |
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-13 } | |
- { 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.5 | |
- 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 | |
--workspace | |
--retries 2 | |
--no-default-features --features rustls-tls --features slow_integration_tests | |
--status-level skip --failure-output immediate-final --no-fail-fast --final-status-level slow | |
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-13 } | |
- { 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. | |
# | |
# Pick the profile to build, as defined in Cargo.toml | |
CARGO_PROFILE: ${{ (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')) && 'dist' || 'ci' }} | |
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.5 | |
- name: Setup | Install cargo-wix [Windows] | |
# 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.8 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 on Linux / Mac | |
if: runner.os != 'Windows' | |
run: > | |
cargo build | |
--locked | |
--profile $CARGO_PROFILE | |
${{ steps.build-options.outputs.CARGO_BUILD_OPTIONS}} | |
- name: Build on Windows | |
if: runner.os == 'Windows' | |
run: > | |
cargo build | |
--locked | |
--profile $env:CARGO_PROFILE | |
${{ 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 }}/${CARGO_PROFILE}/${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 msi Installer | |
if: matrix.os == 'windows-latest' && matrix.target != 'aarch64-pc-windows-msvc' | |
run: > | |
cargo wix -v --no-build --nocapture -I install/windows/main.wxs | |
--profile $env:CARGO_PROFILE | |
--package pixi | |
--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 -o $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" | |
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-13 } | |
- { 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 }} |