name: Check

on:
  push:
    branches:
      - main
  pull_request:

permissions:
  contents: read

jobs:
  format:
    name: Format
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        with:
          persist-credentials: false
      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # master
        with:
          toolchain: nightly
          components: rustfmt
      - name: Cache Rust build artifacts
        uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
      - name: Run format check
        run: cargo fmt --all -- --check

  typos:
    name: Typos
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        with:
          persist-credentials: false
      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # master
        with:
          toolchain: stable
      - name: Install cargo-binstall
        uses: taiki-e/install-action@7a79fe8c3a13344501c80d99cae481c1c9085912 # v2.81.10
        with:
          tool: cargo-binstall
      - name: Install typos
        run: cargo binstall --no-confirm typos-cli@1.47.2
      - name: Check spelling
        run: typos

  markdownlint:
    name: Markdownlint
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        with:
          persist-credentials: false
      - name: Install markdownlint-cli2
        run: npm install --global markdownlint-cli2@0.22.1
      - name: Lint Markdown
        run: markdownlint-cli2 "**/*.md"

  clippy:
    name: Clippy (${{ matrix.toolchain }})
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        # Beta Clippy runs as an early-warning gate for new lints before they reach stable. This
        # keeps future stable releases from turning unrelated PRs red because the baseline already
        # broke on main.
        toolchain:
          - stable
          - beta
    steps:
      - name: Checkout repository
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        with:
          persist-credentials: false
      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # master
        with:
          toolchain: ${{ matrix.toolchain }}
          components: clippy
      - name: Cache Rust build artifacts
        uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
      - name: Run clippy
        run: cargo +${{ matrix.toolchain }} clippy --all-targets --all-features --workspace -- -D warnings

  targets:
    name: Check Targets
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        with:
          persist-credentials: false
      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # master
        with:
          toolchain: stable
      - name: Cache Rust build artifacts
        uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
      - name: Check all workspace targets
        run: cargo check --all-targets --all-features --workspace

  cargo-deny:
    name: cargo-deny (${{ matrix.checks }})
    runs-on: ubuntu-latest
    strategy:
      matrix:
        checks:
          - advisories
          - bans licenses sources
    # Prevent a newly announced advisory from suddenly failing unrelated pull requests.
    continue-on-error: ${{ matrix.checks == 'advisories' }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        with:
          persist-credentials: false
      - name: Run cargo-deny
        uses: EmbarkStudios/cargo-deny-action@bb137d7af7e4fb67e5f82a49c4fce4fad40782fe # v2.0.20
        with:
          rust-version: stable
          log-level: info
          arguments: --all-features
          command: check ${{ matrix.checks }}

  semver-checks:
    name: Semver Checks
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        with:
          fetch-depth: 0
          persist-credentials: false
      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # master
        with:
          toolchain: stable
      - name: Cache Rust build artifacts
        uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
      - name: Install cargo-semver-checks
        uses: taiki-e/install-action@7a79fe8c3a13344501c80d99cae481c1c9085912 # v2.81.10
        with:
          tool: cargo-semver-checks@0.48
      - name: Run cargo-semver-checks
        run: cargo semver-checks --workspace

  docs:
    name: Docs
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        with:
          persist-credentials: false
      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # master
        with:
          toolchain: nightly
      - name: Cache Rust build artifacts
        uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
      - name: Build docs
        run: cargo doc --all-features --workspace

  msrv:
    name: MSRV
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        with:
          persist-credentials: false
      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # master
        with:
          toolchain: 1.88.0
      - name: Cache Rust build artifacts
        uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
      - name: Check workspace on MSRV
        run: cargo check --all-features --workspace

  readme:
    name: Readme
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        with:
          fetch-depth: 0
          persist-credentials: false
      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # master
        with:
          toolchain: stable
      - name: Install cargo-binstall
        uses: taiki-e/install-action@7a79fe8c3a13344501c80d99cae481c1c9085912 # v2.81.10
        with:
          tool: cargo-binstall
      - name: Install cargo-rdme
        run: |
          # normally we use https://github.com/taiki-e/install-action, but cargo-rdme 1.5.0
          # does not publish macOS binaries, so install-action blocks it
          cargo binstall --no-confirm cargo-rdme@1.5.0
      - name: Check READMEs
        run: |
          set -euo pipefail
          set -x
          cargo rdme --check --manifest-path Cargo.toml
          cargo rdme --check --manifest-path tui-bar-graph/Cargo.toml
          cargo rdme --check --manifest-path tui-big-text/Cargo.toml
          cargo rdme --check --manifest-path tui-box-text/Cargo.toml
          cargo rdme --check --manifest-path tui-cards/Cargo.toml
          cargo rdme --check --manifest-path tui-popup/Cargo.toml
          cargo rdme --check --manifest-path tui-prompts/Cargo.toml
          cargo rdme --check --manifest-path tui-qrcode/Cargo.toml
          cargo rdme --check --manifest-path tui-scrollbar/Cargo.toml
          cargo rdme --check --manifest-path tui-scrollview/Cargo.toml

  zizmor:
    name: zizmor
    runs-on: ubuntu-latest
    permissions:
      contents: read
      security-events: write
    steps:
      - name: Checkout repository
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        with:
          persist-credentials: false
      - name: Run zizmor
        uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6
        with:
          inputs: .github/workflows

  actionlint:
    name: actionlint
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
        with:
          persist-credentials: false
      - name: Run actionlint
        uses: docker://rhysd/actionlint:1.7.12
        with:
          args: -color

  required:
    runs-on: ubuntu-latest
    needs:
      - format
      - typos
      - markdownlint
      - clippy
      - targets
      - cargo-deny
      - semver-checks
      - docs
      - msrv
      - readme
      - actionlint
    if: ${{ always() }}
    steps:
      - name: Check required jobs
        env:
          NEEDS_JSON: ${{ toJson(needs) }}
          HAS_FAILED_JOB: >-
            ${{
              contains(needs.*.result, 'failure')
              || contains(needs.*.result, 'cancelled')
              || contains(needs.*.result, 'skipped')
            }}
        run: |
          echo "$NEEDS_JSON"
          test "$HAS_FAILED_JOB" = "false"
