pmat 3.30.1

PMAT - Zero-config AI context generation and code quality toolkit (CLI, MCP)
Documentation
# GitHub Actions Workflow for PMAT TDG Quality Enforcement
# Auto-generated by `pmat hooks install --tdg-enforcement --ci github`
# DO NOT EDIT MANUALLY - Regenerate with `pmat hooks refresh`
#
# This workflow enforces quality gates on pull requests and pushes:
# - Runs TDG analysis on all code changes
# - Checks for quality regressions against baseline
# - Enforces minimum quality grades for new/modified files
# - Blocks merges that violate configured thresholds
# - Auto-updates baseline on main branch commits
#
# Configuration: .pmat/tdg-rules.toml

name: PMAT TDG Quality Enforcement

on:
  pull_request:
    branches:
      - main
      - master
      - develop
    paths:
      - '**/*.rs'
      - '**/*.ts'
      - '**/*.js'
      - '**/*.py'
      - '**/*.go'
      - '**/*.java'
      - '**/*.cpp'
      - '**/*.c'
      - '**/*.h'
      - '**/*.hpp'
      - '.pmat/**'
  push:
    branches:
      - main
      - master
      - develop
  workflow_dispatch:  # Allow manual triggers

env:
  PMAT_VERSION: "{{PMAT_VERSION}}"
  BASELINE_PATH: "{{BASELINE_PATH}}"
  MIN_GRADE: "{{MIN_GRADE}}"
  MAX_SCORE_DROP: "{{MAX_SCORE_DROP}}"
  MODE: "{{MODE}}"

jobs:
  tdg-quality-check:
    name: TDG Quality Analysis
    runs-on: ubuntu-latest
    timeout-minutes: 30

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Full history for git context

      - name: Setup Rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt, clippy

      - name: Cache cargo registry
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

      - name: Install PMAT
        run: |
          echo "đŸ“Ļ Installing PMAT v${PMAT_VERSION}..."
          cargo install pmat --version ${PMAT_VERSION} --force
          pmat --version

      - name: Check for existing baseline
        id: baseline_check
        run: |
          if [ -f "${BASELINE_PATH}" ]; then
            echo "baseline_exists=true" >> $GITHUB_OUTPUT
            echo "✅ Found existing baseline: ${BASELINE_PATH}"
          else
            echo "baseline_exists=false" >> $GITHUB_OUTPUT
            echo "âš ī¸  No baseline found at ${BASELINE_PATH}"
          fi

      - name: Create initial baseline (if needed)
        if: steps.baseline_check.outputs.baseline_exists == 'false'
        run: |
          echo "📊 Creating initial TDG baseline..."
          mkdir -p $(dirname "${BASELINE_PATH}")
          pmat tdg baseline create --output "${BASELINE_PATH}" --path .
          echo "✅ Initial baseline created"

      - name: Run regression check
        id: regression_check
        if: github.event_name == 'pull_request'
        continue-on-error: true
        run: |
          echo "🔍 Checking for quality regressions..."
          pmat tdg check-regression \
            --baseline "${BASELINE_PATH}" \
            --path . \
            --format table \
            --max-score-drop ${MAX_SCORE_DROP} \
            --fail-on-regression

      - name: Check new file quality
        id: quality_check
        if: github.event_name == 'pull_request'
        continue-on-error: true
        run: |
          echo "📋 Checking quality of new/modified files..."
          pmat tdg check-quality \
            --path . \
            --format table \
            --new-files-only \
            --baseline "${BASELINE_PATH}" \
            --min-grade ${MIN_GRADE} \
            --fail-on-violation

      - name: Generate TDG report
        if: always()
        run: |
          echo "📊 Generating comprehensive TDG report..."
          pmat tdg --path . --format json --output tdg-report.json
          pmat tdg --path . --format markdown --output tdg-report.md

      - name: Upload TDG reports
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: tdg-reports
          path: |
            tdg-report.json
            tdg-report.md
          retention-days: 30

      - name: Comment PR with TDG results
        if: github.event_name == 'pull_request' && always()
        uses: actions/github-script@v7
        with:
          github-token: ${{secrets.GITHUB_TOKEN}}
          script: |
            const fs = require('fs');

            // Read markdown report if it exists
            let reportContent = '## PMAT TDG Quality Report\n\n';
            try {
              reportContent += fs.readFileSync('tdg-report.md', 'utf8');
            } catch (err) {
              reportContent += '❌ Error: Could not read TDG report';
            }

            // Add status badges
            const regressionStatus = '${{ steps.regression_check.outcome }}';
            const qualityStatus = '${{ steps.quality_check.outcome }}';

            let statusBadges = '\n### Quality Gate Status\n\n';
            statusBadges += regressionStatus === 'success'
              ? '✅ **Regression Check**: PASSED\n'
              : '❌ **Regression Check**: FAILED\n';
            statusBadges += qualityStatus === 'success'
              ? '✅ **Quality Check**: PASSED\n'
              : '❌ **Quality Check**: FAILED\n';

            reportContent = statusBadges + '\n' + reportContent;

            // Post comment
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: reportContent
            });

      - name: Fail workflow if quality gates failed
        if: |
          (steps.regression_check.outcome == 'failure' ||
           steps.quality_check.outcome == 'failure') &&
          env.MODE == 'strict'
        run: |
          echo "❌ Quality gates failed in strict mode"
          echo "   Fix quality issues or adjust thresholds in .pmat/tdg-rules.toml"
          exit 1

      - name: Update baseline on main branch
        if: |
          github.event_name == 'push' &&
          (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master')
        run: |
          echo "📊 Updating baseline for main branch..."
          pmat tdg baseline update --output "${BASELINE_PATH}" --path .

          # Commit and push updated baseline if changed
          if ! git diff --quiet "${BASELINE_PATH}"; then
            git config user.name "github-actions[bot]"
            git config user.email "github-actions[bot]@users.noreply.github.com"
            git add "${BASELINE_PATH}"
            git commit -m "chore: Update TDG baseline [skip ci]

            Auto-updated by PMAT TDG enforcement workflow

            🤖 Generated with PMAT"
            git push
            echo "✅ Baseline updated and committed"
          else
            echo "â„šī¸  Baseline unchanged"
          fi

      - name: Summary
        if: always()
        run: |
          echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
          echo "📊 PMAT TDG Quality Enforcement Summary"
          echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
          echo "Baseline: ${BASELINE_PATH}"
          echo "Min Grade: ${MIN_GRADE}"
          echo "Max Score Drop: ${MAX_SCORE_DROP}"
          echo "Mode: ${MODE}"
          echo ""
          echo "Regression Check: ${{ steps.regression_check.outcome }}"
          echo "Quality Check: ${{ steps.quality_check.outcome }}"
          echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"