Files
sausage/userland/fd/.github/workflows/CICD.yml
T
surma b9e3e3677d userland: search and exec tools, spawn library (T14)
rg (ripgrep 15.2), grep (ours, on ripgrep's regex crates), find and xargs
(ours), sed (uutils 0.3 wrapper), diff and cmp (uutils diffutils 0.6 with -r),
fd 10.5, jaq 2.3, env and timeout. userland/spawn is a small Command-like
client of the process interface. search-test.nu: 42 cases match native tools.
2026-11-06 17:21:51 +00:00

300 lines
10 KiB
YAML

name: CICD
env:
CICD_INTERMEDIATES_DIR: "_cicd-intermediates"
MSRV_FEATURES: "--all-features"
on:
workflow_dispatch:
pull_request:
push:
branches:
- master
tags:
- '*'
permissions:
contents: read
jobs:
crate_metadata:
name: Extract crate metadata
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7.0.1
with:
persist-credentials: false
- name: Extract crate information
id: crate_metadata
run: |
echo "name=fd" | 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
cargo metadata --no-deps --format-version 1 | jq -r '"msrv=" + .packages[0].rust_version' | 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 }}
msrv: ${{ steps.crate_metadata.outputs.msrv }}
ensure_cargo_fmt:
name: Ensure 'cargo fmt' has been run
runs-on: ubuntu-22.04
steps:
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt
- uses: actions/checkout@v7.0.1
with:
persist-credentials: false
- run: cargo fmt -- --check
lint_check:
name: Ensure 'cargo clippy' has no warnings
runs-on: ubuntu-latest
steps:
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- uses: actions/checkout@v7.0.1
with:
persist-credentials: false
- run: cargo clippy --all-targets --all-features -- -Dwarnings
min_version:
name: Minimum supported rust version
runs-on: ubuntu-22.04
needs: crate_metadata
steps:
- name: Checkout source code
uses: actions/checkout@v7.0.1
with:
persist-credentials: false
- name: Install rust toolchain (v${{ needs.crate_metadata.outputs.msrv }})
uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{ needs.crate_metadata.outputs.msrv }}
components: clippy
- name: Run clippy (on minimum supported rust version to prevent warnings we can't fix)
run: cargo clippy --locked --all-targets "${MSRV_FEATURES}"
- name: Run tests
run: cargo test --locked "${MSRV_FEATURES}"
build:
name: '${{ matrix.job.target }} (${{ matrix.job.os }})'
runs-on: ${{ matrix.job.os }}
needs: crate_metadata
permissions:
id-token: write
contents: write
attestations: write
strategy:
fail-fast: false
matrix:
job:
- { target: aarch64-unknown-linux-gnu , os: ubuntu-24.04, use-cross: true }
- { target: aarch64-unknown-linux-musl , os: ubuntu-24.04, use-cross: true }
- { target: arm-unknown-linux-gnueabihf , os: ubuntu-24.04, use-cross: true }
- { target: arm-unknown-linux-musleabihf, os: ubuntu-24.04, use-cross: true }
- { target: i686-pc-windows-msvc , os: windows-2025 }
- { target: i686-unknown-linux-gnu , os: ubuntu-24.04, use-cross: true }
- { target: i686-unknown-linux-musl , os: ubuntu-24.04, use-cross: true }
- { target: x86_64-apple-darwin , os: macos-26-intel }
- { target: aarch64-apple-darwin , os: macos-26 }
- { target: x86_64-pc-windows-gnu , os: windows-2025 }
- { target: x86_64-pc-windows-msvc , os: windows-2025 }
- { target: aarch64-pc-windows-msvc , os: windows-11-arm }
- { target: aarch64-pc-windows-gnullvm , os: windows-11-arm }
- { target: x86_64-unknown-linux-gnu , os: ubuntu-24.04, use-cross: true }
- { target: x86_64-unknown-linux-musl , os: ubuntu-24.04, use-cross: true }
env:
BUILD_CMD: "${{ matrix.job.use-cross && 'cross' || 'cargo' }}"
target: ${{ matrix.job.target }}
name: ${{ needs.crate_metadata.outputs.name }}
steps:
- name: Checkout source code
uses: actions/checkout@v7.0.1
with:
persist-credentials: false
- name: Install Windows ARM64 GNU-family linker
if: matrix.job.target == 'aarch64-pc-windows-gnullvm'
id: msys2
uses: msys2/setup-msys2@ec48f7c5447b3140e2b088413ae3a55687bccb6e # v2.33.0
with:
msystem: CLANGARM64
update: true
install: mingw-w64-clang-aarch64-clang
- name: Expose Windows ARM64 GNU-family linker
if: matrix.job.target == 'aarch64-pc-windows-gnullvm'
shell: bash
env:
MSYS2_LOCATION: ${{ steps.msys2.outputs.msys2-location }}
run: |
bin_dir=$(cygpath -w "${MSYS2_LOCATION}/clangarm64/bin")
echo "${bin_dir}" >> $GITHUB_PATH
echo "CARGO_TARGET_AARCH64_PC_WINDOWS_GNULLVM_LINKER=${bin_dir}\\clang.exe" >> $GITHUB_ENV
# Link libunwind statically so the release does not need MSYS2's libunwind.dll.
echo "CARGO_TARGET_AARCH64_PC_WINDOWS_GNULLVM_RUSTFLAGS=-C target-feature=+crt-static" >> $GITHUB_ENV
- name: Install prerequisites
shell: bash
run: |
case ${target} in
arm-unknown-linux-*) sudo apt-get -y update ; sudo apt-get -y install gcc-arm-linux-gnueabihf ;;
aarch64-unknown-linux-gnu) sudo apt-get -y update ; sudo apt-get -y install gcc-aarch64-linux-gnu ;;
esac
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.job.target }}
toolchain: "stable"
- name: Install cross
if: matrix.job.use-cross
env:
cross_version: "v0.2.5"
package_name: "cross-x86_64-unknown-linux-gnu.tar.gz"
GH_TOKEN: "${{ github.token }}"
run: |
dir="$HOME/.local/bin/"
mkdir -p "$dir"
gh release download --repo cross-rs/cross \
--pattern "${package_name}" -O - "${cross_version}" \
| tar -C "$dir" -xz
echo "$dir" >> $GITHUB_PATH
echo "Installed cross $cross_version" >> $GITHUB_STEP_SUMMARY
- name: Show version information (Rust, cargo, GCC)
shell: bash
run: |
gcc --version || true
rustup -V
rustup toolchain list
rustup default
cargo -V
rustc -V
- name: Build
shell: bash
run: $BUILD_CMD build --locked --release --target="${target}"
- name: Set binary name & path
id: bin
shell: bash
run: |
# Figure out suffix of binary
EXE_suffix=""
case ${target} in
*-pc-windows-*) EXE_suffix=".exe" ;;
esac;
# Setup paths
BIN_NAME="${name}${EXE_suffix}"
BIN_PATH="target/${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
- name: Set testing options
id: test-options
shell: bash
run: |
# test only library unit tests and binary for arm-type targets
unset CARGO_TEST_OPTIONS
case ${target} in
arm-* | aarch64-*)
CARGO_TEST_OPTIONS="--bin=${name}" ;;
esac
echo "CARGO_TEST_OPTIONS=${CARGO_TEST_OPTIONS}" >> $GITHUB_OUTPUT
- name: Run tests
shell: bash
env:
cargo_test_options: ${{ steps.test-options.outputs.CARGO_TEST_OPTIONS}}
run: $BUILD_CMD test --locked --target="${target}" "${cargo_test_options}"
- name: Generate completions
id: completions
shell: bash
run: make completions
- name: Create tarball
id: package
shell: bash
run: bash scripts/create-archive.sh
env:
BIN_PATH: ${{ steps.bin.outputs.BIN_PATH }}
TARGET: ${{ env.target }}
ARCHIVE_NAME: ${{ env.name }}-v${{ needs.crate_metadata.outputs.version }}-${{ env.target }}
PKG_STAGING: "${{ env.CICD_INTERMEDIATES_DIR }}/package"
- name: Create Debian package
id: debian-package
shell: bash
if: startsWith(matrix.job.os, 'ubuntu')
run: bash scripts/create-deb.sh
env:
TARGET: ${{ matrix.job.target }}
DPKG_VERSION: ${{ needs.crate_metadata.version }}
BIN_PATH: ${{ steps.bin.outputs.BIN_PATH }}
- name: "Artifact upload: tarball"
id: upload-tarball
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7
with:
name: ${{ steps.package.outputs.PKG_NAME }}
path: ${{ steps.package.outputs.PKG_PATH }}
compression-level: 0 # tarball is already compressed
- name: "Artifact upload: Debian package"
id: upload-deb
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7
if: steps.debian-package.outputs.DPKG_NAME
with:
name: ${{ steps.debian-package.outputs.DPKG_NAME }}
path: ${{ steps.debian-package.outputs.DPKG_PATH }}
compression-level: 0 # deb files are already compressed
- 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: "Attest artifacts"
uses: actions/attest@508db95dd578ae2727ebd6217d5ba78e4fbda05d # v4
if: steps.is-release.outputs.IS_RELEASE
with:
subject-path: |
${{ steps.package.outputs.PKG_PATH }}
${{ steps.debian-package.outputs.DPKG_PATH }}
- name: Publish archives and packages
uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3
if: steps.is-release.outputs.IS_RELEASE
with:
files: |
${{ steps.package.outputs.PKG_PATH }}
${{ steps.debian-package.outputs.DPKG_PATH }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
winget:
name: Publish to Winget
runs-on: ubuntu-latest
needs: build
if: startsWith(github.ref, 'refs/tags/v')
steps:
- uses: vedantmgoyal9/winget-releaser@b7370d4d152efdce803a26cc6ca9eee58cb2ad54 # v2
with:
identifier: sharkdp.fd
installers-regex: '-pc-windows-msvc\.zip$'
token: ${{ secrets.WINGET_TOKEN }}