Skip to content

fix: Prepend pixi to path instead of appending (#1644) #78

fix: Prepend pixi to path instead of appending (#1644)

fix: Prepend pixi to path instead of appending (#1644) #78

Workflow file for this run

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
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 }}
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.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: |
# we don't have anymore vendored openssl so we need to use rustls
cargo nextest run --retries 2 --status-level skip --failure-output immediate-final --no-fail-fast --final-status-level slow --no-default-features --features rustls-tls --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.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.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 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
--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 --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"
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 }}