ops-jrz1/specs/001-extract-matrix-platform/contracts/ci-validation.yaml
Dan 894e7241f1 Initialize ops-jrz1 repository with Matrix platform extraction foundation
- Add speckit workflow infrastructure (.claude, .specify)
- Create NixOS configuration skeleton (flake.nix, configuration.nix, hosts/ops-jrz1.nix)
- Add sanitization scripts with 22 rules for personal info removal
- Add validation scripts with gitleaks integration
- Configure git hooks (pre-commit, pre-push) for security validation
- Add project documentation (README, LICENSE)
- Add comprehensive .gitignore for Nix, secrets, staging

Phase 1 and Phase 2 complete. Foundation ready for module extraction from ops-base.
2025-10-13 13:37:17 -07:00

420 lines
12 KiB
YAML

# CI/CD Validation Contract
# Defines automated checks that must pass before merging changes
version: "1.0"
description: "GitHub Actions CI validation requirements for nixos-matrix-platform-template"
# CI workflow configuration
workflow:
name: "CI"
file: ".github/workflows/ci.yml"
triggers:
- push
- pull_request
concurrency:
group: "${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: true
# Jobs and their contracts
jobs:
# Job 1: Nix validation and builds
validate:
name: "Nix Validation"
runs-on: "ubuntu-latest"
timeout-minutes: 10
failure_action: block-merge
steps:
- step: "checkout"
uses: "actions/checkout@v4"
contract:
must_succeed: true
failure_blocks_merge: true
- step: "install-nix"
uses: "cachix/install-nix-action@v25"
with:
nix_path: "nixpkgs=channel:nixos-24.05"
contract:
must_succeed: true
failure_blocks_merge: true
max_duration_seconds: 120
- step: "nix-flake-check"
name: "Run nix flake check"
command: "nix flake check --all-systems"
contract:
exit_code: 0
must_succeed: true
failure_blocks_merge: true
max_duration_seconds: 120
success_criteria:
- "All flake outputs validate successfully"
- "No syntax errors in Nix files"
- "All module options type-check correctly"
- step: "build-example-vps"
name: "Build example VPS configuration"
command: "nix build .#nixosConfigurations.example-vps.config.system.build.toplevel"
contract:
exit_code: 0
must_succeed: true
failure_blocks_merge: true
max_duration_seconds: 180
success_criteria:
- "example-vps.nix builds without errors"
- "All imported modules resolve correctly"
- "result symlink created"
- step: "build-example-dev"
name: "Build example dev configuration"
command: "nix build .#nixosConfigurations.example-dev.config.system.build.toplevel"
contract:
exit_code: 0
must_succeed: true
failure_blocks_merge: true
max_duration_seconds: 180
success_criteria:
- "example-dev.nix builds without errors"
- "All imported modules resolve correctly"
- "result symlink created"
# Job 2: Security scanning
security:
name: "Security Scanning"
runs-on: "ubuntu-latest"
timeout-minutes: 5
failure_action: block-merge
steps:
- step: "checkout"
uses: "actions/checkout@v4"
with:
fetch-depth: 0 # Full history for gitleaks
contract:
must_succeed: true
failure_blocks_merge: true
- step: "gitleaks-scan"
name: "Run gitleaks secret scanner"
uses: "gitleaks/gitleaks-action@v2"
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
contract:
exit_code: 0
must_succeed: true
failure_blocks_merge: true
max_duration_seconds: 60
success_criteria:
- "Zero secrets detected"
- "No Matrix tokens (syt_)"
- "No Slack tokens (xox*)"
- "No age keys (AGE-SECRET-KEY-*)"
- "No personal emails or domains"
failure_message: |
Secret detected in commit! This is a CRITICAL security issue.
DO NOT MERGE until secrets are removed.
Steps to fix:
1. Identify the secret in the gitleaks report above
2. Remove or replace with placeholder (e.g., REPLACE_WITH_TOKEN)
3. If secret is in git history, consider force-push (if safe)
4. Re-run CI to verify fix
# Job 3: Documentation validation
docs:
name: "Documentation Validation"
runs-on: "ubuntu-latest"
timeout-minutes: 5
failure_action: warn # Non-blocking for docs-only changes
steps:
- step: "checkout"
uses: "actions/checkout@v4"
contract:
must_succeed: true
- step: "markdown-lint"
name: "Lint markdown files"
uses: "DavidAnson/markdownlint-cli2-action@v14"
with:
globs: "**/*.md"
contract:
exit_code: 0
must_succeed: false # Warnings only
max_duration_seconds: 30
success_criteria:
- "Markdown files follow style guide"
- "No broken relative links"
- "Headers properly formatted"
- step: "check-links"
name: "Check for broken links"
uses: "gaurav-nelson/github-action-markdown-link-check@v1"
with:
use-quiet-mode: "yes"
config-file: ".github/markdown-link-check.json"
contract:
exit_code: 0
must_succeed: false # Warnings only
max_duration_seconds: 60
success_criteria:
- "All internal links resolve"
- "External links return 200 OK"
# Branch protection rules (configured via GitHub settings)
branch_protection:
branches:
- name: "main"
protections:
require_pull_request: true
require_approvals: 0 # v1.0 single maintainer
require_status_checks: true
required_checks:
- "Nix Validation"
- "Security Scanning"
dismiss_stale_reviews: false
require_code_owner_reviews: false
restrict_pushes: false # Allow maintainer to push directly if needed
allow_force_pushes: false
allow_deletions: false
# Status check requirements
status_checks:
strict: true # Require branches to be up-to-date before merging
contexts:
- "validate" # Job: Nix Validation
- "security" # Job: Security Scanning
# Validation matrix for different scenarios
validation_scenarios:
# Scenario 1: New module added
new_module:
required_checks:
- "nix flake check passes"
- "Module builds successfully"
- "gitleaks finds no secrets"
- "Module imported by at least one example configuration"
- "Module documented in README or relevant doc"
additional_manual_review:
- "Module follows existing patterns"
- "Options are well-documented"
- "Security hardening applied (if applicable)"
- "No personal configuration remains"
# Scenario 2: Documentation change
docs_only:
required_checks:
- "markdown-lint passes (or warnings explained)"
- "link-check passes (or broken links justified)"
- "gitleaks still passes (no secrets in examples)"
additional_manual_review:
- "Technical accuracy verified"
- "No personal infrastructure references"
- "Examples use generic domains/IPs"
# Scenario 3: Example configuration change
config_change:
required_checks:
- "nix flake check passes"
- "Modified configuration builds successfully"
- "gitleaks finds no secrets"
- "No personal domains/IPs introduced"
additional_manual_review:
- "Configuration still demonstrates intended use case"
- "Comments explain key options"
- "Secrets properly templated"
# Scenario 4: CI/CD workflow change
ci_change:
required_checks:
- "Workflow syntax valid (GitHub validates)"
- "Test run completes successfully"
- "No secrets exposed in workflow logs"
additional_manual_review:
- "Change doesn't weaken security checks"
- "Timeout values reasonable"
- "Failure actions appropriate (block vs warn)"
# Failure handling
failure_policies:
nix_build_failure:
severity: critical
action: block-merge
notification: "PR author + maintainers"
auto_comment: |
## Build Failure
The Nix build failed for this PR. This prevents merging.
**Common causes:**
- Syntax error in .nix file
- Missing import or dependency
- Type error in module options
- Invalid configuration value
**To debug:**
1. Run `nix flake check` locally
2. Run `nix build .#nixosConfigurations.<config-name>` locally
3. Check the error message for file and line number
4. Fix the issue and push updated commit
CI will automatically re-run on push.
secret_detected:
severity: critical
action: block-merge
notification: "PR author + maintainers + security team"
auto_comment: |
## ⚠️ SECRET DETECTED ⚠️
gitleaks has detected a potential secret in this PR.
**CRITICAL: DO NOT MERGE until resolved.**
**Steps to fix:**
1. Review the gitleaks report in the CI logs
2. Identify the secret (token, password, key, etc.)
3. Replace with placeholder or remove entirely
4. If secret is in git history:
- Consider force-push to remove (if safe)
- Or add to .gitignore and create new commit
5. Ensure secret is listed in secrets.yaml.example with generation instructions
6. Re-run CI to verify fix
**If this is a false positive:**
- Add pattern to .gitleaksignore (with justification in comment)
- Document why this is safe in PR description
docs_link_failure:
severity: warning
action: warn
notification: "PR author"
auto_comment: |
## Documentation Link Check Warning
Some links in documentation may be broken.
This is a **warning** - the PR can still be merged if links will be fixed soon.
**Common causes:**
- Link to external site that's temporarily down
- Link to doc that hasn't been created yet
- Typo in relative path
**To fix:**
1. Check the link-check report in CI logs
2. Fix broken links or remove them
3. For external links, verify they're stable/permanent
# Performance budgets
performance:
ci_total_time:
target: "5 minutes"
warning: "8 minutes"
critical: "10 minutes"
nix_flake_check:
target: "1 minute"
warning: "2 minutes"
critical: "3 minutes"
nix_build_per_config:
target: "2 minutes"
warning: "3 minutes"
critical: "5 minutes"
gitleaks_scan:
target: "20 seconds"
warning: "40 seconds"
critical: "60 seconds"
# Notification channels
notifications:
on_failure:
- github-pr-comment
- github-pr-status
on_success:
- github-pr-status
on_critical_failure:
- github-pr-comment
- github-pr-status
- email # If configured
# Metrics to track (post-deployment)
metrics:
ci_success_rate:
target: "> 95%"
measurement: "successful CI runs / total CI runs"
false_positive_rate:
target: "< 5%"
measurement: "false secret detections / total gitleaks runs"
average_ci_duration:
target: "< 5 minutes"
measurement: "mean duration of all CI runs"
time_to_fix_failures:
target: "< 1 hour"
measurement: "time from failure to green CI"
# Integration with GitHub features
github_integrations:
status_checks:
enabled: true
required_for_merge: ["validate", "security"]
auto_merge:
enabled: false # Manual merge for v1.0
discussions:
enabled: true
categories: ["Q&A", "Ideas", "Show and Tell"]
issues:
templates:
- bug_report.yml
- feature_request.yml
code_owners:
file: ".github/CODEOWNERS"
content: |
# Code ownership for nixos-matrix-platform-template
* @maintainer-username
# Security-critical files require extra review
.github/workflows/ @maintainer-username
modules/matrix-secrets/ @maintainer-username
*.sops.yaml @maintainer-username
# Pre-commit hooks (optional for contributors)
pre_commit:
config_file: ".pre-commit-config.yaml"
hooks:
- id: "gitleaks"
name: "gitleaks"
entry: "gitleaks protect --staged"
language: "system"
pass_filenames: false
- id: "nix-flake-check"
name: "nix flake check"
entry: "nix flake check"
language: "system"
pass_filenames: false
stages: [commit]
# Success criteria for CI system itself
ci_success_criteria:
- All jobs complete within performance budgets
- Zero false negatives (secrets not detected)
- < 5% false positives (valid code flagged as secret)
- Status checks correctly block/warn as configured
- Auto-comments provide helpful guidance
- Notifications reach appropriate parties
- Metrics tracked and visible in repository insights