Read a workflow file and expand its matrix
PyYAML parses the workflow text. Add "3.14" to the version list and run again to see a fourth job appear.
Checks that depend on people remembering them get forgotten. A pre-commit hook runs formatting and linting before every commit, and a GitHub Actions workflow runs tests, lint and type checks on every push, on several Python versions, before code can merge.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 6 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Write a .pre-commit-config.yaml that runs the Ruff lint and format hooks plus the standard trailing-whitespace hook, and parse it with PyYAML to print the hook ids.
Write a workflow jobs section as a Python string with a test job and a matrix of two operating systems and two Python versions, and print how many jobs the matrix produces.
Write a function run_pipeline(checks) that runs named checks in order, stops at the first failure and returns the exit code.
Explain it without notes
What is a pre-commit hook, and why is it not enough on its own?
Walk through a GitHub Actions workflow for a Python project.
What is a build matrix and when do you use it?
Why should CI tests for an AI application not call the real model?
How do you make CI results mandatory for merging?
Expected output
workflow name: ci
jobs: ['test', 'lint']
test: 3 steps
- actions/checkout@v4
- astral-sh/setup-uv@v6
- uv run --python ${{ matrix.python-version }} pytest
lint: 4 steps
- actions/checkout@v4
- astral-sh/setup-uv@v6
- uv run ruff check .
- uv run ruff format --check .
one test job will run with python 3.11
one test job will run with python 3.12
one test job will run with python 3.13