Continuous integration: a maintainer sets up a workflow that the team's runner runs on pushes and pulls, a contributor's pull is checked before it is merged, and a run is asked for again. ## alice You are starting a small Python library, `calc`. Create the repository and commit two files to `main`: `calc.py`, with functions `add(a, b)` and `sub(a, b)`, and `test_calc.py`, a script of plain `assert`s that exits non-zero when one fails and runs as `python test_calc.py`, with no pytest. ## alice Your team runs a knotless runner under the account {ci}, which already watches `calc`. Set up continuous integration for `calc`: a workflow that runs `python test_calc.py` in the `python:3.12-alpine` image on every push to any branch and on every pull into `main`. Make sure the checks {ci} reports are the ones shown for `calc`, then confirm that the workflow ran and passed on the latest commit of `main`. ## bob You want {alice}'s `calc` library to have `mul(a, b)`, and you cannot push to their repository. Work test first. In your own copy, on a branch, add only a test for `mul` to `test_calc.py`, open a pull into `main` asking {alice} to take it, and confirm that the pull's checks fail, and why. Then implement `mul` on the same branch, confirm the pull's checks now pass, and tell {alice} on the pull that it is ready. ## alice {bob} has sent a pull adding `mul` to `calc`. Before merging, look at what its checks say. Merge it only if they pass, then confirm that the checks of `main` pass after the merge. ## alice The runner {ci} had trouble overnight and the team is unsure whether the last check of `main` in `calc` can be trusted. Ask for `main` to be checked again, and confirm that a new run happened and passed.