Continuous Integration#

The UltraZohm project uses two different build pipelines to test the builds of the UltraZohm software as well as the documentation (docs).

  • The Github pipeline (actions) tests and deploys the docs

    • Tests the build of the Sphinx docs

    • Deploys the docs of the main branch to docs.ultrazohm.com

    • Mirrors the branch to ultrazohm/ultrazohm_sw

  • The Drone test pipeline builds UltraZohm Vivado and Vitis projects

    • Builds bitstream in Vivado (only main & develop branch)

    • Commits the Vivado binaries (.xsa) to the repository and pushes the change (only on main)

    • Creates a new tag and a changelog, commits them to the repository and pushes the changes to main

    • Exports the bitstream

    • Generates the Vitis workspace

    • Builds the software

Unit tests (Ceedling)#

  • All unit tests (see Unit tests (Ceedling) are run in the Drone pipeline.

  • If one test fails, the pipeline fails.

Static code check#

We use cppcheck as our static code analyser.

Note

The build pipeline does not fail if there are warnings from the static code analysis!

We check with regular cppcheck and with the extensions for MISRA and CERT rules. MISRA violations can be suppressed on a line-by-line basis, e.g.:

To suppress a MISRA violation, write a comment in the line before the violation // cppcheck-suppress misra-c2012-$rule_number with $rule_number specifying which rule the code violates. After the rule number, add //. and write a regular comment stating why this deviation is justified.

Warning

Do not use this lightly! The only two places we deviate so far (in new code) is the <stdio.h> for testing and read/write from AXI since the latter requires casting.

UltraZohm development container#

To reduce the time the CI steps spend on installing dependencies, we use a docker image for the UltraZohm development container.

Update:

  1. Rebuild the container with VS Code locally (to also run the post-build steps!)

  2. Login to docker.io on the CLI with your credentials (account has to be part of ultrazohm team on Docker Hub):

podman login docker.io
  1. Tag the local image (podman/docker) (the name of the local image may change):

podman image tag localhost/vsc-ultrazohm_sw-ad6053a7600060d35be6bf639d2373c4:latest ultrazohm/ultrazohm_remote_container_new
  1. Push the image to Docker Hub

podman push ultrazohm/ultrazohm_remote_container_new:latest

Drone pipeline (Software)#

  • Drone pipeline builds

  • Uses Drone

  • Drone has a Server and a Runner

  • Drone Server is the bridge between Github, User and Runner (ci.ultrazohm.com)

  • Runner (Docker runner, see Drone docs) polls the server and executes the build pipeline

  • Server and Runner are used as Docker container on the UltraZohm Server

  • Permissions in the OAuth settings of the Github repository must match the drone docs

  • drone/Docker-compose.yml in uz_server_main repository (only visible to admins) sets up Drone

  • Changes in the docker-compose file are automatically transferred to the UltraZohm by using a rsync pipeline

  • ssh to UltraZohm-Server, cd to /drone and use docker-compose up -d to restart the Drone Server and Runner after changes in the repository

How-to:

ssh $username@ultrazohm.com
cd $path/drone
docker-compose up -d

Setup#

        graph BT
    ultrazohm_sw -->|Trigger Pipeline| A
    subgraph UltraZohm-Server
    A[Drone Server] -->|Pending Pipeline| B[Drone Runner]
    B --> C[Execute Pipeline]
    C -->|Report Status| A
    end
    A -->|Report Status| ultrazohm_sw
    

Fig. 21 Setup of the Drone pipeline#

Drone Runner and Vivado Docker image#

The Drone Runner starts a Docker Container for each pipeline step. To use Vivado and Vitis, we use a custom Vivado docker image (vivado:2020.1). There are two challenges with using Vivado and Vitis in a Docker container.

  • Xilinx license is locked to the MAC

  • Create license on xilinx.com/getlicense

  • Lock the license to the MAC of the machine that executes the runner

  • The UltraZohm-Server license is locked to the Docker network drone_default (see docker network ls and docker network inspect host)

  • Download the .lic file

  • Follow the instructions in uz_server_drone repository (only for admins due to licensing & login information)

  • Make the network adapter that is used for the license MAC-lock to the Drone Runner

  • See https://docs.drone.io/runner/docker/configuration/reference/drone-runner-networks/

  • E.g. DRONE_RUNNER_NETWORKS=drone_default

See the docker-compose file for details (drone/docker-compose.yml, only for admins due to login information in the file). Following is an example docker-compose file without login information. Note that the indentation is relevant since this is a yml file. Furthermore, some configuration is specific to the UltraZohm-Server.

Push back to repository#

The drone pipeline pushes back to the ultrazohm/ultrazohm_sw repository on GitHub if a commit is made to main (through a pull request). Both the binary and changelog push steps use the Drone repository secret drone-ci-push-to-uzsw. Set this secret to a fine-grained GitHub personal access token scoped to ultrazohm/ultrazohm_sw with Contents: read and write permission. Leave Allow Pull Requests disabled for the secret; the publishing steps run only for push events on main. A command-scoped credential helper supplies the token to Git and Git LFS without putting it in the remote URL. No separate username secret is required. The account must be allowed to push the generated commits to main and create tags.

The pipeline:

  • commits all binarys to the repo

  • Creates a tag using autotag

  • Settings for the tag: conventional commits

  • Pushes back to main using https

  • Creates CHANGELOG.md by using auto-changelog

  • Commits the changelog

  • Pushes back to main using https

  • The tag is on the commit of the binarys, the CHANLOG.md is one commit after the tag

  • Commit message is fixed and starts with [skip ci] to prevent infinite CI loop