prose changes to /activate #984
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
| name: CI | |
| # Default behavior, on every push to master and every pull request: build the | |
| # static site, and (on master) publish it to GitHub Pages. That is all that runs | |
| # by default, because the full example/test/type/lint suite is already run on the | |
| # local machine before pushing, and GitHub Actions can be slow. | |
| # | |
| # The full gates (examples match the Markdown, every example runs clean, pytest | |
| # passes, ty-clean, ruff-clean) are opt-in, as are the prose checks (codespell | |
| # spelling and Vale house style). Run them only when you want a second opinion | |
| # in CI, in either of two ways: | |
| # * From the Actions tab, choose this workflow and click "Run workflow" | |
| # (the "run_gates" input defaults to true), or run | |
| # gh workflow run ci.yml -f run_gates=true | |
| # * Include the marker [full-ci] anywhere in a push commit message. | |
| # | |
| # Tooling is managed by uv. | |
| on: | |
| push: | |
| branches: [master] | |
| pull_request: | |
| workflow_dispatch: | |
| inputs: | |
| run_gates: | |
| description: "Run the full gates plus the spelling/house-style checks" | |
| type: boolean | |
| default: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| # Default work: build the static site. Fast, because it skips running the | |
| # examples, type-checking, and linting. On a push to master it hands the | |
| # built site to the deploy job below. | |
| site: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v6 | |
| with: | |
| python-version: "3.15" | |
| enable-cache: true | |
| - name: Install pandoc | |
| run: sudo apt-get update && sudo apt-get install -y pandoc | |
| - name: Install tooling | |
| run: uv sync --locked | |
| - name: Build the static site | |
| run: uv run python tools/build_site.py | |
| # On master only, hand the built site to the deploy job below. | |
| - name: Upload Pages artifact | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/master' | |
| uses: actions/upload-pages-artifact@v3 | |
| with: | |
| path: build/site | |
| # The full gates, opt-in only (manual dispatch with run_gates=true, or a push | |
| # commit message containing [full-ci]). These run on the local machine on | |
| # every change, so they are not part of the default CI path. | |
| gates: | |
| if: >- | |
| (github.event_name == 'workflow_dispatch' && inputs.run_gates) || | |
| (github.event_name == 'push' && | |
| contains(github.event.head_commit.message, '[full-ci]')) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v6 | |
| with: | |
| python-version: "3.15" | |
| enable-cache: true | |
| - name: Install pandoc | |
| run: sudo apt-get update && sudo apt-get install -y pandoc | |
| - name: Install tooling | |
| run: uv sync --locked | |
| # Hard gate: the book's code blocks must match the committed Examples/ | |
| # tree (no drift, no conflicting duplicates). | |
| - name: Check examples match the Markdown | |
| run: uv run python tools/extract_examples.py | |
| - name: Extract examples for running | |
| run: uv run python tools/extract_examples.py --write | |
| # Hard gate: every extracted example must run cleanly (the book is fully | |
| # modernized, so the baseline is empty; use --baseline to gate only | |
| # regressions during future bulk work). | |
| - name: Run examples | |
| run: uv run python tools/run_examples.py | |
| # Hard gate: the book's pytest examples (test_*.py) must pass. | |
| - name: Run the book's pytest examples | |
| run: uv run pytest build/examples | |
| # Hard gate: the examples must stay ty-clean (zero diagnostics). | |
| - name: Type-check examples with ty | |
| run: uv run ty check build/examples | |
| # Hard gate: PEP 8 lint (naming, imports, modernization) must pass. | |
| # See pyproject [tool.ruff]; deliberate exceptions live in | |
| # per-file-ignores. | |
| - name: Lint examples with ruff | |
| run: uv run ruff check build/examples | |
| # The same five checks, applied to Solutions/ (worked exercise | |
| # answers), which go through a parallel extract/validate/ty/ruff/pytest | |
| # pipeline (tools/extract_solutions.py). See tools/README.md. | |
| - name: Check solutions match Solutions/*.md | |
| run: uv run python tools/extract_solutions.py | |
| - name: Extract solutions for running | |
| run: uv run python tools/extract_solutions.py --write | |
| - name: Verify solutions #: output markers | |
| run: uv run python tools/validate_output.py --tree "$GITHUB_WORKSPACE/build/solutions" Solutions | |
| - name: Type-check solutions with ty | |
| run: uv run ty check build/solutions | |
| - name: Lint solutions with ruff | |
| run: uv run ruff check build/solutions | |
| - name: Run the solutions' pytest examples | |
| run: uv run pytest build/solutions | |
| # Prose checks, opt-in only (same trigger as the gates job). codespell fails | |
| # on spelling errors; Vale fails on em-dashes (an error-level rule) and prints | |
| # the warning-level house-style findings. These also run locally via | |
| # `make spell` and `make prose`. | |
| prose: | |
| if: >- | |
| (github.event_name == 'workflow_dispatch' && inputs.run_gates) || | |
| (github.event_name == 'push' && | |
| contains(github.event.head_commit.message, '[full-ci]')) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v6 | |
| with: | |
| python-version: "3.15" | |
| enable-cache: true | |
| # Spelling: codespell is a uv-managed dev tool. Config lives in | |
| # pyproject [tool.codespell]; the ignore list in tools/data/codespell-ignore.txt. | |
| - name: Install tooling | |
| run: uv sync --locked | |
| - name: Spell-check prose with codespell | |
| run: uv run codespell Chapters | |
| # Vale is a standalone binary, not a Python package. Install the latest | |
| # release; pin "version" below if you want fully reproducible runs. | |
| - name: Install Vale | |
| run: | | |
| version=$(curl -fsSL https://api.github.com/repos/errata-ai/vale/releases/latest | grep -oP '"tag_name": "v\K[^"]+') | |
| curl -fsSL "https://github.com/errata-ai/vale/releases/download/v${version}/vale_${version}_Linux_64-bit.tar.gz" | sudo tar -xz -C /usr/local/bin vale | |
| vale --version | |
| # Download the third-party styles referenced in .vale.ini (write-good, | |
| # proselint). They are not committed, so CI fetches them each run. | |
| - name: Sync Vale packages | |
| run: vale sync | |
| # House style: fails on em-dashes (error level); filler findings are | |
| # warnings and do not fail the job. Config in .vale.ini. | |
| - name: House-style lint with Vale | |
| run: vale Chapters | |
| # Publishes the site to GitHub Pages (bruceeckel.github.io/ThinkingInPython) | |
| # on a push to master. It depends only on the site build, not on the opt-in | |
| # gates, so publishing is not blocked by them. | |
| deploy: | |
| needs: site | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/master' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| pages: write | |
| id-token: write | |
| environment: | |
| name: github-pages | |
| url: ${{ steps.deploy.outputs.page_url }} | |
| concurrency: | |
| group: pages | |
| cancel-in-progress: true | |
| steps: | |
| - name: Deploy to GitHub Pages | |
| id: deploy | |
| uses: actions/deploy-pages@v4 |