Skip to content

Build and Test

Build and Test #25

name: Build and Test
# Builds and tests on all combinations of OS and python version.
# Also builds the docs.
#
# Runs when a pull request is opened or updated.
#
# Can also be run manually for debugging purposes.
on:
pull_request_target:
types: [opened, synchronize, reopened]
workflow_dispatch:
inputs:
ref:
description: "The ref to build and test."
required: false
schedule:
# Run every night at midnight PST / 8am UTC, testing against the main branch.
- cron: '0 8 * * *'
defaults:
run:
shell: bash
# If another instance of this workflow is started for the same PR, cancel the
# old one. If a PR is updated and a new test run is started, the old test run
# will be cancelled automatically to conserve resources.
concurrency:
group: ${{ github.workflow }}-${{ github.event.number || inputs.ref }}
cancel-in-progress: true
jobs:
# Configure the build matrix based on repo variables. The list of objects in
# the build matrix contents can't be changed by conditionals, but it can be
# computed by another job and deserialized. This uses
# vars.ENABLE_SELF_HOSTED to determine the build matrix, based on the
# metadata in build-matrix.json.
matrix_config:
runs-on: ubuntu-latest
outputs:
MATRIX: ${{ steps.configure.outputs.MATRIX }}
steps:
- uses: actions/checkout@v4
with:
path: repo-src
ref: ${{ inputs.ref || (github.event.number && format('refs/pull/{0}/merge', github.event.number)) }}
- name: Configure Build Matrix
id: configure
shell: node {0}
run: |
const fs = require('fs');
const enableDebug = "${{ vars.ENABLE_DEBUG }}" != '';
const enableSelfHosted = "${{ vars.ENABLE_SELF_HOSTED }}" != '';
// Use ENABLE_SELF_HOSTED to decide what the build matrix below
// should include.
const {hosted, selfHosted, pythonVersions} = require("${{ github.workspace }}/repo-src/build-matrix.json");
const devices = enableSelfHosted ? hosted.concat(selfHosted) : hosted;
const matrix = [];
for (const device of devices) {
for (const version of pythonVersions) {
// Clone device, add "python" field, push onto the matrix.
matrix.push(Object.assign({}, device, {python_version: version}));
}
}
// Output a JSON object consumed by the build matrix below.
fs.appendFileSync(
process.env['GITHUB_OUTPUT'],
`MATRIX=${ JSON.stringify(matrix) }\n`);
// Output the debug flag directly.
fs.appendFileSync(
process.env['GITHUB_OUTPUT'],
`ENABLE_DEBUG=${ enableDebug }\n`);
// Log the outputs, for the sake of debugging this script.
console.log({enableDebug, enableSelfHosted, matrix});
build_and_test:
needs: matrix_config
strategy:
# Let other matrix entries complete, so we have all results on failure
# instead of just the first failure.
fail-fast: false
matrix:
include: ${{ fromJSON(needs.matrix_config.outputs.MATRIX) }}
name: Build and test ${{ matrix.os_name }} ${{ matrix.target_arch }} Python ${{ matrix.python_version }}
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ inputs.ref || (github.event.number && format('refs/pull/{0}/merge', github.event.number)) }}
- name: Set Python version
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python_version }}
- name: Debug Python version
run: python3 --version
- name: Install Linux deps
if: runner.os == 'Linux'
run: |
sudo apt -y install \
libva2 libva-drm2 \
nodejs npm xvfb
- name: Install Python deps
run: |
python3 -m pip install -r requirements.txt
python3 -m pip install -r optional_requirements.txt
- name: Download binaries
run: |
# Fetch binaries locally instead of installing the release version of
# the binary package. This lets us test changes to the binary package
# before it is released.
# In case of network flake, try it three times. This is arbitrary.
python3 binaries/build_wheels.py || python3 binaries/build_wheels.py || python3 binaries/build_wheels.py
if [[ '${{ runner.os }}' == 'Windows' ]]; then
echo "PYTHONPATH=$GITHUB_WORKSPACE\\binaries;$PYTHONPATH" >> $GITHUB_ENV
else
echo "PYTHONPATH=$GITHUB_WORKSPACE/binaries:$PYTHONPATH" >> $GITHUB_ENV
fi
- name: Build docs (Linux only)
run: bash docs/build.sh
if: runner.os == 'Linux'
- name: Run tests
run: |
if [[ '${{ runner.os }}' == 'Linux' ]]; then
# Run without X11 on Linux by using xvfb.
WRAPPER="xvfb-run -a"
else
WRAPPER=""
fi
# Use the "spec" reporter for clearer logs in GitHub Actions
$WRAPPER python3 run_end_to_end_tests.py --reporters spec
- name: Debug on failure
uses: mxschmitt/[email protected]
with:
limit-access-to-actor: true
if: failure() && vars.ENABLE_DEBUG != ''