Skip to content

update

update #19

# ============================================================
# .github/workflows/ci-python-zensical.yml (ALL-PY-SRC-REPOS)
# ============================================================
# Updated: 2026-08-12
# WHY: Continuous Integration (CI) ensures repository hygiene,
# Python correctness, and documentation builds.
# REQ: CI MUST NOT introduce rules that are not reproducible locally.
# OBS: CI validates only; it does not edit files or deploy docs.
# OBS: yamllint config lives at .github/.yamllint.yml (not repo root).
# Name shown in the repo Actions tab.
name: CI (Python + Zensical)
on:
push:
branches: [main] # WHY: Validate on every push to GitHub branch `main`.
pull_request:
branches: [main] # WHY: Validate any pull requests (PRs) before merge.
workflow_dispatch: # WHY: Allow manual trigger from Actions tab.
permissions: # Least-privilege: this job only needs to READ.
contents: read # It checks code; it never writes to the repo.
concurrency:
group: ci-python-zensical-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
# WHY: Cancel stale CI runs for the same workflow/ref when a newer commit arrives.
# OBS: Different PRs and branches still run independently.
env:
PYTHONUNBUFFERED: "1" # WHY: Real-time log output in CI.
PYTHONIOENCODING: "utf-8" # WHY: Consistent encoding across platforms.
jobs:
ci:
name: Repo checks and Zensical build
runs-on: ubuntu-latest # WHY: Linux matches most production deployments.
timeout-minutes: 30 # WHY: Fail fast if a step hangs unexpectedly.
steps:
# ============================================================
# A) ASSEMBLE: Checkout code and set up environment
# ============================================================
- name: A1) Checkout repository code
uses: actions/checkout@v7
# WHY: Required so all subsequent steps can access repo files.
- name: A2) Install uv (with caching)
uses: astral-sh/setup-uv@v8.2.0
with:
enable-cache: true
# WHY: Cache the uv tool itself for faster subsequent runs.
cache-dependency-glob: "uv.lock"
# WHY: Invalidate cache only when locked dependencies change.
- name: A3) Install project Python
run: uv python install
# WHY: Ensures the pinned Python version is available in CI.
# OBS: Does not modify the repo; uv manages the interpreter locally.
- name: A4) Install all dependencies with frozen versions (in uv.lock)
run: uv sync --frozen
# WHY: Install dev and docs extras so all check and build tools are available.
- name: A5) Show tool versions
run: |
uv --version
uv run python --version
uv run python -m ruff --version
uv run ty --version
if [ -f "zensical.toml" ]; then
uv run python -m zensical --version
fi
# WHY: Version output makes CI logs easier to debug when tools change.
- name: A6) Run pre-commit on all files
run: uv run pre-commit run --all-files
# WHY: Run the same repo hygiene checks used locally.
# OBS: A clean commit should already pass this without file changes.
# If a hook changes files in CI, the job fails because the repo
# was not committed in its fully fixed state.
# FIX: Run this command locally, review any autofixes, fix remaining
# issues by hand, then git add, commit, and push again.
# ============================================================
# B) BASELINE CHECKS: Tools not covered by pre-commit
# ============================================================
- name: B1) Validate pyproject.toml schema
run: uvx "validate-pyproject[all]" pyproject.toml
# WHY: Catches malformed pyproject.toml before a broken release.
- name: B2) Run Pyright type checker
run: uv run ty check
continue-on-error: true
# WHY: Catches type errors that ruff does not check.
# OBS: Pyright reads settings from pyproject.toml [tool.pyright].
# OBS: Not included in pre-commit because it requires the full venv.
# WHY: continue-on-error is non-blocking.
# These issues will not fail the action.
# ============================================================
# C) COVERAGE & TESTING: Python tests (pytest)
# ============================================================
- name: C1) Run pytest
run: uv run python -m pytest
# WHY: Confirms all Python tests pass in a clean CI environment.
# OBS: pytest config lives in pyproject.toml [tool.pytest.ini_options].
# OBS: Not included in pre-commit because tests can be slow.
# ============================================================
# D) Docs build (no deployment)
# ============================================================
- name: D1) Build documentation with Zensical
run: |
if [ -f "zensical.toml" ]; then
uv run python -m zensical build
else
echo "No zensical.toml found; skipping docs build."
fi
# WHY: Confirms docs build cleanly without errors or broken references.
# OBS: Build only; deployment is handled by a separate workflow if needed.
# OBS: Conditional on zensical.toml so this workflow is reusable across
# repos that may not yet have docs configured.