OpenTitan uses Azure Pipelines as continuous integration provider: test jobs are described in an Azure Pipelines-specific way, and then executed on compute resources, some of which are provided by Azure Pipelines, and others of which are provided by lowRISC.
Two things are special in the way OpenTitan does continuous integration: private CI, and testing on FPGA boards.
“Private CI” is a term we use for a subset of test jobs which require tighter access control. The primary use case for private CI are tests using proprietary EDA tools, where the license agreement prevents us from testing arbitrary code with it, from showing the configuration or the output in public, etc. We run such test jobs in a separate environment where only OpenTitan project members have access. The test result (pass/fail) is still shared publicly to enable outside contributors to at least get some feedback if their pull request passed our tests.
To test OpenTitan (both the hardware and the software) on FPGAs we have various FPGA boards connected to a machine at lowRISC. Azure Pipelines is configured to schedule test jobs on this machine when FPGA testing is required. The results and logs of these test runs are shown publicly.
OpenTitan CI uses two Azure DevOps projects (which Azure Pipelines is a part of):
All tests are described in a Azure Pipelines-specific YAML syntax. $REPO_TOP/azure-pipelines.yml
is the main configuration file for all public CI jobs. The private CI jobs are described in a separate private repository, lowrisc/opentitan-private-ci, to keep the job descriptions internal for legal reasons.
The YAML schema is part of the Azure Pipelines documentation.
Each test in the YAML file also specifies which type of compute resource it wants to run on. Identical compute resources are grouped into agent pools, and an individual compute resource is called an agent.
For OpenTitan, we have the following agent pools available, which can also be seen in the Azure Pipelines UI:
All pools except for the Azure Pipelines pool are managed by lowRISC IT.
All agents provide ephemeral test environments: the test environment is initialized at the start of a test job and completely destroyed at the end. This is achieved by running tests in Docker containers which are recreated after each run. The base image used for all lowRISC-hosted agent pools is available as lowrisc/container-ci-eda on DockerHub. (The build rules/Dockerfile for this image are lowRISC-internal.)
lowRISC-provided agents run in a Kubernetes cluster on Google Cloud (GCP), where we also define the resources allocated for the individual agents. The agent pools are static in size, i.e. the number of agents doesn't increase and decrease depending on the number of scheduled jobs.
Builds are triggered by GitHub, which sends notifications to Azure Pipelines on a range of events, e.g. the creation of new pull requests, the merge of code into a branch, etc.
The Azure Pipelines scheduler consumes these events and compares them with the configured pipeline triggers in the azure-pipelines.yml
file. It then processes the pipeline description and adds test jobs to the respective agent pool queues, taking test dependencies into account.
After the agent has completed a test job it reports back the result to the Azure Pipelines scheduler, which makes this information (build artifacts and logs) available to users through the web UI.
Azure Pipelines also reports the test status back to GitHub, where it is displayed below a pull request, as marks next to commits, and in various other places.