BurntSushi/ripgrep

2 workflows · maturity 33% · 5 patterns · GitHub ↗

Security 25/100

Practices

✓ Matrix✓ Permissions○ Security scan○ AI review○ Cache○ Concurrency○ Reusable workflows

Detected patterns

Security dimensions

permissions
25
security scan
0
supply chain
0
secret handling
0
harden runner
0

Workflows (2)

ci matrix perms .github/workflows/ci.yml
Triggers
pull_request, push, schedule
Runs on
${{ matrix.os }}, ubuntu-latest, ubuntu-latest, ubuntu-latest, ubuntu-latest
Jobs
test, wasm, rustfmt, docs, fuzz_testing
Matrix
include, include.build, include.os, include.rust, include.target→ 1.85.0, aarch64-unknown-linux-gnu, armv7-unknown-linux-gnueabihf, armv7-unknown-linux-musleabi, armv7-unknown-linux-musleabihf, beta, i686-unknown-linux-gnu, macos, macos-latest, nightly, nightly-x86_64-gnu, pinned, powerpc64-unknown-linux-gnu, riscv64gc-unknown-linux-gnu, s390x-unknown-linux-gnu, stable, stable-aarch64, stable-arm-gnueabihf, stable-arm-musleabi, stable-arm-musleabihf, stable-musl, stable-powerpc64, stable-riscv64, stable-s390x, stable-x86, ubuntu-latest, win-gnu, win-msvc, winaarch64-msvc, windows-11-arm, windows-latest, x86_64-unknown-linux-musl
Actions
dtolnay/rust-toolchain, dtolnay/rust-toolchain, dtolnay/rust-toolchain, dtolnay/rust-toolchain, dtolnay/rust-toolchain
Commands
  • ci/ubuntu-install-packages
  • # In the past, new releases of 'cross' have broken CI. So for now, we # pin it. We also use their pre-compiled binary releases because cross # has over 100 dependencies and takes a bit to compile. dir="$RUNNER_TEMP/cross-download" mkdir "$dir" echo "$dir" >> $GITHUB_PATH cd "$dir" curl -LO "https://github.com/cross-rs/cross/releases/download/$CROSS_VERSION/cross-x86_64-unknown-linux-musl.tar.gz" tar xf cross-x86_64-unknown-linux-musl.tar.gz echo "CARGO=cross" >> $GITHUB_ENV echo "TARGET_FLAGS=--target ${{ matrix.target }}" >> $GITHUB_ENV echo "TARGET_DIR=./target/${{ matrix.target }}" >> $GITHUB_ENV
  • echo "cargo command is: ${{ env.CARGO }}" echo "target flag is: ${{ env.TARGET_FLAGS }}" echo "target dir is: ${{ env.TARGET_DIR }}"
  • ${{ env.CARGO }} build --verbose --workspace ${{ env.TARGET_FLAGS }}
  • ${{ env.CARGO }} build --verbose --workspace --features pcre2 ${{ env.TARGET_FLAGS }}
  • set +x stderr="$(find "${{ env.TARGET_DIR }}/debug" -name stderr -print0 | xargs -0 ls -t | head -n1)" if [ -s "$stderr" ]; then echo "===== $stderr ===== " cat "$stderr" echo "=====" fi set -x
  • ${{ env.CARGO }} test --verbose --workspace --features pcre2 ${{ env.TARGET_FLAGS }}
  • ${{ env.CARGO }} test --verbose --workspace ${{ env.TARGET_FLAGS }}
View raw YAML
name: ci
on:
  pull_request:
  push:
    branches:
    - master
  schedule:
  - cron: '00 01 * * *'

# The section is needed to drop write-all permissions that are granted on
# `schedule` event. By specifying any permission explicitly all others are set
# to none. By using the principle of least privilege the damage a compromised
# workflow can do (because of an injection or compromised third party tool or
# action) is restricted. Currently the worklow doesn't need any additional
# permission except for pulling the code. Adding labels to issues, commenting
# on pull-requests, etc. may need additional permissions:
#
# Syntax for this section:
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions
#
# Reference for how to assign permissions on a job-by-job basis:
# https://docs.github.com/en/actions/using-jobs/assigning-permissions-to-jobs
#
# Reference for available permissions that we can enable if needed:
# https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token
permissions:
  # to fetch code (actions/checkout)
  contents: read

jobs:
  test:
    name: test
    env:
      # For some builds, we use cross to test on 32-bit and big-endian
      # systems.
      CARGO: cargo
      # When CARGO is set to CROSS, this is set to `--target matrix.target`.
      # Note that we only use cross on Linux, so setting a target on a
      # different OS will just use normal cargo.
      TARGET_FLAGS:
      # When CARGO is set to CROSS, TARGET_DIR includes matrix.target.
      TARGET_DIR: ./target
      # Bump this as appropriate. We pin to a version to make sure CI
      # continues to work as cross releases in the past have broken things
      # in subtle ways.
      CROSS_VERSION: v0.2.5
      # Emit backtraces on panics.
      RUST_BACKTRACE: 1
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
        - build: pinned
          os: ubuntu-latest
          rust: 1.85.0
        - build: stable
          os: ubuntu-latest
          rust: stable
        - build: beta
          os: ubuntu-latest
          rust: beta
        - build: nightly
          os: ubuntu-latest
          rust: nightly
        - build: stable-musl
          os: ubuntu-latest
          rust: stable
          target: x86_64-unknown-linux-musl
        - build: stable-x86
          os: ubuntu-latest
          rust: stable
          target: i686-unknown-linux-gnu
        - build: stable-aarch64
          os: ubuntu-latest
          rust: stable
          target: aarch64-unknown-linux-gnu
        - build: stable-arm-gnueabihf
          os: ubuntu-latest
          rust: stable
          target: armv7-unknown-linux-gnueabihf
        - build: stable-arm-musleabihf
          os: ubuntu-latest
          rust: stable
          target: armv7-unknown-linux-musleabihf
        - build: stable-arm-musleabi
          os: ubuntu-latest
          rust: stable
          target: armv7-unknown-linux-musleabi
        - build: stable-powerpc64
          os: ubuntu-latest
          rust: stable
          target: powerpc64-unknown-linux-gnu
        - build: stable-s390x
          os: ubuntu-latest
          rust: stable
          target: s390x-unknown-linux-gnu
        - build: stable-riscv64
          os: ubuntu-latest
          rust: stable
          target: riscv64gc-unknown-linux-gnu
        - build: macos
          os: macos-latest
          rust: nightly
        - build: win-msvc
          os: windows-latest
          rust: nightly
        - build: win-gnu
          os: windows-latest
          rust: nightly-x86_64-gnu
        - build: winaarch64-msvc
          os: windows-11-arm
          rust: nightly
    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    - name: Install packages (Ubuntu)
      if: matrix.os == 'ubuntu-latest'
      run: |
        ci/ubuntu-install-packages

    - name: Install Rust
      uses: dtolnay/rust-toolchain@master
      with:
        toolchain: ${{ matrix.rust }}

    - name: Use Cross
      if: matrix.os == 'ubuntu-latest' && matrix.target != ''
      run: |
        # In the past, new releases of 'cross' have broken CI. So for now, we
        # pin it. We also use their pre-compiled binary releases because cross
        # has over 100 dependencies and takes a bit to compile.
        dir="$RUNNER_TEMP/cross-download"
        mkdir "$dir"
        echo "$dir" >> $GITHUB_PATH
        cd "$dir"
        curl -LO "https://github.com/cross-rs/cross/releases/download/$CROSS_VERSION/cross-x86_64-unknown-linux-musl.tar.gz"
        tar xf cross-x86_64-unknown-linux-musl.tar.gz
        echo "CARGO=cross" >> $GITHUB_ENV
        echo "TARGET_FLAGS=--target ${{ matrix.target }}" >> $GITHUB_ENV
        echo "TARGET_DIR=./target/${{ matrix.target }}" >> $GITHUB_ENV

    - name: Show command used for Cargo
      run: |
        echo "cargo command is: ${{ env.CARGO }}"
        echo "target flag is: ${{ env.TARGET_FLAGS }}"
        echo "target dir is: ${{ env.TARGET_DIR }}"

    - name: Build ripgrep and all crates
      run: ${{ env.CARGO }} build --verbose --workspace ${{ env.TARGET_FLAGS }}

    - name: Build ripgrep with PCRE2
      run: ${{ env.CARGO }} build --verbose --workspace --features pcre2 ${{ env.TARGET_FLAGS }}

    # This is useful for debugging problems when the expected build artifacts
    # (like shell completions and man pages) aren't generated.
    - name: Show build.rs stderr
      shell: bash
      run: |
        set +x
        stderr="$(find "${{ env.TARGET_DIR }}/debug" -name stderr -print0 | xargs -0 ls -t | head -n1)"
        if [ -s "$stderr" ]; then
          echo "===== $stderr ===== "
          cat "$stderr"
          echo "====="
        fi
        set -x

    - name: Run tests with PCRE2 (sans cross)
      if: matrix.target == ''
      run: ${{ env.CARGO }} test --verbose --workspace --features pcre2 ${{ env.TARGET_FLAGS }}

    - name: Run tests without PCRE2 (with cross)
      # These tests should actually work, but they almost double the runtime.
      # Every integration test spins up qemu to run 'rg', and when PCRE2 is
      # enabled, every integration test is run twice: one with the default
      # regex engine and once with PCRE2.
      if: matrix.target != ''
      run: ${{ env.CARGO }} test --verbose --workspace ${{ env.TARGET_FLAGS }}

    - name: Test zsh shell completions (Unix, sans cross)
      # We could test this when using Cross, but we'd have to execute the
      # 'rg' binary (done in test-complete) with qemu, which is a pain and
      # doesn't really gain us much. If shell completion works in one place,
      # it probably works everywhere.
      if: matrix.target == '' && !startsWith(matrix.os, 'windows')
      shell: bash
      run: ci/test-complete

    - name: Print hostname detected by grep-cli crate
      shell: bash
      run: ${{ env.CARGO }} test --manifest-path crates/cli/Cargo.toml ${{ env.TARGET_FLAGS }} --lib print_hostname -- --nocapture

    - name: Print available short flags
      shell: bash
      run: ${{ env.CARGO }} test --bin rg ${{ env.TARGET_FLAGS }} flags::defs::tests::available_shorts -- --nocapture

     # Setup and compile on the wasm32-wasip1 target
  wasm:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout repository
      uses: actions/checkout@v4
    - name: Install Rust
      uses: dtolnay/rust-toolchain@master
      with:
        toolchain: stable
    - name: Add wasm32-wasip1 target
      run: rustup target add wasm32-wasip1
    - name: Basic build
      run: cargo build --verbose

  rustfmt:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout repository
      uses: actions/checkout@v4
    - name: Install Rust
      uses: dtolnay/rust-toolchain@master
      with:
        toolchain: stable
        components: rustfmt
    - name: Check formatting
      run: cargo fmt --all --check

  docs:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
      - name: Install Rust
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: stable
      - name: Check documentation
        env:
          RUSTDOCFLAGS: -D warnings
        run: cargo doc --no-deps --document-private-items --workspace

  fuzz_testing:
    name: Compile Fuzz Test Targets
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Install required packages (Ubuntu)
        run: |
          sudo apt-get update
          sudo apt-get install g++ --yes

      - name: Install Rust
        uses: dtolnay/rust-toolchain@master
        with:
          toolchain: stable

      - name: Install Fuzzer
        run: cargo install cargo-fuzz
        working-directory: fuzz

      - name: Verify fuzz targets build
        run: cargo check
        working-directory: fuzz
release matrix perms .github/workflows/release.yml
Triggers
push
Runs on
ubuntu-latest, ${{ matrix.os }}, ubuntu-latest
Jobs
create-release, build-release, build-release-deb
Matrix
include, include.build, include.os, include.qemu, include.rust, include.strip, include.target→ aarch64-apple-darwin, aarch64-linux-gnu-strip, aarch64-pc-windows-msvc, aarch64-unknown-linux-gnu, arm-linux-gnueabihf-strip, arm-linux-musleabi-strip, arm-linux-musleabihf-strip, armv7-unknown-linux-gnueabihf, armv7-unknown-linux-musleabi, armv7-unknown-linux-musleabihf, i386, i686-pc-windows-msvc, i686-unknown-linux-gnu, linux, macos, macos-latest, nightly, nightly-x86_64-gnu, qemu-aarch64, qemu-arm, qemu-s390x, s390x-linux-gnu-strip, s390x-unknown-linux-gnu, stable, stable-aarch64, stable-arm-gnueabihf, stable-arm-musleabi, stable-arm-musleabihf, stable-s390x, stable-x86, ubuntu-latest, win-gnu, win-msvc, win32-msvc, winaarch64-msvc, windows-11-arm, windows-latest, x86_64-apple-darwin, x86_64-linux-gnu-strip, x86_64-linux-musl-strip, x86_64-pc-windows-gnu, x86_64-pc-windows-msvc, x86_64-unknown-linux-musl
Actions
dtolnay/rust-toolchain, dtolnay/rust-toolchain
Commands
  • echo "VERSION=${{ github.ref_name }}" >> $GITHUB_ENV
  • echo "version is: $VERSION"
  • if ! grep -q "version = \"$VERSION\"" Cargo.toml; then echo "version does not match Cargo.toml" >&2 exit 1 fi
  • gh release create $VERSION --draft --verify-tag --title $VERSION
  • ci/ubuntu-install-packages
  • # In the past, new releases of 'cross' have broken CI. So for now, we # pin it. We also use their pre-compiled binary releases because cross # has over 100 dependencies and takes a bit to compile. dir="$RUNNER_TEMP/cross-download" mkdir "$dir" echo "$dir" >> $GITHUB_PATH cd "$dir" curl -LO "https://github.com/cross-rs/cross/releases/download/$CROSS_VERSION/cross-x86_64-unknown-linux-musl.tar.gz" tar xf cross-x86_64-unknown-linux-musl.tar.gz echo "CARGO=cross" >> $GITHUB_ENV
  • echo "TARGET_FLAGS=--target ${{ matrix.target }}" >> $GITHUB_ENV echo "TARGET_DIR=./target/${{ matrix.target }}" >> $GITHUB_ENV
  • echo "cargo command is: ${{ env.CARGO }}" echo "target flag is: ${{ env.TARGET_FLAGS }}" echo "target dir is: ${{ env.TARGET_DIR }}"
View raw YAML
name: release

# Only do the release on x.y.z tags.
on:
  push:
    tags:
    - "[0-9]+.[0-9]+.[0-9]+"

# We need this to be able to create releases.
permissions:
  contents: write

jobs:
  # The create-release job runs purely to initialize the GitHub release itself,
  # and names the release after the `x.y.z` tag that was pushed. It's separate
  # from building the release so that we only create the release once.
  create-release:
    name: create-release
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Get the release version from the tag
        if: env.VERSION == ''
        run: echo "VERSION=${{ github.ref_name }}" >> $GITHUB_ENV
      - name: Show the version
        run: |
          echo "version is: $VERSION"
      - name: Check that tag version and Cargo.toml version are the same
        shell: bash
        run: |
          if ! grep -q "version = \"$VERSION\"" Cargo.toml; then
            echo "version does not match Cargo.toml" >&2
            exit 1
          fi
      - name: Create GitHub release
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: gh release create $VERSION --draft --verify-tag --title $VERSION
    outputs:
      version: ${{ env.VERSION }}

  build-release:
    name: build-release
    needs: ['create-release']
    runs-on: ${{ matrix.os }}
    env:
      # For some builds, we use cross to test on 32-bit and big-endian
      # systems.
      CARGO: cargo
      # When CARGO is set to CROSS, this is set to `--target matrix.target`.
      TARGET_FLAGS:
      # When CARGO is set to CROSS, TARGET_DIR includes matrix.target.
      TARGET_DIR: ./target
      # Bump this as appropriate. We pin to a version to make sure CI
      # continues to work as cross releases in the past have broken things
      # in subtle ways.
      CROSS_VERSION: v0.2.5
      # Emit backtraces on panics.
      RUST_BACKTRACE: 1
      # Build static releases with PCRE2.
      PCRE2_SYS_STATIC: 1
    strategy:
      fail-fast: false
      matrix:
        include:
        - build: linux
          os: ubuntu-latest
          rust: nightly
          target: x86_64-unknown-linux-musl
          strip: x86_64-linux-musl-strip
        - build: stable-x86
          os: ubuntu-latest
          rust: stable
          target: i686-unknown-linux-gnu
          strip: x86_64-linux-gnu-strip
          qemu: i386
        - build: stable-aarch64
          os: ubuntu-latest
          rust: stable
          target: aarch64-unknown-linux-gnu
          strip: aarch64-linux-gnu-strip
          qemu: qemu-aarch64
        - build: stable-arm-gnueabihf
          os: ubuntu-latest
          rust: stable
          target: armv7-unknown-linux-gnueabihf
          strip: arm-linux-gnueabihf-strip
          qemu: qemu-arm
        - build: stable-arm-musleabihf
          os: ubuntu-latest
          rust: stable
          target: armv7-unknown-linux-musleabihf
          strip: arm-linux-musleabihf-strip
          qemu: qemu-arm
        - build: stable-arm-musleabi
          os: ubuntu-latest
          rust: stable
          target: armv7-unknown-linux-musleabi
          strip: arm-linux-musleabi-strip
          qemu: qemu-arm
        - build: stable-s390x
          os: ubuntu-latest
          rust: stable
          target: s390x-unknown-linux-gnu
          strip: s390x-linux-gnu-strip
          qemu: qemu-s390x
        - build: macos
          os: macos-latest
          rust: nightly
          target: x86_64-apple-darwin
        - build: macos
          os: macos-latest
          rust: nightly
          target: aarch64-apple-darwin
        - build: win-msvc
          os: windows-latest
          rust: nightly
          target: x86_64-pc-windows-msvc
        - build: win-gnu
          os: windows-latest
          rust: nightly-x86_64-gnu
          target: x86_64-pc-windows-gnu
        - build: winaarch64-msvc
          os: windows-11-arm
          rust: nightly
          target: aarch64-pc-windows-msvc
        - build: win32-msvc
          os: windows-latest
          rust: nightly
          target: i686-pc-windows-msvc

    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    - name: Install packages (Ubuntu)
      if: matrix.os == 'ubuntu-latest'
      shell: bash
      run: |
        ci/ubuntu-install-packages

    - name: Install Rust
      uses: dtolnay/rust-toolchain@master
      with:
        toolchain: ${{ matrix.rust }}
        target: ${{ matrix.target }}

    - name: Use Cross
      if: matrix.os == 'ubuntu-latest' && matrix.target != ''
      shell: bash
      run: |
        # In the past, new releases of 'cross' have broken CI. So for now, we
        # pin it. We also use their pre-compiled binary releases because cross
        # has over 100 dependencies and takes a bit to compile.
        dir="$RUNNER_TEMP/cross-download"
        mkdir "$dir"
        echo "$dir" >> $GITHUB_PATH
        cd "$dir"
        curl -LO "https://github.com/cross-rs/cross/releases/download/$CROSS_VERSION/cross-x86_64-unknown-linux-musl.tar.gz"
        tar xf cross-x86_64-unknown-linux-musl.tar.gz
        echo "CARGO=cross" >> $GITHUB_ENV

    - name: Set target variables
      shell: bash
      run: |
        echo "TARGET_FLAGS=--target ${{ matrix.target }}" >> $GITHUB_ENV
        echo "TARGET_DIR=./target/${{ matrix.target }}" >> $GITHUB_ENV

    - name: Show command used for Cargo
      shell: bash
      run: |
        echo "cargo command is: ${{ env.CARGO }}"
        echo "target flag is: ${{ env.TARGET_FLAGS }}"
        echo "target dir is: ${{ env.TARGET_DIR }}"

    - name: Build release binary
      shell: bash
      run: |
        ${{ env.CARGO }} build --verbose --profile release-lto --features pcre2 ${{ env.TARGET_FLAGS }}
        if [[ "${{ matrix.os }}" == windows-* ]]; then
          bin="target/${{ matrix.target }}/release-lto/rg.exe"
        else
          bin="target/${{ matrix.target }}/release-lto/rg"
        fi
        echo "BIN=$bin" >> $GITHUB_ENV

    - name: Strip release binary (macos)
      if: matrix.os == 'macos-latest'
      shell: bash
      run: strip "$BIN"

    - name: Strip release binary (cross)
      if: env.CARGO == 'cross'
      shell: bash
      run: |
        docker run --rm -v \
          "$PWD/target:/target:Z" \
          "ghcr.io/cross-rs/${{ matrix.target }}:main" \
          "${{ matrix.strip }}" \
          "/$BIN"

    - name: Determine archive name
      shell: bash
      run: |
        version="${{ needs.create-release.outputs.version }}"
        echo "ARCHIVE=ripgrep-$version-${{ matrix.target }}" >> $GITHUB_ENV

    - name: Creating directory for archive
      shell: bash
      run: |
        mkdir -p "$ARCHIVE"/{complete,doc}
        cp "$BIN" "$ARCHIVE"/
        cp {README.md,COPYING,UNLICENSE,LICENSE-MIT} "$ARCHIVE"/
        cp {CHANGELOG.md,FAQ.md,GUIDE.md} "$ARCHIVE"/doc/

    - name: Generate man page and completions (no emulation)
      if: matrix.qemu == ''
      shell: bash
      run: |
        "$BIN" --version
        "$BIN" --generate complete-bash > "$ARCHIVE/complete/rg.bash"
        "$BIN" --generate complete-fish > "$ARCHIVE/complete/rg.fish"
        "$BIN" --generate complete-powershell > "$ARCHIVE/complete/_rg.ps1"
        "$BIN" --generate complete-zsh > "$ARCHIVE/complete/_rg"
        "$BIN" --generate man > "$ARCHIVE/doc/rg.1"

    - name: Generate man page and completions (emulation)
      if: matrix.qemu != ''
      shell: bash
      run: |
        docker run --rm -v \
          "$PWD/target:/target:Z" \
          "ghcr.io/cross-rs/${{ matrix.target }}:main" \
          "${{ matrix.qemu }}" "/$BIN" --version
        docker run --rm -v \
          "$PWD/target:/target:Z" \
          "ghcr.io/cross-rs/${{ matrix.target }}:main" \
          "${{ matrix.qemu }}" "/$BIN" \
            --generate complete-bash > "$ARCHIVE/complete/rg.bash"
        docker run --rm -v \
          "$PWD/target:/target:Z" \
          "ghcr.io/cross-rs/${{ matrix.target }}:main" \
          "${{ matrix.qemu }}" "/$BIN" \
            --generate complete-fish > "$ARCHIVE/complete/rg.fish"
        docker run --rm -v \
          "$PWD/target:/target:Z" \
          "ghcr.io/cross-rs/${{ matrix.target }}:main" \
          "${{ matrix.qemu }}" "/$BIN" \
            --generate complete-powershell > "$ARCHIVE/complete/_rg.ps1"
        docker run --rm -v \
          "$PWD/target:/target:Z" \
          "ghcr.io/cross-rs/${{ matrix.target }}:main" \
          "${{ matrix.qemu }}" "/$BIN" \
            --generate complete-zsh > "$ARCHIVE/complete/_rg"
        docker run --rm -v \
          "$PWD/target:/target:Z" \
          "ghcr.io/cross-rs/${{ matrix.target }}:main" \
          "${{ matrix.qemu }}" "/$BIN" \
            --generate man > "$ARCHIVE/doc/rg.1"

    - name: Build archive (Windows)
      shell: bash
      if: startsWith(matrix.os, 'windows')
      run: |
        7z a "$ARCHIVE.zip" "$ARCHIVE"
        certutil -hashfile "$ARCHIVE.zip" SHA256 > "$ARCHIVE.zip.sha256"
        echo "ASSET=$ARCHIVE.zip" >> $GITHUB_ENV
        echo "ASSET_SUM=$ARCHIVE.zip.sha256" >> $GITHUB_ENV

    - name: Build archive (Unix)
      shell: bash
      if: ${{ !startsWith(matrix.os, 'windows') }}
      run: |
        tar czf "$ARCHIVE.tar.gz" "$ARCHIVE"
        shasum -a 256 "$ARCHIVE.tar.gz" > "$ARCHIVE.tar.gz.sha256"
        echo "ASSET=$ARCHIVE.tar.gz" >> $GITHUB_ENV
        echo "ASSET_SUM=$ARCHIVE.tar.gz.sha256" >> $GITHUB_ENV

    - name: Upload release archive
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      shell: bash
      run: |
        version="${{ needs.create-release.outputs.version }}"
        gh release upload "$version" ${{ env.ASSET }} ${{ env.ASSET_SUM }}

  build-release-deb:
    name: build-release-deb
    needs: ['create-release']
    runs-on: ubuntu-latest
    env:
      TARGET: x86_64-unknown-linux-musl
      # Emit backtraces on panics.
      RUST_BACKTRACE: 1
      # Since we're distributing the dpkg, we don't know whether the user will
      # have PCRE2 installed, so just do a static build.
      PCRE2_SYS_STATIC: 1

    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    - name: Install packages (Ubuntu)
      shell: bash
      run: |
        ci/ubuntu-install-packages

    - name: Install Rust
      uses: dtolnay/rust-toolchain@master
      with:
        toolchain: nightly
        target: ${{ env.TARGET }}

    - name: Install cargo-deb
      shell: bash
      run: |
        cargo install cargo-deb

    # 'cargo deb' does not seem to provide a way to specify an asset that is
    # created at build time, such as ripgrep's man page. To work around this,
    # we force a debug build, copy out the man page (and shell completions)
    # produced from that build, put it into a predictable location and then
    # build the deb, which knows where to look.
    - name: Build debug binary to create release assets
      shell: bash
      run: |
        cargo build --target ${{ env.TARGET }}
        bin="target/${{ env.TARGET }}/debug/rg"
        echo "BIN=$bin" >> $GITHUB_ENV

    - name: Create deployment directory
      shell: bash
      run: |
        dir=deployment/deb
        mkdir -p "$dir"
        echo "DEPLOY_DIR=$dir" >> $GITHUB_ENV

    - name: Generate man page
      shell: bash
      run: |
        "$BIN" --generate man > "$DEPLOY_DIR/rg.1"

    - name: Generate shell completions
      shell: bash
      run: |
        "$BIN" --generate complete-bash > "$DEPLOY_DIR/rg.bash"
        "$BIN" --generate complete-fish > "$DEPLOY_DIR/rg.fish"
        "$BIN" --generate complete-zsh > "$DEPLOY_DIR/_rg"

    - name: Build release binary
      shell: bash
      run: |
        cargo deb --profile deb --target ${{ env.TARGET }}
        version="${{ needs.create-release.outputs.version }}"
        echo "DEB_DIR=target/${{ env.TARGET }}/debian" >> $GITHUB_ENV
        echo "DEB_NAME=ripgrep_$version-1_amd64.deb" >> $GITHUB_ENV

    - name: Create sha256 sum of deb file
      shell: bash
      run: |
        cd "$DEB_DIR"
        sum="$DEB_NAME.sha256"
        shasum -a 256 "$DEB_NAME" > "$sum"
        echo "SUM=$sum" >> $GITHUB_ENV

    - name: Upload release archive
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      shell: bash
      run: |
        cd "$DEB_DIR"
        version="${{ needs.create-release.outputs.version }}"
        gh release upload "$version" "$DEB_NAME" "$SUM"