Skip to content

feat(CHR-1): Complete self-contained Chronicle with local SQLite backend #17

feat(CHR-1): Complete self-contained Chronicle with local SQLite backend

feat(CHR-1): Complete self-contained Chronicle with local SQLite backend #17

Workflow file for this run

name: CI - Test Coverage & Quality
on:
push:
branches: [ main, dev ]
pull_request:
branches: [ main, dev ]
workflow_dispatch:
env:
NODE_VERSION: '18'
PYTHON_VERSION: '3.11'
jobs:
# Dashboard Tests & Coverage
dashboard-tests:
name: πŸ“Š Dashboard Tests & Coverage
runs-on: ubuntu-latest
defaults:
run:
working-directory: apps/dashboard
steps:
- name: πŸš€ Checkout code
uses: actions/checkout@v4
- name: πŸ“¦ Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
cache-dependency-path: apps/dashboard/package-lock.json
- name: πŸ“₯ Install dependencies
run: npm ci
- name: 🧹 Lint code
run: npm run lint
- name: πŸ§ͺ Run tests with coverage
run: npm run test -- --coverage --watchAll=false --passWithNoTests
env:
CI: true
- name: πŸ“Š Check coverage thresholds
run: |
# Extract coverage percentage from Jest output
COVERAGE=$(cat coverage/coverage-summary.json | jq '.total.lines.pct')
echo "Dashboard coverage: $COVERAGE%"
# Fail if below 80% threshold
if (( $(echo "$COVERAGE < 80" | bc -l) )); then
echo "❌ Dashboard coverage ($COVERAGE%) is below required 80% threshold"
exit 1
fi
echo "βœ… Dashboard coverage meets 80% threshold"
- name: πŸ“ˆ Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
flags: dashboard
directory: apps/dashboard/coverage
fail_ci_if_error: true
- name: πŸ’Ύ Archive coverage reports
uses: actions/upload-artifact@v4
with:
name: dashboard-coverage
path: apps/dashboard/coverage/
# Hooks Tests & Coverage
hooks-tests:
name: πŸͺ Hooks Tests & Coverage
runs-on: ubuntu-latest
defaults:
run:
working-directory: apps/hooks
steps:
- name: πŸš€ Checkout code
uses: actions/checkout@v4
- name: 🐍 Setup Python with uv
uses: astral-sh/setup-uv@v3
with:
version: "latest"
- name: πŸ”§ Setup Python environment
run: |
uv python install ${{ env.PYTHON_VERSION }}
uv sync
- name: 🧹 Lint code
run: uv run flake8 src tests
- name: πŸ” Type checking
run: uv run mypy src
- name: πŸ§ͺ Run tests with coverage
run: |
uv run pytest \
--cov=src \
--cov-report=term-missing \
--cov-report=json \
--cov-report=html \
--cov-report=lcov \
--cov-fail-under=60 \
-v
- name: πŸ“Š Check coverage thresholds
run: |
# Extract coverage percentage from pytest-cov JSON output
COVERAGE=$(cat coverage.json | jq '.totals.percent_covered')
echo "Hooks coverage: $COVERAGE%"
# Fail if below 60% threshold (already enforced by --cov-fail-under)
if (( $(echo "$COVERAGE < 60" | bc -l) )); then
echo "❌ Hooks coverage ($COVERAGE%) is below required 60% threshold"
exit 1
fi
echo "βœ… Hooks coverage meets 60% threshold"
- name: πŸ“ˆ Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
flags: hooks
files: apps/hooks/coverage.lcov
fail_ci_if_error: true
- name: πŸ’Ύ Archive coverage reports
uses: actions/upload-artifact@v4
with:
name: hooks-coverage
path: apps/hooks/htmlcov/
# Combined Coverage Analysis
coverage-analysis:
name: πŸ“ˆ Coverage Analysis & Reporting
runs-on: ubuntu-latest
needs: [dashboard-tests, hooks-tests]
steps:
- name: πŸš€ Checkout code
uses: actions/checkout@v4
- name: πŸ“¦ Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: πŸ“₯ Install root dependencies
run: npm ci
- name: πŸ“₯ Download coverage artifacts
uses: actions/download-artifact@v4
with:
pattern: '*-coverage'
merge-multiple: true
- name: πŸ“Š Generate coverage report
run: npm run coverage:report
- name: πŸ† Generate coverage badges
run: npm run coverage:badges
- name: πŸ“ˆ Track coverage trends
run: npm run coverage:trend
- name: πŸ’¬ Comment coverage on PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
// Read coverage data
const dashboardCoverage = JSON.parse(fs.readFileSync('dashboard-coverage/coverage-summary.json', 'utf8'));
const hooksCoverage = JSON.parse(fs.readFileSync('coverage.json', 'utf8'));
const dashboardPct = dashboardCoverage.total.lines.pct;
const hooksPct = hooksCoverage.totals.percent_covered;
const comment = `## πŸ“Š Coverage Report
| Component | Coverage | Threshold | Status |
|-----------|----------|-----------|--------|
| πŸ“Š Dashboard | ${dashboardPct.toFixed(1)}% | 80% | ${dashboardPct >= 80 ? 'βœ…' : '❌'} |
| πŸͺ Hooks | ${hooksPct.toFixed(1)}% | 60% | ${hooksPct >= 60 ? 'βœ…' : '❌'} |
${dashboardPct >= 80 && hooksPct >= 60 ? 'πŸŽ‰ All coverage thresholds met!' : '⚠️ Some coverage thresholds not met'}
View detailed reports in the CI artifacts.`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});
# Security & Quality Gates
quality-gates:
name: πŸ”’ Security & Quality Gates
runs-on: ubuntu-latest
needs: [dashboard-tests, hooks-tests]
steps:
- name: πŸš€ Checkout code
uses: actions/checkout@v4
- name: πŸ“¦ Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: πŸ”’ Dashboard Security Audit
working-directory: apps/dashboard
run: |
npm ci
npm audit --audit-level=moderate
- name: 🐍 Setup Python with uv
uses: astral-sh/setup-uv@v3
with:
version: "latest"
- name: πŸ”’ Hooks Security Check
working-directory: apps/hooks
run: |
uv sync
# Add safety check for Python dependencies
uv run pip install safety
uv run safety check
- name: βœ… Quality validation
run: |
echo "βœ… All quality gates passed"
echo "- Dashboard coverage >= 80%"
echo "- Hooks coverage >= 60%"
echo "- Security audits passed"
echo "- Linting checks passed"