mati 0.1.2

An enforcement layer for codebase knowledge: confirmed gotchas gate what AI agents read and edit at the hook level. Not a passive memory store.
Documentation
name: Release

on:
  push:
    tags:
      - 'v*'

env:
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1
  BINARY_NAME: mati

jobs:
  # ─────────────────────────────────────────────────────────────
  # Linux targets — cross-compiled via `cross`
  # ─────────────────────────────────────────────────────────────
  build-linux:
    name: Build ${{ matrix.target }}
    runs-on: ubuntu-latest
    strategy:
      matrix:
        target:
          - x86_64-unknown-linux-musl
          - aarch64-unknown-linux-musl

    steps:
      - uses: actions/checkout@v4

      - uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}

      - uses: Swatinem/rust-cache@v2
        with:
          key: ${{ matrix.target }}

      - name: Install cross
        run: cargo install cross --git https://github.com/cross-rs/cross

      - name: Build with cross
        run: cross build --release --target ${{ matrix.target }}

      - name: Strip binary
        run: |
          TARGET=${{ matrix.target }}
          if [[ "$TARGET" == aarch64* ]]; then
            STRIP_BIN="aarch64-linux-gnu-strip"
            sudo apt-get install -y binutils-aarch64-linux-gnu
          else
            STRIP_BIN="strip"
          fi
          $STRIP_BIN "target/$TARGET/release/$BINARY_NAME"

      - name: Package artifact
        run: |
          TARGET=${{ matrix.target }}
          ARTIFACT="mati-${TARGET}.tar.gz"
          tar -czf "$ARTIFACT" -C "target/$TARGET/release" "$BINARY_NAME"
          echo "ARTIFACT=$ARTIFACT" >> "$GITHUB_ENV"

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: mati-${{ matrix.target }}
          path: mati-${{ matrix.target }}.tar.gz
          retention-days: 1

  # ─────────────────────────────────────────────────────────────
  # macOS targets — native runners (cross does not support macOS)
  # ─────────────────────────────────────────────────────────────
  build-macos:
    name: Build ${{ matrix.target }}
    runs-on: macos-latest
    strategy:
      matrix:
        target:
          - x86_64-apple-darwin
          - aarch64-apple-darwin

    steps:
      - uses: actions/checkout@v4

      - uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}

      - uses: Swatinem/rust-cache@v2
        with:
          key: ${{ matrix.target }}

      - name: Build
        run: cargo build --release --target ${{ matrix.target }}

      - name: Strip binary
        run: strip "target/${{ matrix.target }}/release/$BINARY_NAME"

      - name: Package artifact
        run: |
          TARGET=${{ matrix.target }}
          ARTIFACT="mati-${TARGET}.tar.gz"
          tar -czf "$ARTIFACT" -C "target/$TARGET/release" "$BINARY_NAME"

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: mati-${{ matrix.target }}
          path: mati-${{ matrix.target }}.tar.gz
          retention-days: 1

  # ─────────────────────────────────────────────────────────────
  # Publish GitHub Release with all artifacts + checksums
  # ─────────────────────────────────────────────────────────────
  release:
    name: Publish GitHub Release
    needs: [build-linux, build-macos]
    runs-on: ubuntu-latest

    permissions:
      contents: write

    steps:
      - uses: actions/checkout@v4

      - uses: dtolnay/rust-toolchain@stable

      - name: Download all artifacts
        uses: actions/download-artifact@v4
        with:
          path: artifacts
          merge-multiple: true

      # Software Bill of Materials for the SHIPPED build. Generated from the
      # default feature set — exactly what the release binaries above are built
      # with (no `semantic`), so the SBOM lists the same dependency closure that
      # the build-time + runtime zero-network attestations (see ci.yml) cover.
      # Ships with every release so security teams can diff/scan the closure
      # offline instead of taking the "zero network" claim on faith.
      - name: Generate SBOM (CycloneDX) for the shipped build
        run: |
          set -euo pipefail
          cargo install cargo-cyclonedx --locked
          cargo cyclonedx --format json
          sbom="$(ls mati*.cdx.json bom.json 2>/dev/null | head -1 || true)"
          if [ -z "${sbom:-}" ]; then sbom="$(find . -maxdepth 2 -name '*.cdx.json' | head -1)"; fi
          test -n "${sbom:-}" && test -f "$sbom"
          cp "$sbom" artifacts/mati-sbom.cdx.json
          echo "SBOM: $sbom -> artifacts/mati-sbom.cdx.json ($(wc -c < artifacts/mati-sbom.cdx.json) bytes)"

      - name: Generate checksums
        run: |
          cd artifacts
          sha256sum mati-*.tar.gz mati-sbom.cdx.json > checksums.txt
          cat checksums.txt

      - name: Publish release
        uses: softprops/action-gh-release@v2
        with:
          files: |
            artifacts/mati-x86_64-unknown-linux-musl.tar.gz
            artifacts/mati-aarch64-unknown-linux-musl.tar.gz
            artifacts/mati-x86_64-apple-darwin.tar.gz
            artifacts/mati-aarch64-apple-darwin.tar.gz
            artifacts/mati-sbom.cdx.json
            artifacts/checksums.txt
          generate_release_notes: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}