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:
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
- 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 "ââââââââââââââââââââââââââââââââââââââââââ"