Skip to content
Latchkey

CI workflow (clap-rs/clap)

The CI workflow from clap-rs/clap, explained and optimized by Latchkey.

B

CI health: B - good

Point runs-on at Latchkey and get job timeouts, SHA-pinned actions, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: clap-rs/clap.github/workflows/ci.ymlLicense Apache-2.0View source

What it does

This is the CI workflow from the clap-rs/clap repository, a real project running GitHub Actions. It is shown here with attribution under its Apache-2.0 license.

Below, Latchkey shows a faster, safer version produced by its optimization engine.

The workflow

workflow (.yml)
name: CI

permissions:
  contents: read

on:
  pull_request:
  push:
    branches:
      - "*master"

env:
  RUST_BACKTRACE: 1
  CARGO_TERM_COLOR: always
  CLICOLOR: 1

concurrency:
  group: "${{ github.workflow }}-${{ github.ref }}"
  cancel-in-progress: true

jobs:
  ci:
    permissions:
      contents: none
    name: CI
    needs: [test, shell-integration, shell-integration-nu, check, ui, minimal-versions, lockfile, docs, rustfmt, clippy, cffconvert]
    runs-on: ubuntu-latest
    if: "always()"
    steps:
      - name: Failed
        run: exit 1
        if: "contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped')"
  test:
    name: Test
    strategy:
      matrix:
        build: [linux, windows, mac, minimal, default, next]
        include:
        - build: linux
          os: ubuntu-latest
          rust: "stable"
          features: "full"
        - build: windows
          os: windows-latest
          rust: "stable"
          features: "full"
        - build: mac
          os: macos-latest
          rust: "stable"
          features: "full"
        - build: minimal
          os: ubuntu-latest
          rust: "stable"
          features: "minimal"
        - build: default
          os: ubuntu-latest
          rust: "stable"
          features: "default"
        - build: next
          os: ubuntu-latest
          rust: "stable"
          features: "next"
    continue-on-error: ${{ matrix.rust != 'stable' }}
    runs-on: ${{ matrix.os }}
    env:
      # Reduce amount of data cached
      CARGO_PROFILE_DEV_DEBUG: line-tables-only
    steps:
    - name: Checkout repository
      uses: actions/checkout@v7
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: ${{ matrix.rust }}
    - uses: Swatinem/rust-cache@v2
    - name: Build
      run: make build-${{matrix.features}}
    - name: Test
      run: make test-${{matrix.features}}
    - name: Test (benches)
      run: make test-${{matrix.features}} ARGS='--workspace --benches'
    - name: Test (ultra-minimal)
      if: matrix.build == 'minimal'
      run: make test-minimal ARGS='--manifest-path Cargo.toml'
    - name: Test dynamic completions
      run: cargo test -p clap_complete -F unstable-dynamic
  shell-integration:
    name: Shell Integration
    runs-on: ubuntu-latest
    steps:
    - name: Checkout repository
      uses: actions/checkout@v7
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: stable
    - uses: Swatinem/rust-cache@v2
    - name: Install shells
      if: runner.os == 'Linux'
      run: sudo apt-get install -y elvish fish zsh
    - name: clap_complete
      run: cargo test -p clap_complete -F unstable-dynamic -F unstable-shell-tests
  shell-integration-nu:
    name: Nushell Integration
    runs-on: ubuntu-latest
    steps:
    - name: Checkout repository
      uses: actions/checkout@v7
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: stable
    - uses: Swatinem/rust-cache@v2
    - name: clap_complete_nu
      run: cargo test -p clap_complete_nushell -F unstable-shell-tests
  check:
    name: Check
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        build: [msrv, wasm, wasm-wasi, debug, release]
        include:
          - build: msrv
            rust: "1.85"  # MSRV
            target: x86_64-unknown-linux-gnu
            features: full
          - build: wasm
            rust: stable
            target: wasm32-unknown-unknown
            features: wasm
          - build: wasm-wasi
            rust: stable
            target: wasm32-wasip2
            features: wasm
          - build: debug
            rust: stable
            target: x86_64-unknown-linux-gnu
            features: debug
          - build: release
            rust: stable
            target: x86_64-unknown-linux-gnu
            features: release
    steps:
      - name: Checkout repository
        uses: actions/checkout@v7
      - name: Install rust
        uses: dtolnay/rust-toolchain@stable
        with:
          toolchain: ${{ matrix.rust }}
          targets: ${{ matrix.target }}
      - uses: Swatinem/rust-cache@v2
      - name: Check
        run: make check-${{ matrix.features }}
        env:
          TOOLCHAIN_TARGET: ${{ matrix.target }}
  ui:
    name: UI Tests
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        features: [default, next]
    steps:
    - name: Checkout repository
      uses: actions/checkout@v7
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: "1.97"  # STABLE
    - uses: Swatinem/rust-cache@v2
    - name: UI Tests
      run: make test-ui-${{ matrix.features }}
  minimal-versions:
    name: Minimal versions
    strategy:
      matrix:
        os: ["ubuntu-latest"]
    runs-on: ${{ matrix.os }}
    steps:
    - name: Checkout repository
      uses: actions/checkout@v7
    - name: Install stable Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: stable
    - name: Install nightly Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: nightly
    - name: Downgrade dependencies to minimal versions
      run: cargo +nightly generate-lockfile -Z minimal-versions
    - name: Compile with minimal versions
      run: cargo +stable check --workspace --all-features --locked --exclude clap_complete_nushell --exclude clap_bench
  lockfile:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout repository
      uses: actions/checkout@v7
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: stable
    - uses: Swatinem/rust-cache@v2
    - name: "Is lockfile updated?"
      run: cargo update --workspace --locked
  docs:
    name: Docs
    runs-on: ubuntu-latest
    steps:
    - name: Checkout repository
      uses: actions/checkout@v7
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: "1.97"  # STABLE
    - uses: Swatinem/rust-cache@v2
    - name: Check documentation
      env:
        RUSTDOCFLAGS: -D warnings
      run: make doc
  rustfmt:
    name: rustfmt
    runs-on: ubuntu-latest
    steps:
    - name: Checkout repository
      uses: actions/checkout@v7
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: "1.97"  # STABLE
        components: rustfmt
    - uses: Swatinem/rust-cache@v2
    - name: Check formatting
      run: cargo fmt --check
  clippy:
    name: clippy
    runs-on: ubuntu-latest
    steps:
    - name: Checkout repository
      uses: actions/checkout@v7
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: "1.97"  # STABLE
        components: clippy
    - uses: Swatinem/rust-cache@v2
    - name: Lint (ultra-minimal)
      run: make clippy-minimal ARGS='--manifest-path Cargo.toml'
    - name: Lint (minimal)
      run: make clippy-minimal
    - name: Lint (all)
      run: make clippy-full
    - name: Lint (release)
      run: make clippy-release
  cffconvert:
    name: cffconvert
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v7
        with:
          persist-credentials: false
      - name: CFF validation
        uses: citation-file-format/cffconvert-github-action@2.0.0
        with:
          args: --validate

The same workflow, on Latchkey

Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.

name: CI
 
permissions:
  contents: read
 
on:
  pull_request:
  push:
    branches:
      - "*master"
 
env:
  RUST_BACKTRACE: 1
  CARGO_TERM_COLOR: always
  CLICOLOR: 1
 
concurrency:
  group: "${{ github.workflow }}-${{ github.ref }}"
  cancel-in-progress: true
 
jobs:
  ci:
    timeout-minutes: 30
    permissions:
      contents: none
    name: CI
    needs: [test, shell-integration, shell-integration-nu, check, ui, minimal-versions, lockfile, docs, rustfmt, clippy, cffconvert]
    runs-on: latchkey-small
    if: "always()"
    steps:
      - name: Failed
        run: exit 1
        if: "contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped')"
  test:
    timeout-minutes: 30
    name: Test
    strategy:
      matrix:
        build: [linux, windows, mac, minimal, default, next]
        include:
        - build: linux
          os: ubuntu-latest
          rust: "stable"
          features: "full"
        - build: windows
          os: windows-latest
          rust: "stable"
          features: "full"
        - build: mac
          os: macos-latest
          rust: "stable"
          features: "full"
        - build: minimal
          os: ubuntu-latest
          rust: "stable"
          features: "minimal"
        - build: default
          os: ubuntu-latest
          rust: "stable"
          features: "default"
        - build: next
          os: ubuntu-latest
          rust: "stable"
          features: "next"
    continue-on-error: ${{ matrix.rust != 'stable' }}
    runs-on: ${{ matrix.os }}
    env:
      # Reduce amount of data cached
      CARGO_PROFILE_DEV_DEBUG: line-tables-only
    steps:
    - name: Checkout repository
      uses: actions/checkout@v7
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: ${{ matrix.rust }}
    - uses: Swatinem/rust-cache@v2
    - name: Build
      run: make build-${{matrix.features}}
    - name: Test
      run: make test-${{matrix.features}}
    - name: Test (benches)
      run: make test-${{matrix.features}} ARGS='--workspace --benches'
    - name: Test (ultra-minimal)
      if: matrix.build == 'minimal'
      run: make test-minimal ARGS='--manifest-path Cargo.toml'
    - name: Test dynamic completions
      run: cargo test -p clap_complete -F unstable-dynamic
  shell-integration:
    timeout-minutes: 30
    name: Shell Integration
    runs-on: latchkey-small
    steps:
    - name: Checkout repository
      uses: actions/checkout@v7
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: stable
    - uses: Swatinem/rust-cache@v2
    - name: Install shells
      if: runner.os == 'Linux'
      run: sudo apt-get install -y elvish fish zsh
    - name: clap_complete
      run: cargo test -p clap_complete -F unstable-dynamic -F unstable-shell-tests
  shell-integration-nu:
    timeout-minutes: 30
    name: Nushell Integration
    runs-on: latchkey-small
    steps:
    - name: Checkout repository
      uses: actions/checkout@v7
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: stable
    - uses: Swatinem/rust-cache@v2
    - name: clap_complete_nu
      run: cargo test -p clap_complete_nushell -F unstable-shell-tests
  check:
    timeout-minutes: 30
    name: Check
    runs-on: latchkey-small
    strategy:
      fail-fast: false
      matrix:
        build: [msrv, wasm, wasm-wasi, debug, release]
        include:
          - build: msrv
            rust: "1.85"  # MSRV
            target: x86_64-unknown-linux-gnu
            features: full
          - build: wasm
            rust: stable
            target: wasm32-unknown-unknown
            features: wasm
          - build: wasm-wasi
            rust: stable
            target: wasm32-wasip2
            features: wasm
          - build: debug
            rust: stable
            target: x86_64-unknown-linux-gnu
            features: debug
          - build: release
            rust: stable
            target: x86_64-unknown-linux-gnu
            features: release
    steps:
      - name: Checkout repository
        uses: actions/checkout@v7
      - name: Install rust
        uses: dtolnay/rust-toolchain@stable
        with:
          toolchain: ${{ matrix.rust }}
          targets: ${{ matrix.target }}
      - uses: Swatinem/rust-cache@v2
      - name: Check
        run: make check-${{ matrix.features }}
        env:
          TOOLCHAIN_TARGET: ${{ matrix.target }}
  ui:
    timeout-minutes: 30
    name: UI Tests
    runs-on: latchkey-small
    strategy:
      fail-fast: false
      matrix:
        features: [default, next]
    steps:
    - name: Checkout repository
      uses: actions/checkout@v7
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: "1.97"  # STABLE
    - uses: Swatinem/rust-cache@v2
    - name: UI Tests
      run: make test-ui-${{ matrix.features }}
  minimal-versions:
    timeout-minutes: 30
    name: Minimal versions
    strategy:
      matrix:
        os: ["ubuntu-latest"]
    runs-on: ${{ matrix.os }}
    steps:
    - name: Checkout repository
      uses: actions/checkout@v7
    - name: Install stable Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: stable
    - name: Install nightly Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: nightly
    - name: Downgrade dependencies to minimal versions
      run: cargo +nightly generate-lockfile -Z minimal-versions
    - name: Compile with minimal versions
      run: cargo +stable check --workspace --all-features --locked --exclude clap_complete_nushell --exclude clap_bench
  lockfile:
    timeout-minutes: 30
    runs-on: latchkey-small
    steps:
    - name: Checkout repository
      uses: actions/checkout@v7
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: stable
    - uses: Swatinem/rust-cache@v2
    - name: "Is lockfile updated?"
      run: cargo update --workspace --locked
  docs:
    timeout-minutes: 30
    name: Docs
    runs-on: latchkey-small
    steps:
    - name: Checkout repository
      uses: actions/checkout@v7
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: "1.97"  # STABLE
    - uses: Swatinem/rust-cache@v2
    - name: Check documentation
      env:
        RUSTDOCFLAGS: -D warnings
      run: make doc
  rustfmt:
    timeout-minutes: 30
    name: rustfmt
    runs-on: latchkey-small
    steps:
    - name: Checkout repository
      uses: actions/checkout@v7
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: "1.97"  # STABLE
        components: rustfmt
    - uses: Swatinem/rust-cache@v2
    - name: Check formatting
      run: cargo fmt --check
  clippy:
    timeout-minutes: 30
    name: clippy
    runs-on: latchkey-small
    steps:
    - name: Checkout repository
      uses: actions/checkout@v7
    - name: Install Rust
      uses: dtolnay/rust-toolchain@stable
      with:
        toolchain: "1.97"  # STABLE
        components: clippy
    - uses: Swatinem/rust-cache@v2
    - name: Lint (ultra-minimal)
      run: make clippy-minimal ARGS='--manifest-path Cargo.toml'
    - name: Lint (minimal)
      run: make clippy-minimal
    - name: Lint (all)
      run: make clippy-full
    - name: Lint (release)
      run: make clippy-release
  cffconvert:
    timeout-minutes: 30
    name: cffconvert
    runs-on: latchkey-small
    steps:
      - name: Checkout repository
        uses: actions/checkout@v7
        with:
          persist-credentials: false
      - name: CFF validation
        uses: citation-file-format/cffconvert-github-action@2.0.0
        with:
          args: --validate
 

What changed

3 third-party actions are referenced by a movable tag. Pin them to the commit SHA (Latchkey resolves and applies this automatically) so a repointed tag cannot change what runs.

What Latchkey heals here

This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:

This workflow runs 12 jobs (22 with the matrix expanded) per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow