dimpact 0.5.3

impact analysis from diff
Documentation
name: CI
on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main
  workflow_dispatch:

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

env:
  CARGO_TARGET_DIR: ${{ github.workspace }}/target
  CARGO_TERM_COLOR: always
  # Precision gate thresholds (FN/FP) for scripts/verify-precision-regression.sh
  # Global defaults (fallback when per-language thresholds are not set)
  DIMPACT_PRECISION_FN_MAX: "0"
  DIMPACT_PRECISION_FP_MAX: "0"
  # Language-specific threshold tuning (lang=threshold, comma-separated)
  DIMPACT_PRECISION_FN_MAX_BY_LANG: "typescript=0,javascript=0,tsx=0,rust=0,go=0,java=0,ruby=0,python=0"
  DIMPACT_PRECISION_FP_MAX_BY_LANG: "typescript=0,javascript=0,tsx=0,rust=0,go=0,java=0,ruby=0,python=0"

jobs:
  check:
    runs-on: ubuntu-latest
    container: ghcr.io/n01e0/dimpact-ci:latest
    steps:
      - name: Ensure base tools (git/bash/ripgrep)
        run: |
          if command -v apt-get >/dev/null 2>&1; then
            apt-get update
            DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends git bash ripgrep python3 ca-certificates
          elif command -v apk >/dev/null 2>&1; then
            apk add --no-cache git bash ripgrep python3 ca-certificates
          elif command -v yum >/dev/null 2>&1; then
            yum install -y git bash ripgrep python3 ca-certificates
          else
            echo "no supported package manager found to install git/bash/ripgrep" >&2
            exit 1
          fi
      - uses: actions/checkout@v6
      - name: Cache CARGO_HOME
        uses: actions/cache@v4
        with:
          path: ~/.cargo
          key: ${{ runner.os }}-cargo-home-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: ${{ runner.os }}
      - name: Install cargo-make
        run: cargo install cargo-make
      - name: Run cargo check --locked --all-targets
        run: |
          echo "::group::cargo check --locked --all-targets"
          if cargo check --locked --all-targets > cargo-check.log 2>&1; then
            cat cargo-check.log
          else
            cat cargo-check.log
            echo "::endgroup::"
            exit 1
          fi
          echo "::endgroup::"
      - name: Run cargo clippy --locked
        run: |
          echo "::group::cargo clippy --locked"
          if cargo clippy --locked > cargo-clippy.log 2>&1; then
            cat cargo-clippy.log
          else
            cat cargo-clippy.log
            echo "::endgroup::"
            exit 1
          fi
          echo "::endgroup::"
      - name: Summarize check/clippy failure logs
        if: failure()
        run: |
          {
            echo "## check/clippy failure summary"
            for f in cargo-check.log cargo-clippy.log; do
              if [ -f "$f" ]; then
                echo
                echo "### $f (tail -n 120)"
                echo '```'
                tail -n 120 "$f"
                echo '```'
              fi
            done
          } >> "$GITHUB_STEP_SUMMARY"
      - name: Upload check/clippy logs artifact
        if: always()
        uses: actions/upload-artifact@v7
        with:
          name: ci-check-logs
          path: |
            cargo-check.log
            cargo-clippy.log
          if-no-files-found: warn
  test:
    runs-on: ubuntu-latest
    container: ghcr.io/n01e0/dimpact-ci:latest
    steps:
      - name: Ensure base tools (git/bash/ripgrep)
        run: |
          if command -v apt-get >/dev/null 2>&1; then
            apt-get update
            DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends git bash ripgrep python3 ca-certificates
          elif command -v apk >/dev/null 2>&1; then
            apk add --no-cache git bash ripgrep python3 ca-certificates
          elif command -v yum >/dev/null 2>&1; then
            yum install -y git bash ripgrep python3 ca-certificates
          else
            echo "no supported package manager found to install git/bash/ripgrep" >&2
            exit 1
          fi
      - uses: actions/checkout@v6
      - name: Cache CARGO_HOME
        uses: actions/cache@v4
        with:
          path: ~/.cargo
          key: ${{ runner.os }}-cargo-home-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: ${{ runner.os }}
      - name: Run cargo test -q --locked
        run: |
          echo "::group::cargo test -q --locked"
          if cargo test -q --locked > cargo-test.log 2>&1; then
            cat cargo-test.log
          else
            cat cargo-test.log
            echo "::endgroup::"
            exit 1
          fi
          echo "::endgroup::"
      - name: Summarize cargo test failure logs
        if: failure()
        run: |
          {
            echo "## cargo test failure summary"
            if [ -f cargo-test.log ]; then
              echo
              echo "### cargo-test.log (tail -n 200)"
              echo '```'
              tail -n 200 cargo-test.log
              echo '```'
            fi
          } >> "$GITHUB_STEP_SUMMARY"
      - name: Upload cargo test logs artifact
        if: always()
        uses: actions/upload-artifact@v7
        with:
          name: ci-test-logs
          path: cargo-test.log
          if-no-files-found: warn

  precision_regression_gate:
    runs-on: ubuntu-latest
    container: ghcr.io/n01e0/dimpact-ci:latest
    steps:
      - name: Ensure base tools (git/bash/ripgrep)
        run: |
          if command -v apt-get >/dev/null 2>&1; then
            apt-get update
            DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends git bash ripgrep python3 ca-certificates
          elif command -v apk >/dev/null 2>&1; then
            apk add --no-cache git bash ripgrep python3 ca-certificates
          elif command -v yum >/dev/null 2>&1; then
            yum install -y git bash ripgrep python3 ca-certificates
          else
            echo "no supported package manager found to install git/bash/ripgrep" >&2
            exit 1
          fi
      - uses: actions/checkout@v6
      - name: Cache CARGO_HOME
        uses: actions/cache@v4
        with:
          path: ~/.cargo
          key: ${{ runner.os }}-cargo-home-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: ${{ runner.os }}
      - name: Run precision regression gate (FN/FP threshold)
        run: |
          echo "DIMPACT_PRECISION_FN_MAX=$DIMPACT_PRECISION_FN_MAX"
          echo "DIMPACT_PRECISION_FP_MAX=$DIMPACT_PRECISION_FP_MAX"
          echo "DIMPACT_PRECISION_FN_MAX_BY_LANG=$DIMPACT_PRECISION_FN_MAX_BY_LANG"
          echo "DIMPACT_PRECISION_FP_MAX_BY_LANG=$DIMPACT_PRECISION_FP_MAX_BY_LANG"
          if bash scripts/verify-precision-regression.sh --report precision-regression-report.json > precision-regression.log 2>&1; then
            cat precision-regression.log
          else
            cat precision-regression.log
            exit 1
          fi
      - name: Publish precision regression summary
        if: always()
        run: |
          {
            echo "## Precision regression gate"
            if [ -f precision-regression.log ]; then
              echo
              echo "### Log"
              echo '```'
              cat precision-regression.log
              echo '```'
            fi
            if [ -f precision-regression-report.json ]; then
              echo
              python3 scripts/render-precision-summary.py precision-regression-report.json
            fi
          } >> "$GITHUB_STEP_SUMMARY"
      - name: Upload precision regression artifacts
        if: always()
        uses: actions/upload-artifact@v7
        with:
          name: ci-precision-regression
          path: |
            precision-regression.log
            precision-regression-report.json
          if-no-files-found: warn

  engine_lsp_regression:
    runs-on: ubuntu-latest
    container: ghcr.io/n01e0/dimpact-ci:latest
    steps:
      - name: Ensure base tools (git/bash/ripgrep)
        run: |
          if command -v apt-get >/dev/null 2>&1; then
            apt-get update
            DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends git bash ripgrep python3 ca-certificates
          elif command -v apk >/dev/null 2>&1; then
            apk add --no-cache git bash ripgrep python3 ca-certificates
          elif command -v yum >/dev/null 2>&1; then
            yum install -y git bash ripgrep python3 ca-certificates
          else
            echo "no supported package manager found to install git/bash/ripgrep" >&2
            exit 1
          fi
      - uses: actions/checkout@v6
        with:
          fetch-depth: 2
      - name: Cache CARGO_HOME
        uses: actions/cache@v4
        with:
          path: ~/.cargo
          key: ${{ runner.os }}-cargo-home-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: ${{ runner.os }}
      - name: Run engine_lsp regression test suite
        run: cargo test -q --locked --test engine_lsp
      - name: Summarize strict real-LSP migration status + residual trend
        if: always()
        run: |
          set -euo pipefail
          bash scripts/summarize-strict-e2e-migration-progress.sh tests/engine_lsp.rs > strict-e2e-migration-summary.md

          bash scripts/summarize-strict-e2e-skips.sh \
            tests/engine_lsp.rs \
            strict-e2e-residual-after.json \
            strict-e2e-residual-after.md

          if git rev-parse --verify HEAD^ >/dev/null 2>&1; then
            git show HEAD^:tests/engine_lsp.rs > /tmp/engine_lsp.prev.rs
            bash scripts/summarize-strict-e2e-skips.sh \
              /tmp/engine_lsp.prev.rs \
              strict-e2e-residual-before.json \
              strict-e2e-residual-before.md
          else
            cp strict-e2e-residual-after.json strict-e2e-residual-before.json
          fi

          python3 scripts/render-strict-e2e-residual-trend.py \
            strict-e2e-residual-before.json \
            strict-e2e-residual-after.json \
            > strict-e2e-residual-trend.md

          cat strict-e2e-migration-summary.md >> "$GITHUB_STEP_SUMMARY"
          cat strict-e2e-residual-after.md >> "$GITHUB_STEP_SUMMARY"
          cat strict-e2e-residual-trend.md >> "$GITHUB_STEP_SUMMARY"

  lsp_graduation_check:
    runs-on: ubuntu-latest
    container: ghcr.io/n01e0/dimpact-ci:latest
    steps:
      - name: Ensure base tools (git/bash/ripgrep)
        run: |
          if command -v apt-get >/dev/null 2>&1; then
            apt-get update
            DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends git bash ripgrep python3 ca-certificates
          elif command -v apk >/dev/null 2>&1; then
            apk add --no-cache git bash ripgrep python3 ca-certificates
          elif command -v yum >/dev/null 2>&1; then
            yum install -y git bash ripgrep python3 ca-certificates
          else
            echo "no supported package manager found to install git/bash/ripgrep" >&2
            exit 1
          fi
      - uses: actions/checkout@v6
      - name: Run graduation auto-check script
        run: |
          if bash scripts/verify-lsp-graduation.sh --skip-regression > lsp-graduation-check.log 2>&1; then
            cat lsp-graduation-check.log
          else
            cat lsp-graduation-check.log
            exit 1
          fi
      - name: Publish graduation check summary
        if: always()
        run: |
          {
            echo "## LSP graduation auto-check (required-check lane)"
            if [ -f lsp-graduation-check.log ]; then
              echo
              echo "### Result"
              if grep -E '^PASS=[0-9]+ FAIL=[0-9]+' lsp-graduation-check.log >/dev/null; then
                grep -E '^PASS=[0-9]+ FAIL=[0-9]+' lsp-graduation-check.log
              else
                echo "PASS/FAIL summary line not found"
              fi
              echo
              echo "### Log tail (200 lines)"
              echo '```'
              tail -n 200 lsp-graduation-check.log
              echo '```'
            else
              echo "graduation check log missing"
            fi
          } >> "$GITHUB_STEP_SUMMARY"
      - name: Upload graduation check log artifact
        if: always()
        uses: actions/upload-artifact@v7
        with:
          name: ci-lsp-graduation-check
          path: lsp-graduation-check.log
          if-no-files-found: warn

  image_build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - name: Build Docker image
        run: docker build -t dimpact:${{ github.sha }} -f docker/Dockerfile .