uno
is set up with a CI/CD development workflow that automatically generate
new releases whenever new commits or tags are pushed to the repository.
The workflow requires for all contributions to be made via a pull request to the main development branch.
A new "nightly" release is automatically triggered whenever commits are pushed
to the main development branch (master
).
A new "stable" release is triggered whenever a tag is pushed to the repository.
The release process consists of the following steps:
-
Build a multi-platform Docker image from the referenced commit, and push it as private Package
mentalsmash/uno-dev:<tag>
to GitHub's Container registry. -
Test the image by using it to run
uno
's full test suite on each target platform. -
Re-tag the image as
mentalsmash/uno:<tag>
and push it to both Docker Hub (as a public image), and to GitHub (as an "internal" Package for the mentalsmash organization). -
Update the "release badges" published in the README.
The <tag>
used by the generated image depends on the type of release:
Event | Release Type | Image Tag |
---|---|---|
push tag without a / in the name |
stable | latest |
push commit to master |
nightly | nightly |
New commits can only be merged to the main development branch via pull request. In order for a pull request to be accepted it must pass all required checks:
-
At least one maintainer must have reviewed and approved the changes.
-
The changes must pass both the "basic" and "full" validation suites.
A "basic" validation will be triggered as soon as a non-draft pull request is opened. If a pull request is opened as draft, the build will be triggered once the PR is "ready for review". Every new commit pushed to the PR branch after that will:
-
Invalidate any approval that the PR received before the push.
-
Cancel (if already in progress) and trigger a new "basic" build.
The "full" validation will be triggered every time the PR transitions into "accepted" state.
Each validation workflow will target one or more platforms, and for each configuration it will:
-
Build a test Docker image for the selected platform.
-
Run
uno
's full test suite.
The difference between the two validation workflows lies only in the number of "flavors" and platforms that they test:
Build Type | amd64 | arm64 |
---|---|---|
basic | ✅ | ❌ |
full | ❌ | ✅ |
uno
uses ruff to automatically enforce a consistent
coding style.
The tool is installed with the dev
dependency group, and it is run automatically
before every git
commit. You can also run the checks manually:
# Enable virtual environment
. .venv/bin/activate
# Run git hooks (both linter and formatter)
pre-commit run --all
# Only linter
ruff check
# Only formatter
ruff format
-
Install the
venv
module:sudo apt-get install -y python3-venv
-
Clone
uno
's repository:git clone --recurse-submodules https://github.com/mentalsmash/uno
-
Create a virtual environment:
cd uno python3 -m venv .venv
-
(Optional) Make sure
pip
andsetuptools
are up to date:.venv/bin/pip install -U pip setuptools
-
Install
uno
and its dependencies:.venv/bin/pip install -e .
-
Install
git
commit hooks:.venv/bin/pre-commit install
uno
includes a configuration file for a devcontainer,
which can be used to spin up a development environment using Codespaces,
(and some of the free hours that most accounts receive from GitHub).
By default, uno
uses RTI Connext DDS to implement a "synchronization databus" between
its agents. A valid RTI license file must be provided via the RTI_LICENSE_FILE
environment variable.
You can request a free evaluation license from RTI.
If you don't have/don't want to get a free license from RTI, you can still use uno
but the agent functionality
will not be available, and the UVN will need to be reconfigured by hand.
uno
includes a Docker Compose file that can be used to build the development image
required to run integration tests.
The image also supports mounting the local copy of the uno
package for testing.
-
Build the image (
mentalsmash/uno-test-runner:latest
) with:cd uno/ docker compose build test-runner
-
Use it to run the unit tests without having to install
uno
's system dependenciesdocker run --rm -v $(pwd):/uno -w /uno \ mentalsmash/uno-test-runner:latest \ pytest -s -v test/unit
-
Use it (implicitly) to run the integration tests:
DEV=y pytest -s -v test/integration
The
DEV
variable tells the integration test framework to mount theuno
package from the host to test changes made to it after building the image. If unspecified, the image will use the version ofuno
installed during build.For increased logging verbosity try:
VERBOSITY=debug DEBUG=y DEV=y pytest -s -v test/integration
To persist the test directories created by each experiment after the tester terminates:
TEST_DIR=/tmp/uno-test DEV=y pytest -s -v test/integration
-
You can also build a test "release" image (
mentalsmash/uno:dev
) with:docker compose build uno
NOTE: this image does not install
uno
in "editable" mode and henve it will not pick up a local copy mounted as a volume.
The arm64
image can be built locally using QEMU, but running tests with it is not recommended
because of the crawling speed at which emulated instructions run.
Instead, uno
CI/CD infrastructure includes arm64
runners that can run the tests natively.
The tests are automatically triggered during every release, and for every "full" PR validation.
Nevertheless, it can be useful to test building the release image locally, which can be achieved with:
docker compose build uno-arm64
If you really want to test the local copy of uno
on an emulated arm64
container, you
can build an arm64
"test runner" with:
docker compose build test-runner-arm64
WARNING: in order to use these commands, you might have to enable QEMU emulation using the tonistiigi/binfmt image:
docker run --privileged --rm tonistiigi/binfmt --install all
If you enounter any emulation problems while using this image (e.g. QEMU segfaults), you can try replacing it with multiarch/qemu-user-static:
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes -c yes