Skip to content

Repository files navigation

openads-dev-environment

This repository defines a common development environment for and enforces consistency of components of OpenADS, the Open Automated Driving Systems project.

Features

Installation

  1. Add this repository as a Git submodule named .openads-dev-environment to the root of any other repository that you would like to use these settings for.
    git submodule add https://github.com/openads-project/openads-dev-environment.git .openads-dev-environment
  2. Create symbolic links to the relevant files and folders.
    ln -s .openads-dev-environment/.vscode .vscode
    ln -s .openads-dev-environment/.devcontainer .devcontainer
    ln -s .openads-dev-environment/.pre-commit-config.yaml .pre-commit-config.yaml
  3. Copy the CI workflow templates into your repository.
    # GitHub
    mkdir -p .github/workflows
    cp .openads-dev-environment/.github/workflow_calls/*.yml .github/workflows/
    
    # GitLab
    cp .openads-dev-environment/.gitlab-ci.template.yml .gitlab-ci.yml
  4. Customize the copied CI workflows to fit your repository, in particular base-image and command of the docker-ros job.
  5. Install the recommended VS Code extensions.

    Ctrl+Shift+P / Extensions: Show Recommended Extensions / Install Workspace Recommended Extensions (Cloud Download Icon)

  6. (optional) Install Git pre-commit hooks.
    pip install pre-commit
    pre-commit install
  7. (optional) Check consistency of your repository with OpenADS conventions.
    .openads-dev-environment/scripts/check_repository_consistency.py

Details

VS Code Configuration

This repository stores common .vscode settings for developing and debugging C++ and Python applications, in particular, ROS applications in container images built by docker-ros.

Features

Select Ctrl+Shift+P / Run Task to run a task. Tasks are defined in tasks.json.

Name Description
Build Builds ROS target workspace using colcon (Ctrl+Shift+B)
Build with Build Type Builds ROS target workspace using colcon with given build type
Test Runs tests in ROS target workspace using colcon
Clean Removes all build artifacts from ROS workspace
Clean CMake cache Builds CMake's clean target
New ROS 2 Package Creates a new ROS 2 package using ros2-pkg-create
Clone VCS repositories Clones VCS repositories from .repos file using vcs import
Install dependencies Install ROS dependencies declared in package.xml files using rosdep

Select the Run and Debug view in the Activity Bar on the side of VS Code (Ctrl+Shift+D). Select one of the pre-defined debugging configurations to start debugging. Debugging configurations are defined in launch.json.

Name Description
ROS 2: Attach Attach debugger to a running ROS executable (requires container to be started as root)
ROS 2: Executable Debug a ROS executable
ROS 2: Launch File Debug ROS nodes started by a launch file
Python: ROS 2 Launch file Debug a ROS 2 Python launch file using the Python debugger
Python: Current File Debug the currently opened Python script

Dev Container

This repository stores a common .devcontainer definition for attaching VS Code to container images built by docker-ros. This allows you to develop and debug ROS applications right from within VS Code.

Usage

Select Ctrl+Shift+P / Dev Containers: Rebuild and Reopen in Container. VS Code will automatically build and launch a new development container and open your repository inside this container.

By default, the Dev Container image is derived from your repository origin, e.g., ghcr.io/<owner>/<repo>:latest-dev or latest-dev_<branch>_ci on non-default branches. If the derived image cannot be pulled, the Dev Container helper falls back to building the image locally with docker-ros.

Customization

Add an .env file to the root of your repository to create custom environment variables. The following variables are used within the build-local-dockerfile.sh:

# overwrites the automatically generated base container image name
VSCODE_DEVCONTAINER_IMAGE=""
# forces to build the base container image locally using docker-ros instead of pulling it from a registry
VSCODE_DEVCONTAINER_BUILD_LOCALLY="false"
# chooses a docker-ros git reference if building the base container image locally using docker-ros
VSCODE_DEVCONTAINER_DOCKER_ROS_REF="main"

Pre-Commit Hooks

This repository stores a common pre-commit configuration for running linting and formatting checks before committing code.

Installation

Pre-commit hooks are auto-installed in the Dev Container. On the host, the pre-commit package is required.

pip install pre-commit
pre-commit install

Usage

Pre-commit hooks will automatically run on git commit and check all staged files. If any check fails, the commit is aborted and you can fix the issues before re-committing.

Pre-commit hooks can also be run manually.

pre-commit run --all-files

README Generator

Use generate_readme.py to generate common-style top-level and package-level READMEs. These READMEs are expected to be auto-generated by the consistency checker, but expect some customization and allow some freedom.

.openads-dev-environment/scripts/generate_readme.py

The package README generator derives ROS interface documentation from source and launch metadata. For C++ ROS nodes, parameters are extracted from declareAndLoadParameter(...) calls. Launch arguments are extracted from DeclareLaunchArgument(...) calls. Topic tables and flowcharts are generated from private ROS topic names such as ~/input and launch remapping metadata. Known transport helper APIs such as image_transport and point_cloud_transport are mapped to their underlying ROS message types.

Docker Compose Generator

Use generate_compose.py to generate Docker Compose deployments from the repository's ROS 2 launch files.

.openads-dev-environment/scripts/generate_compose.py

To check whether the committed Compose file is up to date without changing it, run:

.openads-dev-environment/scripts/generate_compose.py --check

The generator expects a ROS package subdirectory with launch files in launch/. A package-level <package>_launch.py remains the exclusive default and generates deployment/compose/docker-compose.yml. Without that default, a single launch file that directly starts the package generates the same output. Multiple directly launching files generate deployment/compose/docker-compose.<name>.yml, where <name> is the filename without _launch.py or .launch.py. Launch files that only include other launch files do not create a deployment.

Multi-launch deployments use each launch file's default node name and parameter file. The GitHub and GitLab compose-oci jobs publish them below the existing Compose image name with the launch name appended to the ref tag, for example compose:main-cam_generator. Single-launch artifact names and tags remain unchanged.

Each directly launching file must define at least one Node and DeclareLaunchArgument(...) entries. A remappable_topics list is optional and only controls which topic remaps are exposed and grouped as Compose environment variables. The generator owns docker-compose.yml and docker-compose.*.yml below deployment/compose; generation removes obsolete outputs and --check reports them.

For GitLab remotes, the generator uses the registry from an existing Compose file when available. Otherwise, override the derived registry with --gitlab-registry <host[:port]> or OPENADS_GITLAB_REGISTRY; if neither is set, it falls back to <gitlab-host>:5050.

Helm Chart Generator

Use generate_helm.py to generate helm/Chart.yaml and helm/values.yaml, similar to the Docker Compose Generator.

.openads-dev-environment/scripts/generate_helm.py --check

A single launch deployment keeps the existing deployment/helm/Chart.yaml and deployment/helm/values.yaml paths, chart name, and version. Multiple directly launching files generate one chart below deployment/helm/<name>/ per launch file. All charts use the same package-derived chart name and therefore share one OCI repository. Multi-launch chart versions append the launch name with underscores converted to hyphens, for example 1.0.0-first-node; branch builds append the Git ref afterwards. The Helm OCI workflows discover, package, publish, and clean up all generated charts.

Consistency Checker

Use check_repository_consistency.py to run a set of checks that enforce consistency and conventions across repositories. This is set up to be run in CI, but can also be run locally to check for issues before pushing.

.openads-dev-environment/scripts/check_repository_consistency.py

Specific checks can be skipped in CI by setting the skip-checks input in the GitHub workflow template or setting the CONSISTENCY_CHECKS_SKIP environment variable in the GitLab template.

The check_downstream_consistency.py helper is used by the consistency-downstream workflow to run the current development-environment checks against downstream OpenADS modules. When a new OpenADS module becomes available, add its repository URL to .github/workflows/consistency-downstream.yml so generator and consistency-check changes are tested against the complete module set.

List of Consistency Checks

Name Description
compose_generator_is_idempotent Passes when running .openads-dev-environment/scripts/generate_compose.py --check reports that all single- or multi-launch Compose files below deployment/compose match the current launch metadata and no obsolete generated files remain. Re-run the generator and commit the result until the check is clean.
cpp_code_has_doxygen_docs Passes when every tracked C++ function that Doxygen discovers has documentation on at least one emitted declaration or definition record.
default_launch_remappable_topics_cover_node_pubsub Passes when each default ROS package launch file lists every string-literal pub/sub/service/client name used by the launched node executables in its remappable_topics launch arguments. Packages without a default launch file are skipped.
dev_environment_at_remote_main Passes when .openads-dev-environment is present as a git repository and its current HEAD exactly matches origin/main. Update the submodule if it points to any other commit.
docker_ros_ci_has_no_todo Passes when root docker-ros CI files, specifically .github/workflows/docker-ros.yml and .gitlab-ci.yml when present, contain no TODO placeholder text. This ensures the template command placeholder was replaced with a repository-specific command.
generated_readmes_have_no_todo Passes when the repository top-level README.md and every generated package README.md contain no TODO placeholders. Replace all remaining placeholder text before committing.
helm_generator_is_idempotent Passes when running .openads-dev-environment/scripts/generate_helm.py --check reports that all single- or multi-launch Helm charts below deployment/helm match the current launch metadata and no obsolete generated files remain. Re-run the generator and commit the result until the check is clean.
no_top_level_package_xml Passes when the repository root does not contain a package.xml. ROS packages must live in subdirectories instead of treating the whole repository as one package.
readme_generator_is_idempotent Passes when running .openads-dev-environment/scripts/generate_readme.py produces no README content changes and no additional git status changes. Re-run the generator and commit the result until a second run is clean.
required_root_ci_workflows Passes when .github/workflows/ contains compose-oci.yml, consistency.yml, docker-ros.yml, docs.yml, ghcr-cleanup.yml, and helm-oci.yml.
required_top_level_symlinks Passes when the repository root contains symlinks .devcontainer -> .openads-dev-environment/.devcontainer/, .vscode -> .openads-dev-environment/.vscode/, and .pre-commit-config.yaml -> .openads-dev-environment/.pre-commit-config.yaml.
root_ci_workflows_match_templates Passes when the root workflow files .github/workflows/compose-oci.yml, .github/workflows/consistency.yml, .github/workflows/docs.yml, .github/workflows/ghcr-cleanup.yml, and .github/workflows/helm-oci.yml contain at least the content of the corresponding templates in .openads-dev-environment/.github/workflow_calls/.
ros_cmake_has_required_lint_block Passes when every ROS package CMakeLists.txt that declares targets with add_executable(...) or add_library(...) contains the exact required ament_lint_auto block, including the configured .clang-format, .clang-tidy, and ament_flake8.ini paths.
ros_nodes_have_parameter_loader Passes when each detected ROS node source file defines the required parameter helper: declareAndLoadParameter for C++ nodes or declare_and_load_parameter for Python nodes.
ros_packagexml_has_required_metadata Passes when every ROS package package.xml is valid XML and contains non-placeholder <name>, non-0.0.0 <version>, <description>, at least one non-empty <license>, and at least one <maintainer email="...">...</maintainer> plus <author email="...">...</author> entry that are not left at the default TODO placeholder values.
ros_packagexml_has_required_testdepends Passes when every ROS package package.xml contains the exact required <test_depend> block for ament_lint_auto, ament_cmake_clang_format, ament_cmake_clang_tidy, and ament_cmake_flake8.
ros_pubsub_topics_private_namespace Passes when string-literal topic and service names passed to ROS create_publisher, create_subscription, create_service, and create_client calls use the private namespace form ~/... instead of global or relative names.
source_files_have_copyright_notice Passes when every tracked .cpp, .hpp, and .py file contains a copyright notice and a non-placeholder license notice near the top of the file, for example via SPDX-License-Identifier: <license-expression>.
top_level_license Passes when a top-level LICENSE file exists and contains non-placeholder license text.

CI Workflows

This repository stores CI workflow templates for the following use cases. CI workflows are defined for GitHub Actions in .github/workflow_calls and for GitLab CI/CD in .gitlab-ci.template.yml.

Name Description
compose-oci Publishes the repository's single- or multi-launch Docker Compose files as OCI artifacts to the configured container registry.
consistency Runs the consistency checker to check for repository consistency and convention adherence.
docker-ros Uses docker-ros to build, test, and push a container image containing the ROS packages of the repository.
docs Builds and deploys documentation using GitHub Pages or GitLab Pages.
ghcr-cleanup Cleans up unused images in the GitHub Container Registry.
helm-oci Publishes the repository's single- or multi-launch Helm charts as OCI artifacts to the configured container registry.

About

Common development environment for OpenADS modules

Topics

Resources

Stars

2 stars

Watchers

2 watching

Forks

Used by

Contributors

Languages