mitts 0.3.21

Rust-first build and package tooling with a shared artifact cache
Documentation
# Mitts Build — native tests and cache-isolation gates.
# Copyright (c) 2026 Alexander Panasenko
# Contact: alex@prod.codes
# Author: https://prod.codes/about/
# Project: https://github.com/alex09x/mitts
# SPDX-License-Identifier: MIT OR Apache-2.0
name: CI

on:
  pull_request:
  push:
    branches: [main]
  workflow_call:
    inputs:
      ref:
        type: string
        default: ''

permissions:
  contents: read

jobs:
  automation:
    runs-on: ubuntu-22.04
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
        with:
          persist-credentials: false
      - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
        with:
          python-version: '3.12'
      - uses: dtolnay/rust-toolchain@b725eda525362e7cf34af9a7243cac1e3f01a7ec # stable
        with:
          toolchain: 1.98.0
      - name: Workflow and installer regressions
        run: python -m unittest discover -s scripts/release -p 'test_*.py' -v
      - name: Validate GitHub Actions syntax
        run: go run github.com/rhysd/actionlint/cmd/actionlint@v1.7.12 -color
  native:
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-22.04, macos-14]
    runs-on: ${{ matrix.os }}
    timeout-minutes: 90
    env:
      CARGO_BUILD_JOBS: '2'
      RUST_TEST_THREADS: '1'
      CARGO_TERM_COLOR: always
    steps:
      - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
        with:
          persist-credentials: false
      - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
        with:
          ref: ${{ inputs.ref || github.sha }}
          path: source
          fetch-depth: 0
          persist-credentials: false
      - uses: dtolnay/rust-toolchain@b725eda525362e7cf34af9a7243cac1e3f01a7ec # stable
        with:
          toolchain: 1.98.0
          components: rustfmt, clippy, llvm-tools-preview
      - uses: Swatinem/rust-cache@e9d7b9f1e587218970671bac74e5511ed9506e6a # v2
        with:
          workspaces: 'source -> target'
          cache-on-failure: true
      - name: Install latest stable Mitts
        env:
          MITTS_INSTALL_ROOT: ${{ runner.temp }}/mitts-bootstrap
        run: |
          sh site/install.sh
          binary="$MITTS_INSTALL_ROOT/bin/mitts"
          "$binary" --version
          printf 'MITTS_CI_BIN=%s\nMITTS_CI_CACHE_DIR=%s\n' "$binary" "$RUNNER_TEMP/mitts-ci-cache" >> "$GITHUB_ENV"
      - name: Native Bash 3.2 isolation-runner regressions
        if: runner.os == 'macOS'
        run: python3 -m unittest discover -s scripts/release -p test_ci_scripts.py -v
      - name: Formatting
        working-directory: source
        run: python3 "$GITHUB_WORKSPACE/scripts/release/check_format.py" --source . --mitts "$MITTS_CI_BIN"
      - name: Clippy
        working-directory: source
        run: '"$MITTS_CI_BIN" clippy --workspace --all-targets --cache-dir "$MITTS_CI_CACHE_DIR" -- -D warnings'
      - name: Full native suite with LLVM coverage in an isolated store
        working-directory: source
        env:
          MITTS_TEST_COMMAND: coverage
        run: |
          ulimit -n 4096
          mkdir -p .ci-tools
          cp "$GITHUB_WORKSPACE/scripts/run_tests_isolated.sh" .ci-tools/run-tests.sh
          bash .ci-tools/run-tests.sh --no-fail-fast --lcov --output-dir "$GITHUB_WORKSPACE/coverage"
      - name: Documentation tests through Mitts
        working-directory: source
        run: bash .ci-tools/run-tests.sh --doc
      - name: Coverage summary
        if: always()
        run: python3 scripts/release/coverage_summary.py coverage/lcov.info source "$GITHUB_STEP_SUMMARY"
      - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
        if: always()
        with:
          name: coverage-${{ matrix.os }}
          path: coverage/
          if-no-files-found: error
      - name: Prove isolation for every existing test target with independent Cargo runner
        working-directory: source
        run: |
          set -euo pipefail
          ulimit -n 4096
          # Use the portable runner even when validating an older release tag.
          # Untracked tools leave the exact source's tracked tree unchanged.
          mkdir -p .ci-tools
          cp "$GITHUB_WORKSPACE/scripts/probe_store_isolation.sh" .ci-tools/probe.sh
          /bin/bash .ci-tools/probe.sh
      - name: Source manifests and lockfile remain unchanged
        if: always()
        working-directory: source
        run: git diff --exit-code -- Cargo.toml Cargo.lock
  gate:
    if: always()
    needs: [automation, native]
    runs-on: ubuntu-22.04
    steps:
      - name: Require every check
        env:
          AUTOMATION: ${{ needs.automation.result }}
          NATIVE: ${{ needs.native.result }}
        run: test "$AUTOMATION" = success && test "$NATIVE" = success