Executing Github Actions on a schedule
Introduction
Setting up CI/CD on your application/package repository is really helpful and as a developer you can have different usecases in which you would like to perform your tests.
Tests will be usually performed once you try to merge your MR / pull request into your main branch, but this may not be the only case when you’d like to perform a test.
For example, when you’re using external API’s, breaking changes may occur and this can cause your main branch (or tagged version) to break while you haven’t changed a thing…
In this snippet I’d like to show you how you can trigger an action on github, which will test your code and report your test coverage on set intervals of time.
Automating this can be helpful when you’re not actively working on a project, but still want to be notified when one of your tests fail. This may indicate you need to fix something.
Cron
Triggering a script or job can be done using cron
, which is a time-based job scheduler for Unix operating systems. Part of setting up a cron job, is creating the right cron expression (schedule).
I will not go into detail, but a cron expression is a string made of 5 (or optionally 6) fields, separated by whitespace which represent a set of times.
The 5 field format used is as follows: minute hour day_of_month month day_of_week
.
The allowed values per field are:
- Minute: 0-59
- Hour: 0-23
- Day of month: 1-31
- Month: 1-12 or JAN-DEC
- Day of week: 0-6 or SUN-SAT
- Year: 1970-2099 (optional 6th field)
You can use star expressions to indicate any value (*
), a /
will indicate a step value and -
indicates a range of values and finally a ,
is a list separator.
In my usecase, I would like to schedule my tests to be performed every 6th hour on all days of the week, meaning they will run at 06:00, 12:00, 18:00 and 24:00.
The expression I will use is thus: 0 */6 * * *
. A helpful website to check your cron expression is crontab guru.
Now we have made our schedule, it’s time to setup a Github Actions workflow on this schedule.
Running a Github Actions workflow on a cron schedule
On your Github repository, navigate to Actions
and create a new workflow. You can also add a folder in your repository called: .github/workflows
and the .yml definition in that folder.
At the start of this file we define the name of the workflow, together with the schedule:
name: Scheduled tests
on:
schedule:
- cron: '0 */6 * * *' # Runs every 6th hour
This is essential, everything we define from now on, is what will be executed at these times. Let’s start with setting up Python and install our dependencies.
Note that I am using a requirements.txt
file and I’m installing pytest
, pytest-cov
and coverage
separately.
name: Scheduled tests
on:
schedule:
- cron: '0 */6 * * *' # Runs every 6th hour
jobs:
build:
name: Scheduled tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: 3.11
- name: Install dependencies
run: |
pip install pytest pytest-cov coverage
pip install -r requirements.txt
Now, we will run our tests and create a coverage file, which also handily reports how much of our code is being tested and reports this. Therefore we add the following:
- name: Run tests
run: python -m unittest discover -b --start-directory ./tests
- name: Build coverage file
run: |
pytest --cov=bro --cov-config=.coveragerc --junitxml=report.xml --cov-report=html:html/test-coverage-results
coverage report --skip-covered || true
The first command of the previous block pytest --cov=bro --cov-config=.coveragerc --junitxml=report.xml --cov-report=html:html/test-coverage-results
creates a html report with the coverage report (a nice extra). We can make this available as an artifact in the repository, therefore we add the following:
- name: Archive code coverage results
uses: actions/upload-artifact@v3
with:
name: coverage-results
path: html/test-coverage-results
if: ${{ always() }}
- name: Download coverage results
uses: actions/download-artifact@v3
with:
name: coverage-results
Now, add the full workflow file to your main branch in the repository and your tests + coverage report will be executed and built automatically on your defined schedule.