Python PR Builds¶
This action defines how PRs that affect the Python code should be evaluated. At a high level it performs the following checks:
Builds and tests the code against each supported platform / version of Python
Produces a wheel and an sdist and makes them available as a build artifact.
Builds the documentation and makes it available as a build artifact.
Reports code coverage.
Triggers¶
Currently this action is triggered by any PR that is opened against the
develop
or master
branches, unless the changes only affect
the blog.
on:
push:
branches:
- develop
paths:
- 'arlunio/**'
- 'docs/using/tutorial/**'
- 'tests/**'
- 'setup.py'
- 'pyproject.toml'
- 'MANIFEST.in'
pull_request:
branches:
- develop
- master
paths:
- 'arlunio/**'
- 'docs/using/tutorial/**'
- 'tests/**'
- 'setup.py'
- 'pyproject.toml'
- 'MANIFEST.in'
Jobs¶
To ensure that a PR doesn’t introduce any breaking changes we need to run the
test suite against each supported platform and python version. To do this we
make use of the matrix
strategy which spawns a job for each combination
of os
and python-version
test:
name: Test ${{ matrix.python-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: [3.7, 3.8]
os: [ubuntu-latest] # TODO: Enable windows-latest, macOS-latest
Steps¶
With the preliminaries out of the way, time to focus on the actual work this action performs.
Setup¶
- uses: actions/checkout@v1
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
- name: Setup Environment
run: |
python --version
python -m pip install --upgrade pip
python -m pip install --upgrade tox
The first few steps handle checking out the code, setting up Python and ensuring the tools we need to run the tests are available.
Dev Version Number¶
Note
Since we only publish one distribution these steps only run on the latest version of python.
- name: Get Version Number
run: |
build=$(echo $GITHUB_REF | sed -E 's/.*\/([0-9]+)\/.*/\1/')
echo "ref: $GITHUB_REF"
echo "Build number is $build"
echo "::set-env name=BUILD_NUMBER::$build"
echo "::set-output name=BUILD_NUMBER::$build"
if: matrix.python-version == '3.7' && github.event_name == 'pull_request'
- name: Set Version Number
shell: bash
run : |
sed -i 's/"\(.*\)"/"\1dev'"${BUILD_NUMBER}"'"/' arlunio/_version.py
cat arlunio/_version.py
if: matrix.python-version == '3.7' && github.event_name == 'pull_request'
So that we have the option of trying out the changes introduced by a PR locally
before accepting it we package up the python code into a wheel and make
it available as a build artifact. To ensure that these development builds are
not confused with a beta or real release we adjust the version number to
include a dev<BUILD_NUMBER>
suffix.
However unlike beta builds we cannot make use of the einaregilsson/build-number action for PR builds to generate a build number for us. This is due to it requiring access to the GitHub API token which is unavailable for any build originating from a fork of the main repository.
Instead we choose the PR number as the build number which we can obtain using a
carefully crafted sed
command and the GITHUB_REF
environment
variable. Then we make an environment variable BUILD_NUMBER
available
which can be referenced by later steps in the job.
Finally using another carefully crafted sed
command in the next step we
rewrite the version number in the arlunio/_version.py
file so that it
contains the dev<BUILD_NUMBER>
suffix.
Tox¶
- name: 'Tox: Run Tests'
shell: bash
run: |
tox -e py`echo ${{ matrix.python-version }} | tr -d .`
- name: 'Tox: Build Pkg'
run: |
tox -e pkg
ls dist
if: matrix.python-version == '3.7' && github.event_name == 'pull_request'
Time for the main event, we use tox to run all our tests including the doctests defined in the documentation and the codebase as well as a code coverage report. Additionally for the latest version of Python we package the code and build the docs in preparation for them to be uploaded as build artifacts.
Publish Results¶
- name: 'Publish Pkg'
uses: actions/upload-artifact@v1.0.0
with:
name: 'pkg'
path: dist
if: matrix.python-version == '3.7' && github.event_name == 'pull_request'
- name: 'Report Code Coverage'
uses: codecov/codecov-action@v1
with:
name: "${{ matrix.os }}-${{ matrix.python-version }}"
flags: unittests
Finally we publish all the artifacts generated during the course of the build along with uploading our code coverage report to codecov