Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/ros-tooling/action-ros-ci
Github Action to build and test ROS 2 packages using colcon
https://github.com/ros-tooling/action-ros-ci
ci colcon ros2 testing
Last synced: 3 months ago
JSON representation
Github Action to build and test ROS 2 packages using colcon
- Host: GitHub
- URL: https://github.com/ros-tooling/action-ros-ci
- Owner: ros-tooling
- License: apache-2.0
- Created: 2019-10-18T01:54:46.000Z (about 5 years ago)
- Default Branch: master
- Last Pushed: 2024-07-29T15:28:51.000Z (3 months ago)
- Last Synced: 2024-07-29T20:58:32.071Z (3 months ago)
- Topics: ci, colcon, ros2, testing
- Language: TypeScript
- Homepage:
- Size: 24.5 MB
- Stars: 141
- Watchers: 15
- Forks: 52
- Open Issues: 37
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
- awesome-robotic-tooling - action-ros-ci - GitHub Action to build and test ROS 2 packages using colcon. (Development Environment / Unit and Integration Test)
README
# `action-ros-ci`
[![GitHub Action Status](https://github.com/ros-tooling/action-ros-ci/workflows/Test%20action-ros-ci/badge.svg)](https://github.com/ros-tooling/action-ros-ci)
[![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=ros-tooling/action-ros-ci)](https://dependabot.com)
[![codecov](https://codecov.io/gh/ros-tooling/action-ros-ci/branch/master/graph/badge.svg)](https://codecov.io/gh/ros-tooling/action-ros-ci)This action builds and tests a [ROS](http://wiki.ros.org/) or [ROS 2](https://docs.ros.org/en/rolling/) workspace from source.
1. [Requirements](#Requirements)
1. [Overview](#Overview)
1. [Action Output](#Action-Output)
1. [Usage](#Usage)
1. [Build and run tests for your ROS 2 package](#Build-and-run-tests-for-your-ROS-2-package)
1. [Build with a custom `repos` or `rosinstall` file](#Build-with-a-custom-repos-or-rosinstall-file)
1. [Build a ROS 1 workspace](#Build-a-ROS-1-workspace)
1. [Skip tests](#Skip-tests)
1. [Use a `colcon` `defaults.yaml` file](#Use-a-colcon-defaultsyaml-file)
1. [Do not use `--symlink-install` when building](#Do-not-use---symlink-install-when-building)
1. [Enable Address Sanitizer to automatically report memory issues](#Enable-Address-Sanitizer-to-automatically-report-memory-issues)
1. [Generate and process code coverage data](#Generate-and-process-code-coverage-data)
1. [Store `colcon` logs as build artifacts](#Store-colcon-logs-as-build-artifacts)
1. [Use with private repos](#Use-with-private-repos)
1. [Skip `rosdep install`](#Skip-rosdep-install)
1. [Interdependent pull requests or merge requests](#Interdependent-pull-requests-or-merge-requests)
1. [Developing](#Developing)
1. [License](#License)## Requirements
This action requires the following ROS development tools to be installed (and initialized if applicable) on the CI worker instance:
```
colcon-common-extensions
colcon-lcov-result # Optional
colcon-coveragepy-result
colcon-mixin
rosdep
vcstool
```On Linux, the setup can be done through [`ros-tooling/setup-ros`](https://github.com/ros-tooling/setup-ros), or by running the action in a Docker image containing the appropriate binaries.
**Note**: for Windows, `action-ros-ci` currently needs to be run on `windows-2019` or needs another action to install Visual Studio 2019.
## Overview
The action first assembles a workspace, then runs `colcon build`, and `colcon test` in it.
The workspace is built by running:
- `vcs import` on the repo file(s) specified through the `vcs-repo-file-url` argument, if any (defaults to none)
- checkout the code under test in the workspace using `vcs`
- `rosdep install` for the workspace, to get its dependencies
- run `colcon build` (optionally limited to packages specified in `package-name`)
- run `colcon test` (optionally limited to packages specified in `package-name`; optionally [skipped](#Skip-tests))This action requires targeting a ROS or ROS 2 distribution explicitly.
This is provided via the `target-ros1-distro` or `target-ros2-distro` inputs, respectively.
Either or both may be specified, if neither is provided an error will be raised.
This input is used to `source setup.sh` for any installed ROS binaries (e.g. installed using [`ros-tooling/setup-ros`](https://github.com/ros-tooling/setup-ros)), as well as used as an argument to `rosdep install`.## Action Output
This action defines [an output variable](https://help.github.com/en/actions/building-actions/metadata-syntax-for-github-actions#outputs): `ros-workspace-directory-name`.
It contains the path to the root of the ROS workspace assembled by the action.The variable value should be used to retrieve logs, binaries, etc. after the action completes.
## Usage
See [`action.yml`](action.yml) to get the list of inputs supported by this action.
[action-ros-ci-template](https://github.com/ros-tooling/action-ros-ci-template) offers a template for using `action-ros-ci`.
### Build and run tests for your ROS 2 package
Here are the two simplest use-cases.
#### Using dependencies from binaries
In this case, `action-ros-ci` will rely on `setup-ros` for installing ROS 2 binaries.
```yaml
steps:
- uses: ros-tooling/[email protected]
with:
required-ros-distributions: jazzy
- uses: ros-tooling/[email protected]
with:
package-name: my_package
target-ros2-distro: jazzy
```#### Building ROS 2 dependencies from source
In this case, `action-ros-ci` will build all necessary ROS 2 dependencies of `my_package` from source.
```yaml
steps:
- uses: ros-tooling/[email protected]
- uses: ros-tooling/[email protected]
with:
package-name: my_package
target-ros2-distro: jazzy
vcs-repo-file-url: https://raw.githubusercontent.com/ros2/ros2/jazzy/ros2.repos
```### Schedule an action on a specific branch
If you want to continue supporting older ROS releases while developing on an the main branch use `acton-ros-ci` with `ref` on a scheduled job.
Without setting ref the default branch and most recent commit will be used.```yaml
name: Jazzy Source Build
on:
schedule:
# At 00:00 on Sunday.
- cron '0 0 * * 0'jobs:
jazzy_source:
runs_on: ubuntu-latest
container:
image: ubuntu:noble
steps:
- uses: ros-tooling/[email protected]
with:
required-ros-distributions: jazzy
- uses: ros-tooling/[email protected]
with:
package-name: my_package
ref: jazzy
target-ros2-distro: jazzy
vcs-repo-file-url: https://raw.githubusercontent.com/ros2/ros2/jazzy/ros2.repos
```### Build with a custom `repos` or `rosinstall` file
You can specify your own repos file using the `vcs-repo-file-url` input.
You can also automatically generate your package's dependencies using the following workflow:```yaml
steps:
- uses: actions/checkout@v4
- uses: ros-tooling/[email protected]
# Run the generator and output the results to a file.
- run: |
rosinstall_generator --rosdistro \
--deps-only --deps --upstream-development > /tmp/deps.repos
# Pass the file to the action
- uses: ros-tooling/[email protected]
with:
package-name: my_package
target-ros2-distro: jazzy
vcs-repo-file-url: /tmp/deps.repos
```Note that the `actions/checkout` step is required when using a custom repos file from your repository.
### Build a ROS 1 workspace
Building a ROS 1 workspace works the same way.
Simply use `target-ros1-distro` instead of `target-ros2-distro`.```yaml
steps:
- uses: ros-tooling/[email protected]
with:
required-ros-distributions: noetic
- uses: ros-tooling/[email protected]
with:
package-name: my_package
target-ros1-distro: noetic
```### Skip tests
To skip tests and code coverage data processing, set the `skip-tests` option to `true`.
```yaml
steps:
- uses: ros-tooling/[email protected]
with:
required-ros-distributions: jazzy
- uses: ros-tooling/[email protected]
with:
package-name: my_package
target-ros2-distro: jazzy
skip-tests: true
```### Use a `colcon` `defaults.yaml` file
To use a [`colcon` `defaults.yaml` file](https://colcon.readthedocs.io/en/released/user/configuration.html#defaults-yaml), provide a valid JSON string through the `colcon-defaults` input.
This allows using a `colcon` option/argument that is not exposed by this action's inputs.```yaml
steps:
- uses: ros-tooling/[email protected]
with:
required-ros-distributions: jazzy
- uses: ros-tooling/[email protected]
with:
package-name: my_package
target-ros2-distro: jazzy
colcon-defaults: |
{
"build": {
"cmake-args": [
"-DMY_CUSTOM_OPTION=ON"
]
}
}
```### Do not use `--symlink-install` when building
By default, [`--symlink-install` is used with `colcon build`](https://colcon.readthedocs.io/en/released/reference/verb/build.html).
To avoid this, set the `no-symlink-install` input to `true`.```yaml
steps:
- uses: ros-tooling/[email protected]
with:
required-ros-distributions: jazzy
- uses: ros-tooling/[email protected]
with:
package-name: my_package
target-ros2-distro: jazzy
no-symlink-install: true
```### Enable Address Sanitizer to automatically report memory issues
[ASan][addresssanitizer] is an open-source tool developed to automatically report
memory corruption bugs.```yaml
steps:
- uses: ros-tooling/[email protected]
with:
required-ros-distributions: jazzy
- uses: ros-tooling/[email protected]
with:
colcon-defaults: |
{
"build": {
"mixin": ["asan-gcc"]
}
}
colcon-mixin-repository: https://raw.githubusercontent.com/colcon/colcon-mixin-repository/b8436aa16c0bdbc01081b12caa253cbf16e0fb82/index.yaml
package-name: my_package
target-ros2-distro: jazzy
```To look for detected memory errors, check the build logs for entries containing `ERROR: AddressSanitizer`. Example:
```
==9442== ERROR: AddressSanitizer heap-use-after-free on address 0x7f7ddab8c084 at pc 0x403c8c bp 0x7fff87fb82d0 sp 0x7fff87fb82c8
```ASan is analyzing memory issues at runtime. ASan diagnostic messages will be emitted by the package tests when they run.
### Generate and process code coverage data
#### Generate code coverage information using `lcov` and `colcon-lcov-result`
Generate code coverage information for C/C++ files using the appropriate mixins for `gcc`.
`action-ros-ci` uses [`colcon-lcov-result`](https://github.com/colcon/colcon-lcov-result) to aggregate generated coverage information.Flags can be passed manually using, for instance, `extra-cmake-args`, but it is
preferable to use a `colcon` mixin (through [`colcon-defaults`](#Use-a-colcon-defaultsyaml-file)) to pass the appropriate flags automatically.```yaml
steps:
- uses: ros-tooling/[email protected]
with:
required-ros-distributions: jazzy
- uses: ros-tooling/[email protected]
with:
package-name: my_package
target-ros2-distro: jazzy
colcon-defaults: |
{
"build": {
"mixin": ["coverage-gcc"]
}
}
# If possible, pin the repository in the workflow to a specific commit to avoid
# changes in colcon-mixin-repository from breaking your tests.
colcon-mixin-repository: https://raw.githubusercontent.com/colcon/colcon-mixin-repository/b8436aa16c0bdbc01081b12caa253cbf16e0fb82/index.yaml
```#### Generate code coverage information using `coveragepy` and `colcon-coveragepy-result`
Generate code coverage information for Python files using the appropriate mixins.
`action-ros-ci` uses [`colcon-coveragepy-result`](https://github.com/colcon/colcon-coveragepy-result) to aggregate generated coverage information.```yaml
steps:
- uses: ros-tooling/[email protected]
with:
required-ros-distributions: jazzy
- uses: ros-tooling/[email protected]
with:
package-name: my_package
target-ros2-distro: jazzy
colcon-defaults: |
{
"build": {
"mixin": ["coverage-pytest"]
},
"test": {
"mixin": ["coverage-pytest"]
}
}
# If possible, pin the repository in the workflow to a specific commit to avoid
# changes in colcon-mixin-repository from breaking your tests.
colcon-mixin-repository: https://raw.githubusercontent.com/colcon/colcon-mixin-repository/b8436aa16c0bdbc01081b12caa253cbf16e0fb82/index.yaml
```#### Integrate `action-ros-ci` with `codecov`
The generated code coverage information can be uploaded to [codecov.io](https://codecov.io/).
For a private repo, you will need to setup a secret `CODECOV_TOKEN` in [your repository settings][creating-encrypted-secrets].
See [`codecov/codecov-action`](https://github.com/codecov/codecov-action) documentation for more information about how to setup the action.```yaml
steps:
- uses: actions/checkout@v4
- uses: ros-tooling/[email protected]
with:
required-ros-distributions: jazzy
- uses: ros-tooling/[email protected]
with:
package-name: my_package
target-ros2-distro: jazzy
colcon-defaults: |
{
"build": {
"mixin": ["coverage-gcc", "coverage-pytest"]
},
"test": {
"mixin": ["coverage-pytest"]
}
}
# If possible, pin the repository in the workflow to a specific commit to avoid
# changes in colcon-mixin-repository from breaking your tests.
colcon-mixin-repository: https://raw.githubusercontent.com/colcon/colcon-mixin-repository/b8436aa16c0bdbc01081b12caa253cbf16e0fb82/index.yaml
- uses: codecov/[email protected]
with:
token: ${{ secrets.CODECOV_TOKEN }} # only needed for private repos
files: ros_ws/lcov/total_coverage.info,ros_ws/coveragepy/.coverage
flags: unittests
name: codecov-umbrella
```You will also need to add a [`codecov.yml` configuration file](https://docs.codecov.io/docs/codecovyml-reference) (at the root of your repo):
```yaml
fixes:
# For each package in your repo
- "ros_ws/src/*/my_repo/my_package/::"
```The configuration file is required to let codecov map the workspace directory structure to the Git repository structure, and setup the links between codecov and GitHub properly.
Note here that `actions/checkout` is required because `codecov/codecov-action` needs the `codecov.yml` file.### Store `colcon` logs as build artifacts
GitHub workflows can persist data generated in workers during the build using [artifacts](persisting-workflow-data-using-artifacts). `action-ros-ci` generated colcon logs can be saved as follows:
```yaml
steps:
# ...
- uses: ros-tooling/[email protected]
id: action_ros_ci_step
with:
package-name: ament_copyright
target-ros2-distro: jazzy
- uses: actions/upload-artifact@v1
with:
name: colcon-logs
path: ${{ steps.action_ros_ci_step.outputs.ros-workspace-directory-name }}/log
if: always() # upload the logs even when the build fails
```### Use with private repos
`action-ros-ci` needs a token to be able to clone private repositories.
If the only private repository your workflow needs is the one against which it runs, using the default `GITHUB_TOKEN` will work.
However, if your workflow also clones other private repositories (e.g., repositories included in repos files provided through `vcs-repo-file-url`), you will need to generate a [personal access token](https://github.com/settings/tokens) (PAT) with the "repo" scope and add it to your repo's [secrets][creating-encrypted-secrets].
For example, if this secret is called `REPO_TOKEN`:```yaml
steps:
# ...
- uses: ros-tooling/[email protected]
with:
package-name: my_package
# If there are no private dependencies, no need to create a PAT or add a secret
import-token: ${{ secrets.GITHUB_TOKEN }}
# If there are private dependencies (e.g., in a file provided through vcs-repo-file-url), a PAT is required
import-token: ${{ secrets.REPO_TOKEN }}
# ...
```### Skip `rosdep install`
Include an option to bypass `rosdep install` for workflow that uses specific docker image and better control of dependencies. To check for missing dependencies within the workflow's image, user can run with `rosdep-check: true` flag.
```yaml
runs-on: ubuntu-latest
container:
image: ghcr.io/ros-tooling/setup-ros-docker/setup-ros-docker-ubuntu-noble-ros-jazzy-ros-base
steps:
# ...
- uses: ros-tooling/[email protected]
with:
target-ros2-distro: jazzy
package-name: ament_copyright
vcs-repo-file-url: "https://raw.githubusercontent.com/ros2/ros2/release-jazzy-20240523/ros2.repos"
skip-rosdep-install: true
rosdep-check: true
```### Interdependent pull requests or merge requests
This action allows declaring PR dependencies by providing:
* repos file(s) to override the one(s) defined through the `vcs-repo-file-url` action input
* supplemental repos file(s) to be used along with the restFor example, this may be useful when your PR depends on PRs/MRs/branches from other repos for it to work or be properly tested.
Include links in your PR's description using the following format:
```
action-ros-ci-repos-override: https://gist.github.com/some-user/some.repos
action-ros-ci-repos-override: https://gist.github.com/some-user/some-other.repos
action-ros-ci-repos-supplemental: https://gist.github.com/some-user/some-supplemental.repos
action-ros-ci-repos-supplemental: file://path/to/some/other/supplemental.repos
```## Developing
For developing and releasing `action-ros-ci`, see [`DEVELOPING.md`](DEVELOPING.md).
## License
The scripts and documentation in this project are released under the [Apache 2](LICENSE) license.
[creating-encrypted-secrets]: https://help.github.com/en/actions/configuring-and-managing-workflows/creating-and-storing-encrypted-secrets#creating-encrypted-secrets
[persisting-workflow-data-using-artifacts]: https://help.github.com/en/actions/configuring-and-managing-workflows/persisting-workflow-data-using-artifacts
[addresssanitizer]: https://en.wikipedia.org/wiki/AddressSanitizer