From bc68b52a57c2a5c27195e56f75fdc55ac10801d2 Mon Sep 17 00:00:00 2001 From: Ruben Arts Date: Wed, 2 Oct 2024 16:39:02 +0200 Subject: [PATCH] ci: Split jobs, skip matrix logic --- .github/workflows/ci.yml | 188 ++++++++ .github/workflows/rust.yml | 924 ++++++++++++++++++------------------- 2 files changed, 649 insertions(+), 463 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..2f7ce22bf --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,188 @@ +name: CI + +on: + push: + branches: [ main ] + pull_request: + workflow_dispatch: + +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 + +jobs: + lint: + name: Lint & format rust code + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + components: rustfmt, clippy + + - name: Run rustfmt + uses: actions-rust-lang/rustfmt@v1 + + - uses: Swatinem/rust-cache@v2 + with: + save-if: false + - name: Run clippy + run: cargo clippy --all-targets --workspace + + # Checks for dependencies that are not used in the codebase + cargo-machete: + name: Cargo Machete + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Machete + uses: bnjbvr/cargo-machete@main + + + cargo-test-linux: + timeout-minutes: 10 + name: cargo test on Linux + runs-on: "${{ contains(github.event.pull_request.labels.*.name, 'ci:free') && 'ubuntu-latest' || '8core_ubuntu_latest_runner' }}" + steps: + - uses: actions/checkout@v4 + - uses: Swatinem/rust-cache@v2 + - uses: rui314/setup-mold@v1 + - name: Show version information (Rust, cargo, GCC) + shell: bash + run: | + gcc --version || true + rustup -V + rustup show + cargo -V + rustc -V + + - name: "Install cargo nextest" + uses: taiki-e/install-action@v2 + with: + tool: cargo-nextest + + - 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 + + cargo-test-windows: + timeout-minutes: 10 + name: cargo test on Windows + runs-on: "${{ contains(github.event.pull_request.labels.*.name, 'ci:free') && 'windows-latest' || '16core_windows_latest_runner' }}" + if: ${{ (github.event_name != 'pull_request') || contains(github.event.pull_request.labels.*.name, 'ci:all') }} + steps: + - uses: actions/checkout@v4 + - uses: Swatinem/rust-cache@v2 + - uses: rui314/setup-mold@v1 + - name: Show version information (Rust, cargo, MSVC) + shell: bash + run: | + rustup -V + rustup show + cargo -V + rustc -V + rustc -vV || true + + - name: "Install cargo nextest" + uses: taiki-e/install-action@v2 + with: + tool: cargo-nextest + + - 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 + + cargo-test-macos: + timeout-minutes: 10 + name: cargo test on macOS + runs-on: 'macos-latest' + steps: + - uses: actions/checkout@v4 + - uses: Swatinem/rust-cache@v2 + - uses: rui314/setup-mold@v1 + - name: Show version information (Rust, cargo, clang) + shell: bash + run: | + clang --version || true + rustup -V + rustup show + cargo -V + rustc -V + + - name: "Install cargo nextest" + uses: taiki-e/install-action@v2 + with: + tool: cargo-nextest + + - 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-linux: + name: Build on Linux + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: rui314/setup-mold@v1 + - name: Install Rust toolchain + uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + target: x86_64-unknown-linux-musl + - uses: Swatinem/rust-cache@v2 + + - name: "Build" + run: cargo build --locked --target x86_64-unknown-linux-musl --profile dist + + - name: "Upload binary" + uses: actions/upload-artifact@v4 + with: + name: pixi-linux-${{ github.sha }} + path: ./target/x86_64-unknown-linux-musl/debug/pixi + retention-days: 1 + + # TODO: Add build-windows and build-macos jobs + + + # TODO: Add Downstream tests jobs + + + # TODO: Create a release workflow + + rustdoc-links: + name: Check intra-doc links + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: Swatinem/rust-cache@v2 + with: + save-if: false + + - 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 diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index e2616952c..6b68f389e 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -1,463 +1,461 @@ -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 - -jobs: - check-rustdoc-links: - name: Check intra-doc links - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: Swatinem/rust-cache@v2 - with: - save-if: false - # - 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 - - uses: Swatinem/rust-cache@v2 - with: - save-if: false - - 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 }} - - # Checks for dependencies that are not used in the codebase - cargo-machete: - name: Cargo Machete - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Machete - uses: bnjbvr/cargo-machete@main - - 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: "${{ contains(github.event.pull_request.labels.*.name, 'ci:free') && 'ubuntu-latest' || '8core_ubuntu_latest_runner' }}", - } - - { 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: "${{ contains(github.event.pull_request.labels.*.name, 'ci:free') && 'windows-latest' || '16core_windows_latest_runner' }}", - } - - steps: - - uses: actions/checkout@v4 - - uses: taiki-e/setup-cross-toolchain-action@v1 - with: - target: ${{ matrix.target }} - - - uses: Swatinem/rust-cache@v2 - - - 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 - - - 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: "${{ contains(github.event.pull_request.labels.*.name, 'ci:free') && 'ubuntu-latest' || '8core_ubuntu_latest_runner' }}" - } - - { - 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: "${{ contains(github.event.pull_request.labels.*.name, 'ci:free') && 'windows-latest' || '16core_windows_latest_runner' }}" - } - - { - 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: Setup | Install cargo-wix [Windows] - # aarch64 is only supported in wix 4.0 development builds - if: startsWith(matrix.name, '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}" >> $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: startsWith(matrix.name, 'Windows') && 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: startsWith(matrix.name, 'Windows') && 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: - name: "Test examples, downstream projects and integration" - needs: - - build - uses: ./.github/workflows/test_downstream.yml - - export-filter: - name: Only run example tests if relevant code or manifests have changed - runs-on: ubuntu-20.04 - needs: - - build - outputs: - exports: ${{ steps.filter.outputs.exports }} - - steps: - - name: checkout repo - uses: actions/checkout@v4 - - uses: dorny/paths-filter@v3 - id: filter - with: - filters: | - exports: - - src/cli/project/export/conda_environment.rs - - src/cli/project/export/test-data/testenv/* - - examples/pypi-source-deps/* - - examples/pypi-custom-registry/* - - examples/pypi-find-links/* - - examples/docker/* - - export_tests: - name: "Export tests" - needs: export-filter - if: ${{ needs.export-filter.outputs.exports == 'true' }} - uses: ./.github/workflows/test_exports.yml - - test_common_wheels: - name: "Test installation of common wheels" - needs: - - build - uses: ./.github/workflows/test_common_wheels.yml +#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 +# +#jobs: +# check-rustdoc-links: +# name: Check intra-doc links +# runs-on: ubuntu-latest +# steps: +# - uses: actions/checkout@v4 +# +# - uses: Swatinem/rust-cache@v2 +# with: +# save-if: false +# +# - 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 +# - uses: Swatinem/rust-cache@v2 +# with: +# save-if: false +# - 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 }} +# +# # Checks for dependencies that are not used in the codebase +# cargo-machete: +# name: Cargo Machete +# runs-on: ubuntu-latest +# steps: +# - name: Checkout +# uses: actions/checkout@v3 +# - name: Machete +# uses: bnjbvr/cargo-machete@main +# +# 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: "${{ contains(github.event.pull_request.labels.*.name, 'ci:free') && 'ubuntu-latest' || '8core_ubuntu_latest_runner' }}", +# } +# - { 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: "${{ contains(github.event.pull_request.labels.*.name, 'ci:free') && 'windows-latest' || '16core_windows_latest_runner' }}", +# } +# +# steps: +# - uses: actions/checkout@v4 +# - uses: taiki-e/setup-cross-toolchain-action@v1 +# with: +# target: ${{ matrix.target }} +# +# - uses: Swatinem/rust-cache@v2 +# +# - 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 +# +# - 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: "${{ contains(github.event.pull_request.labels.*.name, 'ci:free') && 'ubuntu-latest' || '8core_ubuntu_latest_runner' }}" +# } +# - { +# 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: "${{ contains(github.event.pull_request.labels.*.name, 'ci:free') && 'windows-latest' || '16core_windows_latest_runner' }}" +# } +# - { +# 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: Setup | Install cargo-wix [Windows] +# # aarch64 is only supported in wix 4.0 development builds +# if: startsWith(matrix.name, '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}" >> $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: startsWith(matrix.name, 'Windows') && 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: startsWith(matrix.name, 'Windows') && 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: +# name: "Test examples, downstream projects and integration" +# needs: +# - build +# uses: ./.github/workflows/test_downstream.yml +# +# export-filter: +# name: Only run example tests if relevant code or manifests have changed +# runs-on: ubuntu-20.04 +# needs: +# - build +# outputs: +# exports: ${{ steps.filter.outputs.exports }} +# +# steps: +# - name: checkout repo +# uses: actions/checkout@v4 +# - uses: dorny/paths-filter@v3 +# id: filter +# with: +# filters: | +# exports: +# - src/cli/project/export/conda_environment.rs +# - src/cli/project/export/test-data/testenv/* +# - examples/pypi-source-deps/* +# - examples/pypi-custom-registry/* +# - examples/pypi-find-links/* +# - examples/docker/* +# +# export_tests: +# name: "Export tests" +# needs: export-filter +# if: ${{ needs.export-filter.outputs.exports == 'true' }} +# uses: ./.github/workflows/test_exports.yml +# +# test_common_wheels: +# name: "Test installation of common wheels" +# needs: +# - build +# uses: ./.github/workflows/test_common_wheels.yml