Catch a Python Bug Before It Ships
Run your tests against Python 3.15 RC in a GitHub Actions matrix build.
Introduction
30 Second Summary
A new version of Python arrives every year, and every year some code that worked fine on the old version quietly breaks on the new one. Right now Python 3.15 is still a release candidate, so the problems in it are there for anyone to find.
In this project, you will write a small Python package with its own test suite, then run that suite against two Python versions at once inside GitHub Actions. If the release candidate breaks your code, you see it in a red job before the final release ships.
What You'll Build
You push one commit and watch two test jobs run side by side in your repository's Actions tab, one for the Python everyone uses today and one for the version that is not out yet.
By the end of this project, you'll have:
- A public repository on GitHub holding a few Python functions and a test file you can run locally in one command.
- A matrix workflow that tests your code on Python 3.14 and Python 3.15 at the same time, so a single push tells you whether the next release breaks you.
- A red job you caused on purpose, where the release candidate fails a test that the current Python passes, and a fix that turns the whole matrix green again.
- Secret Mission: An optional challenge to push your skills further.
Are there any prerequisites?
You need a GitHub account and enough Python to write a function and a test for it. Everything else runs on GitHub's own machines, and Actions minutes on a public repository cost nothing.
Before We Start
Before we dive in, let's lock in what you're about to build and why it matters. Python 3.15 is still a release candidate, so a bug you catch now is a bug that never reaches the final release.
Write Your Functions and Tests
Python 3.15 is in its release candidate phase. The code is frozen apart from clear bug fixes, so anyone who runs real code against it can still catch a problem before the final release.
To catch anything, you need code worth running. In this step you build a tiny Python module with a matching test suite, and park it in a public repository that GitHub Actions can reach later.
In this step, get ready to:
- Create a public GitHub repository called python-rc-bug-hunter and clone it to your machine.
- Write a calculator.py module with three small functions.
- Write matching pytest tests and watch them pass locally.
Create your repository on GitHub
GitHub Actions only runs on code that lives on GitHub. Your repository is the home your test suite needs before any workflow can pick it up.
- In your browser, go to github.com/new.
- Enter python-rc-bug-hunter in the Repository name field.
- Select Public for the visibility.
- Tick Add a README file.
- Click Create repository.
Why make the repository public?
GitHub Actions minutes on a public repository carry no charge. Every workflow run in this project costs you nothing.
A public repository also means anyone can see the bug you find. That is the whole point of testing a release candidate in the open.
- Move into your empty project folder from earlier by running this command:
cd ~/Desktop/[[PROJECT_FOLDER="your project folder name"]]
- Pull your new repository into that folder by running this command:
git clone https://github.com/[[GITHUB_USERNAME="your GitHub username"]]/python-rc-bug-hunter.git .
- Confirm the clone landed by running this command:
ls
- You should see README.md in the output.
Clone refused to run?
Git will not clone into a folder that already has files in it. Run ls first and clear anything sitting there.
A message about the repository not being found usually means a typo in your username or the repository name. Compare the URL against the address bar on your repository page.
Why won't my git clone command work?
Write your calculator functions
Your test suite needs something to test. Three tiny arithmetic functions are enough to tell you whether a Python version behaves the way you expect.
- In your code editor, click File in the top menu bar.
- Click Open Folder.
- Select your project folder, then click Open.
- In the Explorer sidebar, click the New File icon.
- Name the file calculator.py and press Enter.
- Add your three functions by pasting this into calculator.py:
# Add two numbers together
def add(a, b):
return a + b
# Divide one number by another
def divide(a, b):
return a / b
# Average a list of numbers
def average(numbers):
return sum(numbers) / len(numbers)
What does this code do?
- add and divide are single-line arithmetic, so any change in behaviour points at Python itself rather than at your code.
- average leans on the built-ins sum and len, which gives your suite something beyond raw operators to exercise.
- Save calculator.py.
- Check your functions load by running this command in your terminal:
python3 -c "import calculator; print(calculator.average([2, 4, 6]))"
You should see 4.0 printed in the terminal.
Python can't find your module?
An import error almost always means your terminal is sitting in a different folder. Run ls and check that calculator.py is listed.
On Windows, use python in place of python3.
Why can't Python import my calculator module?
Write and run your tests
A function that works is not the same as a function you can prove works on demand. Your tests are what a new Python version gets measured against later in this project.
- In the Explorer sidebar, click the New File icon again.
- Name the file test_calculator.py and press Enter.
- Add your four tests by pasting this into test_calculator.py:
import pytest
from calculator import add, average, divide
# Each test states one expected result
def test_add():
assert add(2, 3) == 5
def test_divide():
assert divide(10, 4) == 2.5
def test_average():
assert average([2, 4, 6]) == 4
# Dividing by zero should raise, not quietly return a number
def test_divide_by_zero():
with pytest.raises(ZeroDivisionError):
divide(1, 0)
What does this code do?
- Every function starting with test_ is collected and run automatically. That naming rule is how pytest finds your work.
- assert states the result you expect. A test fails the moment reality disagrees with it.
- pytest.raises flips the expectation around. This test only passes if the code inside it blows up in the way you named.
- Save test_calculator.py.
Before you run anything, take a guess. Do you expect all four tests to pass on the Python you have installed, or does one of them look shaky?
- Run your whole suite by running this command:
pytest
You should see a green summary line at the bottom telling you all four tests passed. That green line is the baseline every Python version now has to match.
Pytest collected nothing?
A run that reports zero tests usually means the file name is wrong. Pytest only collects files whose names start with test_.
A command-not-found message means your terminal is not seeing pytest. Check you are in the same terminal where you installed it earlier.
Why is pytest not picking up my test file?
- Stage and commit your two new files by running these commands:
git add calculator.py test_calculator.py
git commit -m "Add calculator functions and tests"
- Send your commit up to GitHub by running this command:
git push
- Refresh your repository page in the browser.
calculator.py and test_calculator.py are now listed next to your README on GitHub.
Push asking for credentials?
Git will prompt for a username and password if it has never authenticated with GitHub on this machine. GitHub expects a personal access token in place of your account password.
How do I authenticate my git push to GitHub?
You have a green test suite living in a public repository. Next up, you hand that suite to GitHub Actions so it runs on every push without you touching the terminal.
Turn On GitHub Actions
Your test suite passes on your machine. That proves one thing only: the code works on your laptop, with your Python, on your operating system.
To test against a Python you have not installed, you need a computer that spins up on demand and runs your suite for you. GitHub Actions gives you that computer, free on public repositories.
In this step you write the file that tells that computer what to do.
In this step, get ready to:
- Create a workflow file inside your repository.
- Tell GitHub Actions to install Python and run your tests on every push.
- Watch your first run finish green in the Actions tab.
Create the workflow file
GitHub Actions looks in exactly one place for instructions: a folder called .github/workflows at the top of your repository. A workflow file anywhere else is just a file.
- Switch back to the terminal where you ran pytest, which is already inside your python-rc-bug-hunter folder.
macOS
- Create the workflow folder and an empty workflow file by running these commands:
mkdir -p .github/workflows
touch .github/workflows/tests.yml
Windows
- Create the workflow folder and an empty workflow file by running these commands in PowerShell:
New-Item -ItemType Directory -Force -Path .github\workflows
New-Item -ItemType File -Path .github\workflows\tests.yml
Linux
- Create the workflow folder and an empty workflow file by running these commands:
mkdir -p .github/workflows
touch .github/workflows/tests.yml
- Confirm the file exists by running this command:
ls .github/workflows
You should see tests.yml in the output.
Nothing in the output?
- Your terminal may be sitting somewhere other than your repository, so move into the python-rc-bug-hunter folder and run the create commands again.
- Check the folder name for a typo. The leading dot in .github is easy to drop.
- Still stuck? Why can't my terminal find the folder I just made?
Write the workflow that runs your tests
A workflow file answers three questions: when to run, which machine to run on, and which commands to run. You write those answers in YAML, where indentation carries the meaning.
- In your code editor, open the empty .github/workflows/tests.yml file.
- Tell GitHub what to run by pasting this into the file:
name: Tests
# Run this workflow every time you push to GitHub
on: push
jobs:
test:
# The machine GitHub spins up for this job
runs-on: ubuntu-latest
steps:
# Copy your repository onto that machine
- uses: actions/checkout@v7
# Install the Python version named below
- uses: actions/setup-python@v7
with:
python-version: "3.14"
- run: pip install pytest
- run: pytest
What does this workflow do?
- on: push is the trigger. Every commit you send to GitHub starts a run.
- runs-on: ubuntu-latest asks for a fresh Linux machine, thrown away after the run.
- actions/checkout@v7 copies your repository onto that machine. Without it the job has nothing to test.
- actions/setup-python@v7 installs whichever Python you name in python-version.
- The last two steps are the two commands you already ran by hand, install pytest and run the suite.
Keep the quotes around the version
The quotes keep 3.14 as text. Without them YAML reads the version as a number, and a version like 3.15 can lose a digit before Actions ever sees it.
- Save .github/workflows/tests.yml.
- Confirm Git can see your new file by running this command in your terminal:
git status
You should see .github/ listed under untracked files.
Git not listing your new file?
- An unsaved file exists only in the editor, so save it and run the command again.
- Your editor may have created the file outside the repository, so check the path reads .github/workflows/tests.yml inside python-rc-bug-hunter.
- Still nothing? Why doesn't git status show my new workflow file?
✔️ Awesome, I've got everything!
Great, double check you've saved your file before you push it.
ⓧ I'd like to double check the full code
Here's the whole workflow file to compare against.
name: Tests
# Run this workflow every time you push to GitHub
on: push
jobs:
test:
# The machine GitHub spins up for this job
runs-on: ubuntu-latest
steps:
# Copy your repository onto that machine
- uses: actions/checkout@v7
# Install the Python version named below
- uses: actions/setup-python@v7
with:
python-version: "3.14"
- run: pip install pytest
- run: pytest
Push the workflow and watch it run
The workflow counts for nothing until GitHub has it. Actions reads workflow files from the repository, never from your laptop.
- Send your workflow to GitHub by running these three commands:
git add .github/workflows/tests.yml
git commit -m "Add test workflow"
git push
Before you open your repository, make a prediction. Does GitHub have a finished run waiting for you, a run still in progress, or nothing at all?
- In the browser where you're signed in to GitHub, return to your python-rc-bug-hunter repository.
- Click the Actions tab at the top of the repository.
You should see a run named Tests, triggered by the commit you just pushed. A yellow dot means it is still working, and a green tick means it finished.
No run on the Actions tab?
- Your push may not have landed, so run the push command again and read the terminal output for an error.
- The file has to sit inside .github/workflows, and the name has to end in .yml.
- Still empty? Why is my Actions tab empty after pushing a workflow?
- Click the Tests run to open it.
- Click the test job to open its log.
The log ends with the same pytest summary you saw in your own terminal, with every test passing.
Why a green run here beats a green run on your laptop
That machine did not exist two minutes ago. It downloaded a clean Python, installed pytest, and ran your suite with none of your local settings or stray packages.
A green tick means your tests pass for someone who is not you.
Your tests now run on a machine that is not yours, against one Python version. Next up, you'll make that same file test two Python versions side by side.
Build a Version Matrix
Last step you handed your test suite to GitHub's machines and watched the job finish green. That green only covers one version of Python though.
GitHub Actions has a build matrix for exactly this. You list the versions once, and Actions runs the whole job again for each one.
In this step, get ready to:
- Turn your single test job into a matrix over two Python versions.
- Push the change and watch two jobs run side by side in the Actions tab.
- Work out why one of those two jobs comes back red.
Add a build matrix to your workflow
- Switch back to your code editor.
- Open .github/workflows/tests.yml.
- Find the runs-on: line inside your job:
jobs:
test:
runs-on: ubuntu-latest
- Add a strategy block underneath it, so your job now reads like this:
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.14', '3.15']
What does the matrix do?
strategy.matrix turns one job definition into several jobs. Actions reads your list of two versions and runs the entire job once per entry.
Both jobs start at the same time on separate machines. Neither one waits for the other.
The version numbers are quoted for a reason. Left bare, YAML reads them as numbers instead of text, and a version like 3.10 reaches the setup step as 3.1.
- Scroll down to the step that sets up Python and find its python-version: line, which right now holds one hard-coded version:
with:
python-version: '3.14'
- Replace that hard-coded version with the matrix value, so the two lines now read:
with:
python-version: ${{ matrix.python-version }}
How each job knows which version to install
Every matrix job gets its own copy of the value from your list. ${{ matrix.python-version }} reads that copy while the job runs.
One job sees 3.14. The other sees 3.15. Same file, two different installs.
✔️ Awesome, I've got everything!
Nice. Your workflow now names both Python versions in a single file.
ⓧ I'd like to double check the full code
Your whole .github/workflows/tests.yml should look like this.
name: Tests
on: push
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.14', '3.15']
steps:
- uses: actions/checkout@v7
- uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}
- run: pip install pytest
- run: pytest
Push the matrix and watch two jobs run
- Save .github/workflows/tests.yml.
- Switch back to your terminal.
- Stage and commit the change by running these commands:
git add .github/workflows/tests.yml
git commit -m "Run tests on a Python version matrix"
- Send the commit to GitHub by running this command:
git push
Before you look at GitHub, how many jobs do you think this push starts, and do you expect all of them to pass?
- Return to your python-rc-bug-hunter repository in the browser.
- Click the Actions tab.
- Click the run at the top of the list.
Two jobs appear in the left sidebar instead of one, each labelled with the version it runs.
The 3.14 job finishes green. The 3.15 job goes red.
Only seeing one job?
- Check that strategy sits at the same indentation as runs-on:, not inside the steps: list.
- Refresh your repository page to confirm your commit actually landed. A new run only appears once the push reaches GitHub.
Why is my matrix only running one job?
Find out why the 3.15 job went red
- Click the red job in the left sidebar.
- Expand the step that sets up Python.
The job never reached your tests. It stopped while trying to install Python 3.15, because that version has no final release yet.
Why the release candidate stays invisible
The setup step serves final, released versions of Python unless you tell it otherwise. Python 3.15 is still a release candidate, so there is nothing final for it to hand over.
A red job here is the expected result. Your matrix is working, and it is asking for something the setup step has not been given permission to fetch.
Your matrix runs, and it is already telling you something useful about the release candidate. Next up, you give the setup step permission to fetch pre-releases and watch that red job pull Python 3.15 down for real.
Install the Release Candidate
Two jobs now run side by side every time you push. That matrix is the machinery that gets your test suite in front of a Python that has not shipped yet.
Which raises a question. Python 3.15 has no stable release, so what exactly did that second job install?
GitHub Actions has an answer for this. In this step you find out what your 3.15 job actually did, then change one line so it reaches for the release candidate.
In this step, get ready to:
- Open the 3.15 job from your last push and see what it did with a version that has not shipped.
- Switch on pre-release installs in your workflow's Python setup step.
- Read the release candidate version out of the 3.15 job log.
Find out what the 3.15 job did
Before you open the log, take a guess. Did the 3.15 job install a Python and run your tests, or did it stop before it got there?
- Go to your python-rc-bug-hunter repository on GitHub.
- Click the Actions tab.
- Click the workflow run at the top of the list.
- Click the job named for Python 3.15.
The 3.15 job never reaches your tests. It stops at the step that sets up Python, and the 3.14 job beside it stays green.
Why 3.15 finds nothing
The setup-python action downloads a build of Python from a published list of versions. By default it only considers finished, stable releases.
Python 3.15 has no stable release yet. The only 3.15 builds in existence are release candidates, and the action walks straight past them.
Can't find the 3.15 job?
The two jobs are listed in the left sidebar of the run page, each labelled with its Python version. If you only see one job, your matrix change from the last step may not have been pushed.
Why does my GitHub Actions run only show one job instead of two?
Switch on pre-release installs
- In your editor, open .github/workflows/tests.yml.
- Find the with: block under the step that uses the actions/setup-python action, which looks like this:
with:
python-version: ${{ matrix.python-version }}
- Add allow-prereleases: true below the python-version line, so the block now looks like this:
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true
What does allow-prereleases do?
It widens the list of builds the action is willing to install. Release candidates, betas and alphas all become fair game.
Your 3.14 job is unaffected. A stable 3.14 exists, and a stable release always wins over a pre-release of the same version.
- Save tests.yml.
- Send the change to GitHub by running these commands:
git add .github/workflows/tests.yml
git commit -m "Allow pre-release Python installs"
git push
One more prediction before you look. Does one line of YAML get the 3.15 job past the setup step, or does it need a version that actually exists?
- Switch back to the Actions tab in your browser.
- Click the new run at the top of the list.
Both jobs now get past Python setup and run pytest. Your tests just ran on a Python that is not out yet.
3.15 job still stopping at setup?
Check that allow-prereleases is indented to line up with python-version, and that both sit under the same with: block.
Check that your matrix still quotes its versions as '3.15'. Unquoted, YAML reads it as a number and truncates it to 3.1.
Why is my setup-python step still failing to find a Python version?
Read the release candidate version in the log
A passing job tells you a Python got installed. The log tells you exactly which build it was.
- Click the job named for Python 3.15.
- Click the step that sets up Python to expand its log.
- Find the line naming the Python version that was downloaded and installed.
Look closely at the digits. The version carries a release candidate marker rather than a finished 3.15.0.
Why that line matters
That is the build the Python core developers published for people to test ahead of the October final release.
Every test you write from here on runs against it. Anything that breaks there is a real report worth filing.
Your pipeline is now pointed at unreleased Python. Next up, you write a test that leans on something the release candidate changed and watch the 3.15 job turn red.
Catch and Fix the Bug
Your workflow now installs the real Python 3.15 release candidate, and you have read the proof in the job log.
Both jobs have stayed green the whole time, which means nothing has actually touched what the new version changed. In this step you give your calculator a feature that Python 3.15 treats differently, then let the matrix tell you about it.
In this step, get ready to:
- Add a function to calculator.py that builds an expression node, plus a test that covers it.
- Push the change and watch the 3.15 job go red while 3.14 stays green.
- Fix the function and get the whole matrix passing again.
Add a function that builds an expression node
Python can hold a piece of code as a tree of objects called an abstract syntax tree. Building those nodes by hand is ordinary tooling work, and it is exactly the kind of code that shifts between versions.
- Return to calculator.py in your editor.
- Give the file access to the tree types by adding this line at the very top of calculator.py, above your existing functions:
import ast
- Give your calculator a way to build an addition node by adding this function at the bottom of calculator.py:
def build_sum_node(left_value, right_value):
# Wrap each plain number so the tree can hold it.
left = ast.Constant(value=left_value)
right = ast.Constant(value=right_value)
# Join the two numbers into a single addition node.
return ast.BinOp(left=left, right=right)
What does this code do?
- ast.Constant wraps a plain number so it can sit inside a tree.
- ast.BinOp is the node type for a binary operation such as addition.
- build_sum_node hands the finished node back so other code can inspect it.
- Save calculator.py.
- Confirm the file still imports cleanly by running your test suite:
pytest
Your existing tests still pass, which proves calculator.py has no syntax errors.
Seeing an import error?
- Check that import ast sits at the very top of the file, not inside a function.
- Check you are running pytest from inside the python-rc-bug-hunter folder.
- Why is pytest failing to import my calculator module?
- Switch back to test_calculator.py in your editor.
- Pull in what the new test needs by adding these lines below the imports already at the top of test_calculator.py:
import ast
from calculator import build_sum_node
- Cover the new function by adding this test at the bottom of test_calculator.py:
def test_build_sum_node_returns_a_binop():
# Build the node from two plain numbers.
node = build_sum_node(3, 4)
# The result should be an addition node, not a bare number.
assert isinstance(node, ast.BinOp)
What does this test check?
- build_sum_node(3, 4) runs your new function with two plain numbers.
- isinstance(node, ast.BinOp) confirms an addition node came back.
- The test says nothing about Python versions. Your workflow is what turns it into a version check.
- Save test_calculator.py.
Before you run anything, do you think this test passes on your local Python 3.14?
- Find out by running your suite again:
pytest
The new test passes. Scroll to the bottom of the output and you will find a warnings summary naming a DeprecationWarning from your new function.
Why a warning and not a failure
Python flags something as deprecated for a release or two before it goes away. On 3.14 your function still works and Python only grumbles about it.
A warning does not fail a test run, so your 3.14 job will stay green. The open question is what the release candidate does with the same code.
No warnings summary at the bottom?
- Check that both files are saved. An unsaved test_calculator.py means the new test never ran.
- Check the test count went up by one compared to your last pytest run.
- Why is pytest not showing me a warnings summary?
Push the change and watch the 3.15 job break
Your laptop only has one Python on it. GitHub Actions is where the second opinion lives.
- Stage both changed files by running this command:
git add calculator.py test_calculator.py
- Record the change by running this command:
git commit -m "Add expression node builder and its test"
- Send it to GitHub by running this command:
git push
Before you look at the run, which of the two jobs do you expect to fail, and what do you think its error will say?
- Switch back to your python-rc-bug-hunter repository in the browser.
- Open the Actions tab.
- Click the run at the top of the list to answer which job broke.
The 3.14 job is green and the 3.15 job is red. You just caught a change in a Python that has not shipped yet.
- Click the red 3.15 job to open its log.
- Expand the step that runs pytest to read the traceback.
The traceback ends in a TypeError on the line where your function builds the addition node.
What changed in the release candidate
In Python 3.15, the constructors of AST nodes raise a TypeError when a required argument is omitted.
The same code raised only a DeprecationWarning on every version since 3.13. That is why your local run looked fine and the matrix did not.
Both jobs still green?
- Check you are looking at the newest run, not the one from the previous step.
- Check your push actually landed by refreshing the repository's file list and opening test_calculator.py on GitHub.
- Why did my new test pass on both Python versions?
Fix the function and get both jobs green
You have found a real difference between two Pythons, and the repair is one argument. This is the exact move a maintainer makes on the morning a release candidate lands.
- Return to calculator.py in your editor.
- Find this line at the bottom of the file:
return ast.BinOp(left=left, right=right)
- Tell the node which operator to use by adding op=ast.Add() between the two arguments, so the line reads:
return ast.BinOp(left=left, op=ast.Add(), right=right)
- Save calculator.py.
- Check the warning is gone by running your suite:
pytest
Your tests pass and the warnings summary at the bottom is gone.
- Stage the fix by running this command:
git add calculator.py
- Record it by running this command:
git commit -m "Pass the operator to the BinOp node"
- Send the fix to GitHub by running this command:
git push
Before you open the run, do you expect both jobs to pass this time, or only the 3.14 one?
- Switch back to the Actions tab in your browser.
- Open the run at the top of the list to see how the matrix ended.
Both jobs are green. Your suite now passes on the Python everyone is using and on the one that is still a candidate.
Still seeing a red 3.15 job?
- Check the run you are viewing is the one from your latest push, not the earlier failing run.
- Check op=ast.Add() sits inside the ast.BinOp call and not on a line of its own.
- Why is my 3.15 job still failing after the fix?
✔️ Awesome, I've got everything!
Great, double check both files are saved and your latest push is the one on the Actions tab.
ⓧ I'd like to double check the full code
Scroll up and confirm each of these is present, in order:
- import ast at the very top of calculator.py.
- build_sum_node at the bottom of calculator.py, with op=ast.Add() inside the ast.BinOp call.
- import ast and from calculator import build_sum_node near the top of test_calculator.py.
- test_build_sum_node_returns_a_binop at the bottom of test_calculator.py.
Secret mission
Turn Your Matrix Into an Early Warning System
Your workflow only wakes up when you push. Real maintainers want to hear about a broken release candidate on a quiet Monday morning, without a red job blocking everyone else's work. Add a schedule, a manual trigger, and a 3.15 job that is allowed to fail.
Clean Up Your Resources
Clean Up Your Resources
Decide whether to keep your workflow running, pause it to come back later, or delete everything entirely. GitHub Actions minutes are free on public repositories, so nothing here costs you money while it sits.
Resources you used:
- Your public GitHub repository python-rc-bug-hunter.
- Your local copy of python-rc-bug-hunter on your Desktop, holding calculator.py, test_calculator.py, and .github/workflows/tests.yml.
- The pytest package you installed locally with pip.
Keep everything running
No action needed. Choose this if you're still actively building on python-rc-bug-hunter or want the matrix to run on every push.
- Leave the repository public so your workflow keeps running at no cost.
- Reuse .github/workflows/tests.yml in another Python project you own.
Your local clone and the pytest package stay on your machine until you remove them.
Pause - I'll come back to this later
Stop the workflow from running on every push, and keep every file exactly where it is.
- Open your python-rc-bug-hunter repository on GitHub.
- Click the Actions tab.
- Select your workflow in the left sidebar.
- Open the ... menu on the right of the workflow name.
- Click Disable workflow.
Pushes still land on main. No jobs run until you enable the workflow again from the same menu.
Delete - I don't want to use this again
Remove the repository from GitHub, then remove the project folder and test runner from your machine.
- Open your python-rc-bug-hunter repository on GitHub.
- Click the Settings tab.
- Scroll to the Danger Zone at the bottom of the General page.
- Click Delete this repository.
- Type the repository name when GitHub asks you to confirm, then confirm the deletion.
- Delete your local copy by running this command on macOS or Linux:
rm -rf ~/Desktop/python-rc-bug-hunter
- Delete your local copy by running this command on Windows:
rmdir /s /q %USERPROFILE%\Desktop\python-rc-bug-hunter
- Remove the pytest package by running this command:
pip uninstall pytest
- Enter y when pip asks you to confirm the removal.
- Confirm the folder is gone by running ls on your Desktop.
Nice Work!
Nice Work!
Nice work! You've built a GitHub Actions matrix that tests your Python package against a released version and a release candidate at the same time.
You also watched a real version-specific failure show up in python-rc-bug-hunter and fixed it before the new Python ever shipped.
You've learned how to:
- Write a small Python package in calculator.py and cover it with pytest tests that run locally and in CI.
- Run one test suite against two Python versions at once using a matrix workflow in .github/workflows/tests.yml.
- Install a release candidate in CI with allow-prereleases: true, then read the job log to confirm which build actually ran.
- Take on the Secret Mission and push your workflow further with an optional challenge.
Ready to quiz yourself?