UNPKG

@sebastienrousseau/dotfiles

Version:

The Trusted Shell Platform — Universal dotfiles managed by Chezmoi. Features Bash & Zsh for macOS, Linux & WSL. Rust modern tooling & enterprise-grade security.

119 lines (82 loc) 3.2 kB
--- render_with_liquid: false --- {% raw %} # ADR-001: Multi-stage CI/CD Pipeline Design **Status**: Accepted **Date**: 2026-02-09 **Authors**: @sebastienrousseau ## Context The dotfiles repository requires a CI/CD pipeline that: - Validates changes across multiple platforms (Linux, macOS) - Runs security scans to detect secrets and vulnerabilities - Tests shell scripts, Lua configurations, and Nix expressions - Maintains fast feedback loops for developers - Minimizes GitHub Actions costs (runner minutes) Traditional approaches run all checks on every commit, leading to: - Wasted compute on unrelated changes (e.g., running Lua linting when only docs change) - High costs from macOS runners ($0.08/min vs $0.008/min for Linux) - Long feedback times from sequential job execution ## Decision Implement a **5-stage progressive CI pipeline** with path-based filtering: ### Stage 1: Change Detection Use `dorny/paths-filter` to detect which file categories changed: - `shell`: *.sh, scripts/**, install/** - `lua`: dot_config/nvim/**, *.lua - `nix`: nix/**, *.nix - `config`: dot_*/**, .chezmoitemplates/** ### Stage 2: Lint (Parallel, Conditional) - **lint-shell**: Only runs if shell files changed - **lint-lua**: Only runs if Lua files changed - Run in parallel to minimize wall-clock time ### Stage 3: Security (Always on PRs) - **secrets-scan**: Gitleaks on every PR (critical) - **link-check**: Only on schedule (expensive) ### Stage 4: Test (Conditional Matrix) - Linux-only for PRs (cheapest) - Full matrix (Linux + macOS) on schedule/manual trigger - Docker container tests for installation validation ### Stage 5: Quality (Schedule/Manual Only) - Idempotency verification - Performance benchmarks - Nix flake checks ### Cost Optimization Strategies 1. **Path filters**: Skip jobs when files don't match 2. **Concurrency groups**: Cancel in-progress runs on new pushes 3. **Conditional matrices**: Expensive OS testing only on schedule 4. **Aggressive caching**: Tools, dependencies, databases ## Consequences ### Positive - ~50% reduction in GitHub Actions minutes - Fast feedback for most changes (1-3 minutes) - Comprehensive testing still available via schedule/manual - Clear separation of concerns between stages ### Negative - Complexity in workflow configuration - Some bugs might only surface in scheduled runs - Path filter maintenance required as repo structure evolves ### Neutral - Developers can trigger full CI manually with `workflow_dispatch` - Breaking changes to CI require testing across all stages ## Implementation ```yaml # Key patterns used on: push: paths: - '**.sh' # Only trigger on shell changes concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: changes: outputs: shell: ${{ steps.filter.outputs.shell }} lint-shell: needs: changes if: needs.changes.outputs.shell == 'true' ``` ## References - [GitHub Actions Path Filtering](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#onpushpull_requestpull_request_targetpathspaths-ignore) - [dorny/paths-filter](https://github.com/dorny/paths-filter) {% endraw %}