Skip to main content

CI Integration Hook

GitHub Actions integration for running CODITECT quality checks in CI/CD pipeline with PR status reporting.


Purpose

The CI integration hook bridges local git hooks with GitHub Actions CI/CD to:

  1. Mirror Local Checks - Run same checks as pre-commit/pre-push in CI
  2. PR Status Checks - Report pass/fail status on pull requests
  3. Quality Gates - Enforce quality thresholds before merge
  4. Artifact Generation - Produce coverage reports, test results
  5. Notifications - Alert on failures via GitHub, Slack, email

Priority: P0 - Critical for automated quality enforcement Impact: Ensures all code meets quality standards before merge


Trigger

Event: GitHub Actions workflow triggers

  • push - On push to any branch
  • pull_request - On PR open, sync, reopen
  • workflow_dispatch - Manual trigger

Blocking: Yes - PR cannot merge if checks fail Timeout: 300 seconds (5 minutes per job)


Workflow Jobs

Quality Checks Job (P0)

Mirrors pre-commit hook checks:

  • Secrets Scan - gitleaks for credential detection
  • Python Lint - ruff linting and formatting
  • JavaScript Lint - eslint and prettier
  • Markdown Lint - markdownlint-cli2
  • YAML Validation - yamllint

Test Job (P0)

Mirrors pre-push hook checks:

  • Python Tests - pytest with coverage
  • JavaScript Tests - jest/vitest
  • Rust Tests - cargo test
  • Coverage Upload - Codecov/Coveralls

Build Job (P1)

Validates build process:

  • Python Build - pip wheel or poetry build
  • JavaScript Build - npm run build
  • Rust Build - cargo build --release
  • Docker Build - Build and tag container

Security Job (P1)

Security-specific checks:

  • Dependency Audit - npm audit, pip-audit, cargo-audit
  • SAST Scan - Semgrep or CodeQL
  • Container Scan - Trivy for Docker images

Installation

Step 1: Create Workflow File

Create .github/workflows/coditect-ci.yml:

name: CODITECT CI

on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
workflow_dispatch:
inputs:
skip_tests:
description: 'Skip test execution'
required: false
default: 'false'

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

jobs:
quality:
name: Quality Checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Install pre-commit
run: pip install pre-commit

- name: Run pre-commit hooks
run: pre-commit run --all-files

- name: Secrets Scan
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

test:
name: Tests
runs-on: ubuntu-latest
if: ${{ github.event.inputs.skip_tests != 'true' }}
strategy:
matrix:
python-version: ['3.10', '3.11', '3.12']
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
pip install -r requirements.txt
pip install pytest pytest-cov

- name: Run tests
run: |
pytest --cov=. --cov-report=xml --cov-fail-under=70

- name: Upload coverage
uses: codecov/codecov-action@v3
with:
files: ./coverage.xml
fail_ci_if_error: true

build:
name: Build
runs-on: ubuntu-latest
needs: [quality, test]
steps:
- uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Build package
run: |
pip install build
python -m build

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/

security:
name: Security Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Run Semgrep
uses: returntocorp/semgrep-action@v1
with:
config: p/default

- name: Dependency Audit
run: |
pip install pip-audit
pip-audit --require-hashes -r requirements.txt || true

Step 2: Configure Branch Protection

Go to GitHub Settings → Branches → Branch protection rules:

Branch: main
Settings:
- Require status checks to pass before merging:
- Required status checks:
- quality
- test
- build
- Require branches to be up to date:
- Require pull request reviews:
- Dismiss stale PR reviews:

Step 3: Add Secrets (if needed)

GitHub Settings → Secrets → Actions:

CODECOV_TOKEN - For coverage uploads
SLACK_WEBHOOK - For notifications (optional)

Configuration

Workflow Inputs

InputDefaultDescription
skip_testsfalseSkip test job
skip_securityfalseSkip security scan
python_version3.11Default Python version
coverage_threshold70Minimum coverage %

Environment Variables

env:
CODITECT_CI: true
COVERAGE_THRESHOLD: 70
LOG_LEVEL: info

Matrix Testing

strategy:
matrix:
python-version: ['3.10', '3.11', '3.12']
os: [ubuntu-latest, macos-latest]
fail-fast: false

Bypass

Skip Specific Jobs

# In commit message
git commit -m "docs: Update README [skip ci]"

# Skip tests only via workflow_dispatch
# Go to Actions → CODITECT CI → Run workflow
# Set skip_tests: true

Force Merge (Admin Only)

# Requires admin privileges
gh pr merge <pr-number> --admin --merge

Emergency Bypass

# Add to workflow for emergency override
if: |
github.event_name != 'pull_request' ||
contains(github.event.pull_request.labels.*.name, 'emergency')

Examples

Successful PR Checks

CODITECT CI / Quality Checks (pull_request) ✅
├── Checkout: 5s
├── Set up Python: 10s
├── Install pre-commit: 8s
├── Run pre-commit hooks: 25s ✅
└── Secrets Scan: 12s ✅

CODITECT CI / Tests (3.10) ✅
├── Checkout: 4s
├── Set up Python 3.10: 8s
├── Install dependencies: 15s
├── Run tests: 45s ✅ (48 passed, 0 failed)
└── Upload coverage: 5s ✅ (78% coverage)

CODITECT CI / Tests (3.11) ✅
└── ... similar ...

CODITECT CI / Tests (3.12) ✅
└── ... similar ...

CODITECT CI / Build ✅
├── Build package: 10s ✅
└── Upload artifacts: 3s ✅

CODITECT CI / Security Scan ✅
├── Semgrep: 30s ✅ (0 findings)
└── Dependency Audit: 15s ✅ (0 vulnerabilities)

All checks have passed!
Ready to merge ✅

Failed PR Checks

CODITECT CI / Quality Checks (pull_request) ❌
├── Checkout: 5s
├── Set up Python: 10s
├── Install pre-commit: 8s
└── Run pre-commit hooks: 25s ❌
Error: ruff found 3 issues
src/api.py:15: E501 Line too long
src/api.py:23: F401 Unused import
src/utils.py:8: E302 Expected 2 blank lines

CODITECT CI / Tests (3.11) ❌
├── Run tests: 45s ❌
FAILED tests/test_auth.py::test_login
AssertionError: Expected 200, got 401

Some checks were not successful
1 failing check

❌ Cannot merge until all checks pass

Troubleshooting

Tests Pass Locally But Fail in CI

Symptom: Different results between local and CI Solution:

# Ensure same Python version
python --version # local
# Check workflow for python-version

# Run with CI environment
CI=true pytest

# Check for environment-dependent tests
# Mark with @pytest.mark.skipif(os.environ.get('CI'))

Secrets Scan False Positives

Symptom: Gitleaks blocking legitimate code Solution:

# Create .gitleaksignore
echo "path/to/file.py:line_number" >> .gitleaksignore

# Or use inline allow
# gitleaks:allow
api_key = get_from_env("API_KEY")

Workflow Timeout

Symptom: Job exceeds timeout Solution:

jobs:
test:
timeout-minutes: 15 # Increase from default 6
steps:
- name: Run tests
timeout-minutes: 10 # Step-level timeout

Concurrent Workflow Issues

Symptom: Multiple workflows running on same PR Solution:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true # Cancel older runs

Coverage Below Threshold

Symptom: "Coverage 65% < 70% threshold" Solution:

# Check uncovered lines
pytest --cov=. --cov-report=term-missing

# Add tests for uncovered code
# Or adjust threshold temporarily
# coverage_threshold: 65

# Never lower threshold permanently without approval

Performance

JobTypical TimeMax Time
Quality Checks30-60s120s
Tests (per matrix)45-90s180s
Build15-30s60s
Security Scan30-60s120s
Total2-4 min8 min

Optimization Tips:

  1. Use caching for dependencies
  2. Run jobs in parallel where possible
  3. Use matrix fail-fast for quick feedback
  4. Skip unchanged jobs with paths filter
jobs:
test:
if: |
github.event_name != 'pull_request' ||
contains(github.event.pull_request.changed_files, 'src/') ||
contains(github.event.pull_request.changed_files, 'tests/')

Notifications

Slack Integration

- name: Notify Slack on Failure
if: failure()
uses: slackapi/slack-github-action@v1
with:
payload: |
{
"text": "CI Failed: ${{ github.repository }}",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*CI Failed* on `${{ github.ref_name }}`\n<${{ github.event.pull_request.html_url }}|View PR>"
}
}
]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}

Email Notification

- name: Email on Failure
if: failure()
uses: dawidd6/action-send-mail@v3
with:
server_address: smtp.gmail.com
server_port: 465
username: ${{ secrets.EMAIL_USERNAME }}
password: ${{ secrets.EMAIL_PASSWORD }}
subject: CI Failed - ${{ github.repository }}
to: team@example.com
from: ci@example.com
body: Build failed on ${{ github.ref_name }}


Implementation Files

Complete workflow file at:

  • .github/workflows/coditect-ci.yml (to be created)
  • .coditect/hooks/ci-integration (helper script)

Changelog

v1.0.0 - December 8, 2025

  • Initial comprehensive documentation
  • GitHub Actions workflow template
  • Branch protection configuration
  • Notification integrations
  • Performance optimization guide

Status: Production Ready Owner: Hal Casteel, CEO/CTO, AZ1.AI Inc. Copyright: 2025 AZ1.AI Inc. All Rights Reserved