Merge #68
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # ============================================================ | |
| # .github/workflows/ci-hygiene.yml (Continuous Integration) | |
| # ============================================================ | |
| # Updated: 2026-06-04 | |
| # | |
| # WHY-FILE: Minimal checks for repositories where hygiene is the primary gate. | |
| # REQ: Any check that can be run locally MUST be available locally via pre-commit. | |
| # REQ: CI MUST NOT introduce arbitrary rules that are not reproducible locally. | |
| # OBS: CI does not introduce additional style rules beyond repo configuration. | |
| name: CI Hygiene | |
| # WHY: Validate repo contents on pushes to main branch and pull requests. | |
| on: | |
| push: | |
| branches: [main] # WHY: Run when pushing to main branch. | |
| pull_request: | |
| branches: [main] # WHY: Run on pull requests targeting main branch. | |
| workflow_dispatch: # WHY: Allow manual triggering from Actions tab. | |
| permissions: # WHY: Use least privileges required. | |
| contents: read | |
| env: | |
| PYTHONUNBUFFERED: "1" # WHY: Real-time logging. | |
| PYTHONIOENCODING: "utf-8" # WHY: Ensure UTF-8 encoding for international characters. | |
| PYTHON_VERSION: "3.14" | |
| NODE_VERSION: "24" | |
| jobs: | |
| ci: | |
| name: Repository checks (pre-commit) | |
| runs-on: ubuntu-latest # WHY: Linux environment matches most production deployments. | |
| timeout-minutes: 10 # WHY: Prevent hanging jobs. If over, it is likely stuck. | |
| steps: | |
| # ============================================================ | |
| # ASSEMBLE: Get code and set up environment | |
| # ============================================================ | |
| - name: A1) Checkout repository code | |
| # WHY: Needed to access files for checks. | |
| uses: actions/checkout@v7 | |
| - name: A2) Set up Python | |
| # WHY: pre-commit and uvx-based hooks require Python tooling. | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: A3) Set up uv | |
| # WHY: Local hooks invoke uvx, so CI must provide uvx on PATH. | |
| uses: astral-sh/setup-uv@v7 | |
| - name: A4) Set up Node.js | |
| # WHY: markdownlint hook uses npx markdownlint-cli2. | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| - name: A5) Run pre-commit (all files) | |
| # WHY: Single source of truth for locally runnable quality gates. | |
| # OBS: Fails if hooks would modify files; does not commit changes. | |
| id: precommit | |
| run: | | |
| python -m pip install --upgrade pip | |
| python -m pip install pre-commit | |
| pre-commit run --show-diff-on-failure --color=always --all-files | |
| - name: A5f) If pre-commit failed, explain local fix | |
| if: failure() | |
| run: | | |
| echo "## Pre-commit failed" >> "$GITHUB_STEP_SUMMARY" | |
| echo "Please run the following locally and commit the resulting changes:" >> "$GITHUB_STEP_SUMMARY" | |
| echo "" >> "$GITHUB_STEP_SUMMARY" | |
| echo '```shell' >> "$GITHUB_STEP_SUMMARY" | |
| echo "uvx pre-commit run --all-files" >> "$GITHUB_STEP_SUMMARY" | |
| echo '```' >> "$GITHUB_STEP_SUMMARY" |