diff --git a/.gitlab-ci/docker-ros.yml b/.gitlab-ci/docker-ros.yml index f4c33bd..19e2fd6 100644 --- a/.gitlab-ci/docker-ros.yml +++ b/.gitlab-ci/docker-ros.yml @@ -9,69 +9,81 @@ workflow: variables: - TARGET: run # Target stage of Dockerfile (comma-separated list) [dev|run] - PLATFORM: amd64 # Target platform architecture (comma-separated list) [amd64|arm64|...] - BASE_IMAGE: '' # Base image name:tag (required) - COMMAND: '' # Launch command of run image (required if target=run) - IMAGE_NAME: ${CI_REGISTRY_IMAGE} # Image name of run image - IMAGE_TAG: latest # Image tag of run image - DEV_IMAGE_NAME: ${IMAGE_NAME} # Image name of dev image - DEV_IMAGE_TAG: ${IMAGE_TAG}-dev # Image tag of dev image - SLIM_IMAGE_NAME: ${IMAGE_NAME} # Image name of slim run image - SLIM_IMAGE_TAG: ${IMAGE_TAG}-slim # Image tag of slim run image - BUILD_CONTEXT: . # Build context of Docker build process - REGISTRY: ${CI_REGISTRY} # Docker registry to push images to - REGISTRY_USER: ${CI_REGISTRY_USER} # Docker registry username - REGISTRY_PASSWORD: ${CI_REGISTRY_PASSWORD} # Docker registry password - ENABLE_INDUSTRIAL_CI: 'false' # Enable industrial_ci - ENABLE_SLIM: 'true' # Enable an extra slimmed run image via slim (only if run stage is targeted) - SLIM_BUILD_ARGS: '--sensor-ipc-mode proxy --continue-after=10 --show-clogs --http-probe=false' # Arguments to `slim build` (except for `--target` and `--tag`) - ENABLE_SINGLEARCH_PUSH: 'false' # Enable push of single arch images with [-amd64|-arm64] postfix - ENABLE_PUSH_AS_LATEST: 'false' # Push images with tag `latest`/`latest-dev` in addition to the configured image names - RMW_IMPLEMENTATION: 'rmw_cyclonedds_cpp' # RMW implementation to use (only for ROS 2) - ROS_DISTRO: '' # ROS Distro (required if ROS is not installed in `base-image`) - DISABLE_ROS_INSTALLATION: 'false' # Disable automatic installation of `ros-$ROS_DISTRO-ros-core` package, e.g., if ROS is already installed in `base-image` and package is not available for the OS - GIT_HTTPS_SERVER: ${CI_SERVER_HOST} # Server URL (without protocol) for cloning private Git repositories via HTTPS - GIT_HTTPS_USER: gitlab-ci-token # Username for cloning private Git repositories via HTTPS - GIT_HTTPS_PASSWORD: ${CI_JOB_TOKEN} # Password for cloning private Git repositories via HTTPS - GIT_SSH_PRIVATE_KEY: '' # SSH private key for cloning private Git repositories via SSH - GIT_SSH_KNOWN_HOST_KEYS: '' # Known SSH host keys for cloning private Git repositories via SSH (may be obtained using `ssh-keyscan`) - ADDITIONAL_DEBS_FILE: docker/additional-debs.txt # Relative filepath to file containing additional apt deb packages to install - ENABLE_RECURSIVE_ADDITIONAL_DEBS: 'false' # Enable recursive discovery of files named `additional-debs-file` - ADDITIONAL_FILES_DIR: docker/additional-files # Relative path to directory containing additional files to copy into image" - ADDITIONAL_PIP_FILE: docker/additional-pip-requirements.txt # Relative filepath to file containing additional pip packages to install - ENABLE_RECURSIVE_ADDITIONAL_PIP: 'false' # Enable recursive discovery of files named `additional-pip-file` - BLACKLISTED_PACKAGES_FILE: docker/blacklisted-packages.txt # Relative filepath to file containing the blacklisted packages - ENABLE_RECURSIVE_BLACKLISTED_PACKAGES: 'false' # Enable recursive discovery of files named `blacklisted-packages-file` - CUSTOM_SCRIPT_FILE: docker/custom.sh # Relative filepath to script containing custom installation commands - ENABLE_RECURSIVE_CUSTOM_SCRIPT: 'false' # Enable recursive discovery of files named `custom-script-file` - VCS_IMPORT_FILE: .repos # Relative filepath to file containing additional repos to install via vcstools (only relevant if ENABLE_RECURSIVE_VCS_IMPORT=false) - ENABLE_RECURSIVE_VCS_IMPORT: 'true' # Enable recursive discovery of files named `*.repos` + ADDITIONAL_DEBS_FILE: docker/additional-debs.txt # Relative filepath to file containing additional apt deb packages to install + ADDITIONAL_FILES_DIR: docker/additional-files # Relative path to directory containing additional files to copy into image" + ADDITIONAL_PIP_FILE: docker/additional-pip-requirements.txt # Relative filepath to file containing additional pip packages to install + BASE_IMAGE: '' # Base image name:tag (required) + BLACKLISTED_PACKAGES_FILE: docker/blacklisted-packages.txt # Relative filepath to file containing the blacklisted packages + BUILD_CONTEXT: . # Build context of Docker build process + BUILD_IMAGE_NAME: ${IMAGE_NAME} # Image name of build image + BUILD_IMAGE_TAG: ${IMAGE_TAG}-build # Image tag of build image + COMMAND: '' # Launch command of build/run image (required if target=run) + CUSTOM_SCRIPT_FILE: docker/custom.sh # Relative filepath to script containing custom installation commands + DEV_IMAGE_NAME: ${IMAGE_NAME} # Image name of dev image + DEV_IMAGE_TAG: ${IMAGE_TAG}-dev # Image tag of dev image + DISABLE_ROS_INSTALLATION: 'false' # Disable automatic installation of `ros-$ROS_DISTRO-ros-core` package, e.g., if ROS is already installed in `base-image` and package is not available for the OS + ENABLE_CONTINUE_BUILD_DESPITE_ERRORS: 'false' # Enable `catkin build --continue-on-failure` / `colcon build --continue-on-error` + ENABLE_CONTINUE_ROSDEP_INSTALL_DESPITE_ERRORS: 'false' # Enable `rosdep install -r` + ENABLE_INDUSTRIAL_CI: 'false' # Enable industrial_ci + ENABLE_PUSH_AS_LATEST: 'false' # Push images with tag `latest`/`latest-dev` in addition to the configured image names + ENABLE_RECURSIVE_ADDITIONAL_DEBS: 'false' # Enable recursive discovery of files named `additional-debs-file` + ENABLE_RECURSIVE_ADDITIONAL_PIP: 'false' # Enable recursive discovery of files named `additional-pip-file` + ENABLE_RECURSIVE_BLACKLISTED_PACKAGES: 'false' # Enable recursive discovery of files named `blacklisted-packages-file` + ENABLE_RECURSIVE_CUSTOM_SCRIPT: 'false' # Enable recursive discovery of files named `custom-script-file` + ENABLE_RECURSIVE_VCS_IMPORT: 'true' # Enable recursive discovery of files named `*.repos` + ENABLE_ROS1_DEVEL_SPACE: 'false' # Enable building to ROS devel space instead of install space (ROS 1 only) + ENABLE_SINGLEARCH_PUSH: 'false' # Enable push of single arch images with [-amd64|-arm64] postfix + ENABLE_SLIM: 'true' # Enable an extra slimmed run image via slim (only if run stage is targeted) + GIT_HTTPS_PASSWORD: ${CI_JOB_TOKEN} # Password for cloning private Git repositories via HTTPS + GIT_HTTPS_SERVER: ${CI_SERVER_HOST} # Server URL (without protocol) for cloning private Git repositories via HTTPS + GIT_HTTPS_USER: gitlab-ci-token # Username for cloning private Git repositories via HTTPS + GIT_SSH_KNOWN_HOST_KEYS: '' # Known SSH host keys for cloning private Git repositories via SSH (may be obtained using `ssh-keyscan`) + GIT_SSH_PRIVATE_KEY: '' # SSH private key for cloning private Git repositories via SSH + IMAGE_NAME: ${CI_REGISTRY_IMAGE} # Image name of run image + IMAGE_TAG: latest # Image tag of run image + PLATFORM: amd64 # Target platform architecture (comma-separated list) [amd64|arm64|...] + REGISTRY_PASSWORD: ${CI_REGISTRY_PASSWORD} # Docker registry password + REGISTRY_USER: ${CI_REGISTRY_USER} # Docker registry username + REGISTRY: ${CI_REGISTRY} # Docker registry to push images to + RMW_IMPLEMENTATION: 'rmw_cyclonedds_cpp' # RMW implementation to use (only for ROS 2) + ROS_DISTRO: '' # ROS Distro (required if ROS is not installed in `base-image`) + SLIM_BUILD_ARGS: '--sensor-ipc-mode proxy --continue-after=10 --show-clogs --http-probe=false' # Arguments to `slim build` (except for `--target` and `--tag`) + SLIM_IMAGE_NAME: ${IMAGE_NAME} # Image name of slim run image + SLIM_IMAGE_TAG: ${IMAGE_TAG}-slim # Image tag of slim run image + TARGET: run # Target stage of Dockerfile (comma-separated list) [dev|build|run] + VCS_IMPORT_FILE: .repos # Relative filepath to file containing additional repos to install via vcstools (only relevant if ENABLE_RECURSIVE_VCS_IMPORT=false) # ----- DOCKER_ROS_GIT_REF: main _RUN_IMAGE: ${IMAGE_NAME}:${IMAGE_TAG} + _BUILD_IMAGE: ${BUILD_IMAGE_NAME}:${BUILD_IMAGE_TAG} _DEV_IMAGE: ${DEV_IMAGE_NAME}:${DEV_IMAGE_TAG} _SLIM_IMAGE: ${SLIM_IMAGE_NAME}:${SLIM_IMAGE_TAG} - _IMAGE_DEV_CI: ${_DEV_IMAGE}_${CI_COMMIT_REF_SLUG}_ci - _IMAGE_RUN_CI: ${_RUN_IMAGE}_${CI_COMMIT_REF_SLUG}_ci - _IMAGE_SLIM_CI: ${_SLIM_IMAGE}_${CI_COMMIT_REF_SLUG}_ci - _IMAGE_DEV_CI_AMD64: ${_IMAGE_DEV_CI}-amd64 - _IMAGE_DEV_CI_ARM64: ${_IMAGE_DEV_CI}-arm64 - _IMAGE_RUN_CI_AMD64: ${_IMAGE_RUN_CI}-amd64 - _IMAGE_RUN_CI_ARM64: ${_IMAGE_RUN_CI}-arm64 + _IMAGE_BUILD_CI_AMD64: ${_IMAGE_BUILD_CI}-amd64 + _IMAGE_BUILD_CI_ARM64: ${_IMAGE_BUILD_CI}-arm64 + _IMAGE_BUILD_CI: ${_BUILD_IMAGE}_${CI_COMMIT_REF_SLUG}_ci + _IMAGE_BUILD_LATEST: ${BUILD_IMAGE_NAME}:latest-build + _IMAGE_BUILD_TAG: ${BUILD_IMAGE_NAME}:${CI_COMMIT_TAG}-build + _IMAGE_BUILD_TARGET_TAG: ${_BUILD_IMAGE}-${CI_COMMIT_TAG} + _IMAGE_DEV_CI_AMD64: ${_IMAGE_DEV_CI}-amd64 + _IMAGE_DEV_CI_ARM64: ${_IMAGE_DEV_CI}-arm64 + _IMAGE_DEV_CI: ${_DEV_IMAGE}_${CI_COMMIT_REF_SLUG}_ci + _IMAGE_DEV_LATEST: ${DEV_IMAGE_NAME}:latest-dev + _IMAGE_DEV_TAG: ${DEV_IMAGE_NAME}:${CI_COMMIT_TAG}-dev + _IMAGE_DEV_TARGET_TAG: ${_DEV_IMAGE}-${CI_COMMIT_TAG} + _IMAGE_RUN_CI_AMD64: ${_IMAGE_RUN_CI}-amd64 + _IMAGE_RUN_CI_ARM64: ${_IMAGE_RUN_CI}-arm64 + _IMAGE_RUN_CI: ${_RUN_IMAGE}_${CI_COMMIT_REF_SLUG}_ci + _IMAGE_RUN_LATEST: ${IMAGE_NAME}:latest + _IMAGE_RUN_TAG: ${IMAGE_NAME}:${CI_COMMIT_TAG} + _IMAGE_RUN_TARGET_TAG: ${_RUN_IMAGE}-${CI_COMMIT_TAG} _IMAGE_SLIM_CI_AMD64: ${_IMAGE_SLIM_CI}-amd64 _IMAGE_SLIM_CI_ARM64: ${_IMAGE_SLIM_CI}-arm64 - _IMAGE_DEV_LATEST: ${DEV_IMAGE_NAME}:latest-dev - _IMAGE_RUN_LATEST: ${IMAGE_NAME}:latest + _IMAGE_SLIM_CI: ${_SLIM_IMAGE}_${CI_COMMIT_REF_SLUG}_ci _IMAGE_SLIM_LATEST: ${SLIM_IMAGE_NAME}:latest-slim - _IMAGE_DEV_TARGET_TAG: ${_DEV_IMAGE}-${CI_COMMIT_TAG} - _IMAGE_RUN_TARGET_TAG: ${_RUN_IMAGE}-${CI_COMMIT_TAG} - _IMAGE_SLIM_TARGET_TAG: ${_SLIM_IMAGE}-${CI_COMMIT_TAG} - _IMAGE_DEV_TAG: ${DEV_IMAGE_NAME}:${CI_COMMIT_TAG}-dev - _IMAGE_RUN_TAG: ${IMAGE_NAME}:${CI_COMMIT_TAG} _IMAGE_SLIM_TAG: ${SLIM_IMAGE_NAME}:${CI_COMMIT_TAG}-slim + _IMAGE_SLIM_TARGET_TAG: ${_SLIM_IMAGE}-${CI_COMMIT_TAG} GIT_SUBMODULE_STRATEGY: recursive DOCKER_DRIVER: overlay2 @@ -81,6 +93,7 @@ variables: stages: - Build dev Images + - Build build Images - Build run Images - Test ROS Industrial CI - Slim Images @@ -150,12 +163,45 @@ dev-arm64: ENABLE_SLIM: 'false' _IMAGE_POSTFIX: _${CI_COMMIT_REF_SLUG}_ci +build-amd64: + stage: Build build Images + extends: .build + needs: + - job: dev-amd64 + optional: true + rules: + - if: $PLATFORM =~ /.*amd64.*/ && $TARGET =~ /.*build.*/ + variables: + _PLATFORM: amd64 + _TARGET: build + IMAGE: ${_IMAGE_BUILD_CI_AMD64} + ENABLE_SINGLEARCH_PUSH: 'true' + _IMAGE_POSTFIX: _${CI_COMMIT_REF_SLUG}_ci + +build-arm64: + stage: Build build Images + extends: .build + tags: [privileged, arm64] + needs: + - job: dev-arm64 + optional: true + rules: + - if: $PLATFORM =~ /.*arm64.*/ && $TARGET =~ /.*build.*/ + variables: + _PLATFORM: arm64 + _TARGET: build + IMAGE: ${_IMAGE_BUILD_CI_ARM64} + ENABLE_SINGLEARCH_PUSH: 'true' + _IMAGE_POSTFIX: _${CI_COMMIT_REF_SLUG}_ci + run-amd64: stage: Build run Images extends: .build needs: - job: dev-amd64 optional: true + - job: build-amd64 + optional: true rules: - if: $PLATFORM =~ /.*amd64.*/ && $TARGET =~ /.*run.*/ variables: @@ -173,6 +219,8 @@ run-arm64: needs: - job: dev-arm64 optional: true + - job: build-arm64 + optional: true rules: - if: $PLATFORM =~ /.*arm64.*/ && $TARGET =~ /.*run.*/ variables: @@ -300,6 +348,10 @@ Slim run-arm64: optional: true - job: dev-arm64 optional: true + - job: build-amd64 + optional: true + - job: build-arm64 + optional: true - job: run-amd64 optional: true - job: run-arm64 @@ -326,6 +378,10 @@ Slim run-arm64: docker manifest create ${IMG_DEV} --amend ${_IMAGE_DEV_CI_AMD64} --amend ${_IMAGE_DEV_CI_ARM64} docker manifest push ${IMG_DEV} fi + if [[ "${TARGET}" =~ build ]]; then + docker manifest create ${IMG_BUILD} --amend ${_IMAGE_BUILD_CI_AMD64} --amend ${_IMAGE_BUILD_CI_ARM64} + docker manifest push ${IMG_BUILD} + fi if [[ "${TARGET}" =~ run ]]; then docker manifest create ${IMG_RUN} --amend ${_IMAGE_RUN_CI_AMD64} --amend ${_IMAGE_RUN_CI_ARM64} docker manifest push ${IMG_RUN} @@ -340,6 +396,11 @@ Slim run-arm64: docker tag ${_IMAGE_DEV_CI_AMD64} ${IMG_DEV} docker push ${IMG_DEV} fi + if [[ "${TARGET}" =~ build ]]; then + docker pull ${_IMAGE_BUILD_CI_AMD64} + docker tag ${_IMAGE_BUILD_CI_AMD64} ${IMG_BUILD} + docker push ${IMG_BUILD} + fi if [[ "${TARGET}" =~ run ]]; then docker pull ${_IMAGE_RUN_CI_AMD64} docker tag ${_IMAGE_RUN_CI_AMD64} ${IMG_RUN} @@ -356,6 +417,11 @@ Slim run-arm64: docker tag ${_IMAGE_DEV_CI_ARM64} ${IMG_DEV} docker push ${IMG_DEV} fi + if [[ "${TARGET}" =~ build ]]; then + docker pull ${_IMAGE_BUILD_CI_ARM64} + docker tag ${_IMAGE_BUILD_CI_ARM64} ${IMG_BUILD} + docker push ${IMG_BUILD} + fi if [[ "${TARGET}" =~ run ]]; then docker pull ${_IMAGE_RUN_CI_ARM64} docker tag ${_IMAGE_RUN_CI_ARM64} ${IMG_RUN} @@ -378,6 +444,7 @@ Push CI: - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH variables: IMG_DEV: ${_IMAGE_DEV_CI} + IMG_BUILD: ${_IMAGE_BUILD_CI} IMG_RUN: ${_IMAGE_RUN_CI} IMG_SLIM: ${_IMAGE_SLIM_CI} @@ -389,6 +456,7 @@ Push: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH variables: IMG_DEV: ${_DEV_IMAGE} + IMG_BUILD: ${_BUILD_IMAGE} IMG_RUN: ${_RUN_IMAGE} IMG_SLIM: ${_SLIM_IMAGE} @@ -400,6 +468,7 @@ Push latest: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $ENABLE_PUSH_AS_LATEST == 'true' variables: IMG_DEV: ${_IMAGE_DEV_LATEST} + IMG_BUILD: ${_IMAGE_BUILD_LATEST} IMG_RUN: ${_IMAGE_RUN_LATEST} IMG_SLIM: ${_IMAGE_SLIM_LATEST} @@ -411,6 +480,7 @@ Push target tag: - if: $CI_COMMIT_TAG variables: IMG_DEV: ${_IMAGE_DEV_TARGET_TAG} + IMG_BUILD: ${_IMAGE_BUILD_TARGET_TAG} IMG_RUN: ${_IMAGE_RUN_TARGET_TAG} IMG_SLIM: ${_IMAGE_SLIM_TARGET_TAG} @@ -422,5 +492,6 @@ Push tag: - if: $CI_COMMIT_TAG && $ENABLE_PUSH_AS_LATEST == 'true' variables: IMG_DEV: ${_IMAGE_DEV_TAG} + IMG_BUILD: ${_IMAGE_BUILD_TAG} IMG_RUN: ${_IMAGE_RUN_TAG} IMG_SLIM: ${_IMAGE_SLIM_TAG} diff --git a/README.md b/README.md index 345616d..2eb2af7 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ # *docker-ros* – Automated Containerization of ROS Apps +// TODO: explain build image somewhere +

@@ -310,6 +312,8 @@ If your ROS-based repository (or any of your repository's upstream dependencies, Create a file `blacklisted-packages.txt` in your `docker` folder (or configure a different `BLACKLISTED_PACKAGES_FILE`) and list any ROS package name to blacklist. +If you are having problems with (upstream) packages that you don't need, also have a look at `ENABLE_CONTINUE_ROSDEP_INSTALL_DESPITE_ERRORS` and `ENABLE_CONTINUE_BUILD_DESPITE_ERRORS`. + ### Extra System Dependencies (*apt*) If your ROS-based repository requires system dependencies that cannot be installed by specifying their [rosdep](https://docs.ros.org/en/independent/api/rosdep/html/) keys in a `package.xml`, you can use a special `additional-debs.txt` file. @@ -375,8 +379,14 @@ The password of the custom user is set to its username (`dockeruser:dockeruser` - **`build-context` | `BUILD_CONTEXT`** Build context of Docker build process *default:* `${{ github.workspace }}` | `.` +- **`build-image-name` | `BUILD_IMAGE_NAME`** + Image name of build image + *default:* `` +- **`build-image-tag` | `BUILD_IMAGE_TAG`** + Image tag of build image + *default:* `-build` - **`command` | `COMMAND`** - Launch command of run image + Launch command of build/run image *required if `target=run`* - **`custom-script-file` | `CUSTOM_SCRIPT_FILE`** Relative filepath to script containing custom installation commands @@ -397,21 +407,24 @@ The password of the custom user is set to its username (`dockeruser:dockeruser` - **`enable-checkout` | `-`** Enable [*checkout*](https://github.com/actions/checkout) action to (re-)download your repository prior to running the pipeline *default:* `true` -- **`enable-checkout-submodules` | `-`** - Enable submodules for the [*checkout*](https://github.com/actions/checkout) action (`false`|`true`|`recursive`) - *default:* `recursive` - **`enable-checkout-lfs` | `-`** Enable [*Git LFS*](https://git-lfs.com/) support for the [*checkout*](https://github.com/actions/checkout) action *default:* `true` +- **`enable-checkout-submodules` | `-`** + Enable submodules for the [*checkout*](https://github.com/actions/checkout) action (`false`|`true`|`recursive`) + *default:* `recursive` +- **`enable-continue-build-despite-errors` | `ENABLE_CONTINUE_BUILD_DESPITE_ERRORS`** + Enable `catkin build --continue-on-failure` / `colcon build --continue-on-error` + *default:* `false` +- **`enable-continue-rosdep-install-despite-errors` | `ENABLE_CONTINUE_ROSDEP_INSTALL_DESPITE_ERRORS`** + Enable `rosdep install -r` + *default:* `false` - **`enable-industrial-ci` | `ENABLE_INDUSTRIAL_CI`** Enable [*industrial_ci*](https://github.com/ros-industrial/industrial_ci) *default:* `false` - **`enable-push-as-latest` | `ENABLE_PUSH_AS_LATEST`** - Push images with tag `latest`/`latest-dev` in addition to the configured image names + Push images with tag `latest`/`latest-dev`/`latest-build` in addition to the configured image names *default:* `false` -- **`enable-singlearch-push` | `ENABLE_SINGLEARCH_PUSH`** - Enable push of single arch images with `-amd64`/`-arm64` postfix - *default:* `false` - **`enable-recursive-additional-debs` | `ENABLE_RECURSIVE_ADDITIONAL_DEBS`** Enable recursive discovery of files named `additional-debs-file` *default:* `false` @@ -427,6 +440,12 @@ The password of the custom user is set to its username (`dockeruser:dockeruser` - **`enable-recursive-vcs-import` | `ENABLE_RECURSIVE_VCS_IMPORT`** Enable recursive discovery of files named `*.repos` *default:* `true` +- **`enable-ros1-devel-space` | `ENABLE_ROS1_DEVEL_SPACE`** + Enable building to ROS devel space instead of install space (ROS 1 only) + *default:* `false` +- **`enable-singlearch-push` | `ENABLE_SINGLEARCH_PUSH`** + Enable push of single arch images with `-amd64`/`-arm64` postfix + *default:* `false` - **`enable-slim` | `ENABLE_SLIM`** Enable an extra slimmed run image via [slim](https://github.com/slimtoolkit/slim) (only if `run` stage is targeted) *default:* `true` @@ -482,7 +501,7 @@ The password of the custom user is set to its username (`dockeruser:dockeruser` - **`target` | `TARGET`** Target stage of Dockerfile (comma-separated list) *default:* `run` - *supported values:* `dev`, `run` + *supported values:* `dev`, `build`, `run` - **`vcs-import-file` | `VCS_IMPORT_FILE`** Relative filepath to file containing additional repos to install via vcstools (only relevant if `enable-recursive-vcs-import=false`) *default:* `.repos` diff --git a/action.yml b/action.yml index bb78023..1bb0601 100644 --- a/action.yml +++ b/action.yml @@ -7,7 +7,7 @@ branding: inputs: target: - description: "Target stage of Dockerfile (comma-separated list) [dev|run]" + description: "Target stage of Dockerfile (comma-separated list) [dev|build|run]" default: run platform: @@ -18,7 +18,7 @@ inputs: required: true command: - description: "Launch command of run image (required if target=run)" + description: "Launch command of build/run image (required if target=run)" image-name: description: "Image name of run image" @@ -35,6 +35,12 @@ inputs: dev-image-tag: description: "Image tag of dev image" + build-image-name: + description: "Image name of build image" + + build-image-tag: + description: "Image tag of build image" + slim-image-name: description: "Image name of slim run image" default: ghcr.io/${{ github.repository }} @@ -140,7 +146,7 @@ inputs: default: false enable-push-as-latest: - description: "Push images with tag `latest`/`latest-dev` in addition to the configured image names" + description: "Push images with tag `latest`/`latest-dev`/`latest-build` in addition to the configured image names" default: false enable-checkout: @@ -155,6 +161,18 @@ inputs: description: "Enable Git LFS support for the checkout action" default: true + enable-continue-build-despite-errors: + description: Enable `catkin build --continue-on-failure` / `colcon build --continue-on-error` + default: false + + enable-continue-rosdep-install-despite-errors: + description: Enable `rosdep install -r` + default: false + + enable-ros1-devel-space: + description: Enable building to ROS devel space instead of install space (ROS 1 only) + default: false + runs: using: "composite" @@ -207,6 +225,12 @@ runs: with: string: ${{ inputs.dev-image-name }} + - name: Enforce lower-case build image name + id: build-image-name + uses: ASzc/change-string-case-action@v6 + with: + string: ${{ inputs.build-image-name }} + - name: Enforce lower-case slim image name id: slim-image-name uses: ASzc/change-string-case-action@v6 @@ -219,37 +243,42 @@ runs: working-directory: ${{ inputs.build-context }} run: docker/docker-ros/scripts/ci.sh env: - PLATFORM: ${{ inputs.platform }} - TARGET: ${{ inputs.target }} + ADDITIONAL_DEBS_FILE: ${{ inputs.additional-debs-file }} + ADDITIONAL_FILES_DIR: ${{ inputs.additional-files-dir }} + ADDITIONAL_PIP_FILE: ${{ inputs.additional-pip-file }} BASE_IMAGE: ${{ inputs.base-image }} + BLACKLISTED_PACKAGES_FILE: ${{ inputs.blacklisted-packages-file }} + BUILD_IMAGE_NAME: ${{ steps.build-image-name.outputs.lowercase }} + BUILD_IMAGE_TAG: ${{ inputs.build-image-tag }} COMMAND: ${{ inputs.command }} - IMAGE_NAME: ${{ steps.image-name.outputs.lowercase }} - IMAGE_TAG: ${{ inputs.image-tag }} + CUSTOM_SCRIPT_FILE: ${{ inputs.custom-script-file }} DEV_IMAGE_NAME: ${{ steps.dev-image-name.outputs.lowercase }} DEV_IMAGE_TAG: ${{ inputs.dev-image-tag }} - SLIM_IMAGE_NAME: ${{ steps.slim-image-name.outputs.lowercase }} - SLIM_IMAGE_TAG: ${{ inputs.slim-image-tag }} - ENABLE_SLIM: ${{ inputs.enable-slim }} - SLIM_BUILD_ARGS: ${{ inputs.slim-build-args }} - RMW_IMPLEMENTATION: ${{ inputs.rmw-implementation }} - ROS_DISTRO: ${{ inputs.ros-distro }} DISABLE_ROS_INSTALLATION: ${{ inputs.disable-ros-installation }} - GIT_HTTPS_SERVER: ${{ inputs.git-https-server }} - GIT_HTTPS_USER: ${{ inputs.git-https-user }} - GIT_HTTPS_PASSWORD: ${{ inputs.git-https-password }} - GIT_SSH_PRIVATE_KEY: ${{ inputs.git-ssh-private-key }} - GIT_SSH_KNOWN_HOST_KEYS: ${{ inputs.git-ssh-known-host-keys }} - ADDITIONAL_DEBS_FILE: ${{ inputs.additional-debs-file }} + ENABLE_CONTINUE_BUILD_DESPITE_ERRORS: ${{ inputs.enable-continue-build-despite-errors }} + ENABLE_CONTINUE_ROSDEP_INSTALL_DESPITE_ERRORS: ${{ inputs.enable-continue-rosdep-install-despite-errors }} ENABLE_RECURSIVE_ADDITIONAL_DEBS: ${{ inputs.enable-recursive-additional-debs }} - ADDITIONAL_FILES_DIR: ${{ inputs.additional-files-dir }} - ADDITIONAL_PIP_FILE: ${{ inputs.additional-pip-file }} ENABLE_RECURSIVE_ADDITIONAL_PIP: ${{ inputs.enable-recursive-additional-pip }} - BLACKLISTED_PACKAGES_FILE: ${{ inputs.blacklisted-packages-file }} ENABLE_RECURSIVE_BLACKLISTED_PACKAGES: ${{ inputs.enable-recursive-blacklisted-packages }} - CUSTOM_SCRIPT_FILE: ${{ inputs.custom-script-file }} ENABLE_RECURSIVE_CUSTOM_SCRIPT: ${{ inputs.enable-recursive-custom-script }} - VCS_IMPORT_FILE: ${{ inputs.vcs-import-file }} ENABLE_RECURSIVE_VCS_IMPORT: ${{ inputs.enable-recursive-vcs-import }} + ENABLE_ROS1_DEVEL_SPACE: ${{ inputs.enable-ros1-devel-space }} + ENABLE_SLIM: ${{ inputs.enable-slim }} + GIT_HTTPS_PASSWORD: ${{ inputs.git-https-password }} + GIT_HTTPS_SERVER: ${{ inputs.git-https-server }} + GIT_HTTPS_USER: ${{ inputs.git-https-user }} + GIT_SSH_KNOWN_HOST_KEYS: ${{ inputs.git-ssh-known-host-keys }} + GIT_SSH_PRIVATE_KEY: ${{ inputs.git-ssh-private-key }} + IMAGE_NAME: ${{ steps.image-name.outputs.lowercase }} + IMAGE_TAG: ${{ inputs.image-tag }} + PLATFORM: ${{ inputs.platform }} + RMW_IMPLEMENTATION: ${{ inputs.rmw-implementation }} + ROS_DISTRO: ${{ inputs.ros-distro }} + SLIM_BUILD_ARGS: ${{ inputs.slim-build-args }} + SLIM_IMAGE_NAME: ${{ steps.slim-image-name.outputs.lowercase }} + SLIM_IMAGE_TAG: ${{ inputs.slim-image-tag }} + TARGET: ${{ inputs.target }} + VCS_IMPORT_FILE: ${{ inputs.vcs-import-file }} - name: Set up industrial_ci if: ${{ inputs.enable-industrial-ci == 'true' }} @@ -260,15 +289,15 @@ runs: if: ${{ inputs.enable-industrial-ci == 'true' }} uses: ros-industrial/industrial_ci@master env: - UPSTREAM_WORKSPACE: ${{ inputs.build-context }}/.repos - TARGET_WORKSPACE: ${{ inputs.build-context }} ADDITIONAL_DEBS: git AFTER_INIT_EMBED: '[[ "$RMW_IMPLEMENTATION" == "rmw_zenoh_cpp" ]] && export UNDERLAY="/opt/ws_rmw_zenoh/install" ; [[ -n ${{ inputs.git-https-server }} ]] && git config --global url.https://${{ inputs.git-https-user }}:${{ inputs.git-https-password }}@${{ inputs.git-https-server }}.insteadOf https://${{ inputs.git-https-server }}' - SSH_PRIVATE_KEY: ${{ inputs.git-ssh-private-key }} - SSH_SERVER_HOSTKEYS: ${{ inputs.git-ssh-known-host-keys }} - DOCKER_RUN_OPTS: -u root:root DOCKER_IMAGE: ${{ steps.build-images.outputs.INDUSTRIAL_CI_IMAGE }} DOCKER_PULL: false + DOCKER_RUN_OPTS: -u root:root + SSH_PRIVATE_KEY: ${{ inputs.git-ssh-private-key }} + SSH_SERVER_HOSTKEYS: ${{ inputs.git-ssh-known-host-keys }} + TARGET_WORKSPACE: ${{ inputs.build-context }} + UPSTREAM_WORKSPACE: ${{ inputs.build-context }}/.repos - name: Slugify ref name id: slugify-ref-name @@ -281,40 +310,45 @@ runs: working-directory: ${{ inputs.build-context }} run: docker/docker-ros/scripts/ci.sh env: - PLATFORM: ${{ inputs.platform }} - TARGET: ${{ inputs.target }} + _ENABLE_IMAGE_PUSH: true + _IMAGE_POSTFIX: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) && format('_{0}_ci', steps.slugify-ref-name.outputs.slug) || '' }} + ADDITIONAL_DEBS_FILE: ${{ inputs.additional-debs-file }} + ADDITIONAL_FILES_DIR: ${{ inputs.additional-files-dir }} + ADDITIONAL_PIP_FILE: ${{ inputs.additional-pip-file }} BASE_IMAGE: ${{ inputs.base-image }} + BLACKLISTED_PACKAGES_FILE: ${{ inputs.blacklisted-packages-file }} + BUILD_IMAGE_NAME: ${{ steps.build-image-name.outputs.lowercase }} + BUILD_IMAGE_TAG: ${{ inputs.build-image-tag }} COMMAND: ${{ inputs.command }} - IMAGE_NAME: ${{ steps.image-name.outputs.lowercase }} - IMAGE_TAG: ${{ inputs.image-tag }} + CUSTOM_SCRIPT_FILE: ${{ inputs.custom-script-file }} DEV_IMAGE_NAME: ${{ steps.dev-image-name.outputs.lowercase }} DEV_IMAGE_TAG: ${{ inputs.dev-image-tag }} - SLIM_IMAGE_NAME: ${{ steps.slim-image-name.outputs.lowercase }} - SLIM_IMAGE_TAG: ${{ inputs.slim-image-tag }} - ENABLE_SLIM: ${{ inputs.enable-slim }} - SLIM_BUILD_ARGS: ${{ inputs.slim-build-args }} - ENABLE_SINGLEARCH_PUSH: ${{ inputs.enable-singlearch-push }} - RMW_IMPLEMENTATION: ${{ inputs.rmw-implementation }} - ROS_DISTRO: ${{ inputs.ros-distro }} DISABLE_ROS_INSTALLATION: ${{ inputs.disable-ros-installation }} - GIT_HTTPS_SERVER: ${{ inputs.git-https-server }} - GIT_HTTPS_USER: ${{ inputs.git-https-user }} - GIT_HTTPS_PASSWORD: ${{ inputs.git-https-password }} - GIT_SSH_PRIVATE_KEY: ${{ inputs.git-ssh-private-key }} - GIT_SSH_KNOWN_HOST_KEYS: ${{ inputs.git-ssh-known-host-keys }} - ADDITIONAL_DEBS_FILE: ${{ inputs.additional-debs-file }} + ENABLE_CONTINUE_BUILD_DESPITE_ERRORS: ${{ inputs.enable-continue-build-despite-errors }} + ENABLE_CONTINUE_ROSDEP_INSTALL_DESPITE_ERRORS: ${{ inputs.enable-continue-rosdep-install-despite-errors }} ENABLE_RECURSIVE_ADDITIONAL_DEBS: ${{ inputs.enable-recursive-additional-debs }} - ADDITIONAL_FILES_DIR: ${{ inputs.additional-files-dir }} - ADDITIONAL_PIP_FILE: ${{ inputs.additional-pip-file }} ENABLE_RECURSIVE_ADDITIONAL_PIP: ${{ inputs.enable-recursive-additional-pip }} - BLACKLISTED_PACKAGES_FILE: ${{ inputs.blacklisted-packages-file }} ENABLE_RECURSIVE_BLACKLISTED_PACKAGES: ${{ inputs.enable-recursive-blacklisted-packages }} - CUSTOM_SCRIPT_FILE: ${{ inputs.custom-script-file }} ENABLE_RECURSIVE_CUSTOM_SCRIPT: ${{ inputs.enable-recursive-custom-script }} - VCS_IMPORT_FILE: ${{ inputs.vcs-import-file }} ENABLE_RECURSIVE_VCS_IMPORT: ${{ inputs.enable-recursive-vcs-import }} - _ENABLE_IMAGE_PUSH: true - _IMAGE_POSTFIX: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) && format('_{0}_ci', steps.slugify-ref-name.outputs.slug) || '' }} + ENABLE_ROS1_DEVEL_SPACE: ${{ inputs.enable-ros1-devel-space }} + ENABLE_SINGLEARCH_PUSH: ${{ inputs.enable-singlearch-push }} + ENABLE_SLIM: ${{ inputs.enable-slim }} + GIT_HTTPS_PASSWORD: ${{ inputs.git-https-password }} + GIT_HTTPS_SERVER: ${{ inputs.git-https-server }} + GIT_HTTPS_USER: ${{ inputs.git-https-user }} + GIT_SSH_KNOWN_HOST_KEYS: ${{ inputs.git-ssh-known-host-keys }} + GIT_SSH_PRIVATE_KEY: ${{ inputs.git-ssh-private-key }} + IMAGE_NAME: ${{ steps.image-name.outputs.lowercase }} + IMAGE_TAG: ${{ inputs.image-tag }} + PLATFORM: ${{ inputs.platform }} + RMW_IMPLEMENTATION: ${{ inputs.rmw-implementation }} + ROS_DISTRO: ${{ inputs.ros-distro }} + SLIM_BUILD_ARGS: ${{ inputs.slim-build-args }} + SLIM_IMAGE_NAME: ${{ steps.slim-image-name.outputs.lowercase }} + SLIM_IMAGE_TAG: ${{ inputs.slim-image-tag }} + TARGET: ${{ inputs.target }} + VCS_IMPORT_FILE: ${{ inputs.vcs-import-file }} - name: Push images (as latest) if: ${{ inputs.enable-push-as-latest == 'true' }} @@ -322,37 +356,42 @@ runs: working-directory: ${{ inputs.build-context }} run: docker/docker-ros/scripts/ci.sh env: - PLATFORM: ${{ inputs.platform }} - TARGET: ${{ inputs.target }} + _ENABLE_IMAGE_PUSH: true + _IMAGE_POSTFIX: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) && format('_{0}_ci', steps.slugify-ref-name.outputs.slug) || '' }} + ADDITIONAL_DEBS_FILE: ${{ inputs.additional-debs-file }} + ADDITIONAL_FILES_DIR: ${{ inputs.additional-files-dir }} + ADDITIONAL_PIP_FILE: ${{ inputs.additional-pip-file }} BASE_IMAGE: ${{ inputs.base-image }} + BLACKLISTED_PACKAGES_FILE: ${{ inputs.blacklisted-packages-file }} + BUILD_IMAGE_NAME: ${{ steps.build-image-name.outputs.lowercase }} + BUILD_IMAGE_TAG: ${{ inputs.build-image-tag }} COMMAND: ${{ inputs.command }} - IMAGE_NAME: ${{ steps.image-name.outputs.lowercase }} - IMAGE_TAG: latest + CUSTOM_SCRIPT_FILE: ${{ inputs.custom-script-file }} DEV_IMAGE_NAME: ${{ steps.dev-image-name.outputs.lowercase }} DEV_IMAGE_TAG: latest-dev - SLIM_IMAGE_NAME: ${{ steps.slim-image-name.outputs.lowercase }} - SLIM_IMAGE_TAG: latest-slim - ENABLE_SLIM: ${{ inputs.enable-slim }} - SLIM_BUILD_ARGS: ${{ inputs.slim-build-args }} - ENABLE_SINGLEARCH_PUSH: ${{ inputs.enable-singlearch-push }} - RMW_IMPLEMENTATION: ${{ inputs.rmw-implementation }} - ROS_DISTRO: ${{ inputs.ros-distro }} DISABLE_ROS_INSTALLATION: ${{ inputs.disable-ros-installation }} - GIT_HTTPS_SERVER: ${{ inputs.git-https-server }} - GIT_HTTPS_USER: ${{ inputs.git-https-user }} - GIT_HTTPS_PASSWORD: ${{ inputs.git-https-password }} - GIT_SSH_PRIVATE_KEY: ${{ inputs.git-ssh-private-key }} - GIT_SSH_KNOWN_HOST_KEYS: ${{ inputs.git-ssh-known-host-keys }} - ADDITIONAL_DEBS_FILE: ${{ inputs.additional-debs-file }} + ENABLE_CONTINUE_BUILD_DESPITE_ERRORS: ${{ inputs.enable-continue-build-despite-errors }} + ENABLE_CONTINUE_ROSDEP_INSTALL_DESPITE_ERRORS: ${{ inputs.enable-continue-rosdep-install-despite-errors }} ENABLE_RECURSIVE_ADDITIONAL_DEBS: ${{ inputs.enable-recursive-additional-debs }} - ADDITIONAL_FILES_DIR: ${{ inputs.additional-files-dir }} - ADDITIONAL_PIP_FILE: ${{ inputs.additional-pip-file }} ENABLE_RECURSIVE_ADDITIONAL_PIP: ${{ inputs.enable-recursive-additional-pip }} - BLACKLISTED_PACKAGES_FILE: ${{ inputs.blacklisted-packages-file }} ENABLE_RECURSIVE_BLACKLISTED_PACKAGES: ${{ inputs.enable-recursive-blacklisted-packages }} - CUSTOM_SCRIPT_FILE: ${{ inputs.custom-script-file }} ENABLE_RECURSIVE_CUSTOM_SCRIPT: ${{ inputs.enable-recursive-custom-script }} - VCS_IMPORT_FILE: ${{ inputs.vcs-import-file }} ENABLE_RECURSIVE_VCS_IMPORT: ${{ inputs.enable-recursive-vcs-import }} - _ENABLE_IMAGE_PUSH: true - _IMAGE_POSTFIX: ${{ github.ref != format('refs/heads/{0}', github.event.repository.default_branch) && format('_{0}_ci', steps.slugify-ref-name.outputs.slug) || '' }} + ENABLE_ROS1_DEVEL_SPACE: ${{ inputs.enable-ros1-devel-space }} + ENABLE_SINGLEARCH_PUSH: ${{ inputs.enable-singlearch-push }} + ENABLE_SLIM: ${{ inputs.enable-slim }} + GIT_HTTPS_PASSWORD: ${{ inputs.git-https-password }} + GIT_HTTPS_SERVER: ${{ inputs.git-https-server }} + GIT_HTTPS_USER: ${{ inputs.git-https-user }} + GIT_SSH_KNOWN_HOST_KEYS: ${{ inputs.git-ssh-known-host-keys }} + GIT_SSH_PRIVATE_KEY: ${{ inputs.git-ssh-private-key }} + IMAGE_NAME: ${{ steps.image-name.outputs.lowercase }} + IMAGE_TAG: latest + PLATFORM: ${{ inputs.platform }} + RMW_IMPLEMENTATION: ${{ inputs.rmw-implementation }} + ROS_DISTRO: ${{ inputs.ros-distro }} + SLIM_BUILD_ARGS: ${{ inputs.slim-build-args }} + SLIM_IMAGE_NAME: ${{ steps.slim-image-name.outputs.lowercase }} + SLIM_IMAGE_TAG: latest-slim + TARGET: ${{ inputs.target }} + VCS_IMPORT_FILE: ${{ inputs.vcs-import-file }} diff --git a/docker/Dockerfile b/docker/Dockerfile index 757c9ba..9911584 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -34,6 +34,9 @@ RUN apt-get update && \ git \ python3-rosdep \ python3-vcstool && \ + if [[ "$ROS_DISTRO" == "noetic" ]]; then \ + apt-get install -y python3-catkin-tools; \ + fi && \ if [[ "$DISABLE_ROS_INSTALLATION" != "true" ]]; then \ apt-get install -y ros-${ROS_DISTRO}-ros-core; \ fi && \ @@ -75,17 +78,26 @@ RUN if [[ $ENABLE_RECURSIVE_VCS_IMPORT == 'true' ]]; then \ # remove blacklisted packages from workspace ARG BLACKLISTED_PACKAGES_FILE="docker/blacklisted-packages.txt" ARG ENABLE_RECURSIVE_BLACKLISTED_PACKAGES="false" -RUN echo "colcon list -p --base-paths src/ --packages-select \\" >> $WORKSPACE/.remove-packages.sh && \ +RUN if [[ -x "$(command -v colcon)" ]]; then \ + echo "colcon list -p --base-paths src/ --packages-select \\" >> $WORKSPACE/.remove-packages.sh ; \ + elif [[ -x "$(command -v catkin)" ]]; then \ + echo "for pkg in \\" >> $WORKSPACE/.remove-packages.sh ; \ + fi && \ if [[ $ENABLE_RECURSIVE_BLACKLISTED_PACKAGES == 'true' ]]; then \ find . -type f -name $(basename ${BLACKLISTED_PACKAGES_FILE}) -exec sed '$a\' {} \; | awk '{print " " $0 " \\"}' >> $WORKSPACE/.remove-packages.sh ; \ elif [[ -f src/target/${BLACKLISTED_PACKAGES_FILE} ]]; then \ cat src/target/${BLACKLISTED_PACKAGES_FILE} | awk '{print " " $0 " \\"}' >> $WORKSPACE/.remove-packages.sh ; \ fi && \ - echo ";" >> $WORKSPACE/.remove-packages.sh && \ + if [[ -x "$(command -v colcon)" ]]; then \ + echo ";" >> $WORKSPACE/.remove-packages.sh ; \ + elif [[ -x "$(command -v catkin)" ]]; then \ + echo "; do find . -type f -name package.xml -path \"*/\$pkg/package.xml\" -exec dirname {} \;; done" >> $WORKSPACE/.remove-packages.sh ; \ + fi && \ chmod +x $WORKSPACE/.remove-packages.sh && \ - $WORKSPACE/.remove-packages.sh 2> /dev/null | xargs rm -rf + $WORKSPACE/.remove-packages.sh 2> /dev/null | xargs rm -rfv # create install script with list of rosdep dependencies +ARG ENABLE_CONTINUE_ROSDEP_INSTALL_DESPITE_ERRORS="false" RUN echo "set -e" >> $WORKSPACE/.install-dependencies.sh && \ source /opt/ros/$ROS_DISTRO/setup.bash && \ apt-get update && \ @@ -94,9 +106,11 @@ RUN echo "set -e" >> $WORKSPACE/.install-dependencies.sh && \ export OS="ubuntu:$(lsb_release -c | awk '{print $2}')" && \ if [[ "$ROS_DISTRO" = "rolling" && "$OS" = "ubuntu:focal" ]]; then export OS="ubuntu:jammy"; fi && \ set -o pipefail && \ - ROS_PACKAGE_PATH=$(pwd):$ROS_PACKAGE_PATH rosdep install --os $OS -y --simulate --from-paths src --ignore-src \ - | sed -E "s/'apt-get install -y ([^']+)' \(alternative 1\/1\)/apt-get install -y \1/" \ - | tee -a $WORKSPACE/.install-dependencies.sh && \ + if [[ $ENABLE_CONTINUE_ROSDEP_INSTALL_DESPITE_ERRORS == 'true' ]]; then \ + ROS_PACKAGE_PATH=$(pwd):$ROS_PACKAGE_PATH rosdep install --os $OS -y --simulate --from-paths src --ignore-src -r | sed -E "s/'apt-get install -y ([^']+)' \(alternative 1\/1\)/apt-get install -y \1/" | tee -a $WORKSPACE/.install-dependencies.sh ; \ + else \ + ROS_PACKAGE_PATH=$(pwd):$ROS_PACKAGE_PATH rosdep install --os $OS -y --simulate --from-paths src --ignore-src | sed -E "s/'apt-get install -y ([^']+)' \(alternative 1\/1\)/apt-get install -y \1/" | tee -a $WORKSPACE/.install-dependencies.sh ; \ + fi && \ chmod +x $WORKSPACE/.install-dependencies.sh && \ rm -rf /var/lib/apt/lists/* @@ -243,7 +257,9 @@ RUN source /opt/ros/$ROS_DISTRO/setup.bash && \ fi # source ROS -RUN echo "source /opt/ros/$ROS_DISTRO/setup.bash" >> ~/.bashrc +RUN echo "source /opt/ros/$ROS_DISTRO/setup.bash" >> ~/.bashrc && \ + echo "[[ -f $WORKSPACE/devel/setup.bash ]] && source $WORKSPACE/devel/setup.bash" >> ~/.bashrc && \ + echo "[[ -f $WORKSPACE/install/setup.bash ]] && source $WORKSPACE/install/setup.bash" >> ~/.bashrc # set entrypoint ENV TINI_VERSION=v0.19.0 @@ -264,23 +280,38 @@ CMD ["bash"] FROM dev AS build # build ROS workspace -RUN if [[ -x "$(command -v colcon)" ]]; then \ - source /opt/ros/${ROS_DISTRO}/setup.bash && \ - [[ -f /opt/ws_rmw_zenoh/install/setup.bash ]] && source /opt/ws_rmw_zenoh/install/setup.bash ; \ - colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release ; \ +ARG ENABLE_CONTINUE_BUILD_DESPITE_ERRORS="false" +ARG ENABLE_ROS1_DEVEL_SPACE="false" +RUN source /opt/ros/${ROS_DISTRO}/setup.bash && \ + if [[ -x "$(command -v colcon)" ]]; then \ + [[ -f /opt/ws_rmw_zenoh/install/setup.bash ]] && source /opt/ws_rmw_zenoh/install/setup.bash && \ + if [[ $ENABLE_CONTINUE_BUILD_DESPITE_ERRORS == 'true' ]]; then \ + colcon build --continue-on-error --cmake-args -DCMAKE_BUILD_TYPE=Release || true ; \ + else \ + colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release ; \ + fi ; \ elif [[ -x "$(command -v catkin)" ]]; then \ - catkin config --install --extend /opt/ros/${ROS_DISTRO} && \ - catkin build -DCMAKE_BUILD_TYPE=Release --force-color --no-status --summarize ; \ + if [[ $ENABLE_ROS1_DEVEL_SPACE == 'false' ]]; then \ + catkin config --install --extend /opt/ros/${ROS_DISTRO} ; \ + fi && \ + if [[ $ENABLE_CONTINUE_BUILD_DESPITE_ERRORS == 'true' ]]; then \ + catkin build -DCMAKE_BUILD_TYPE=Release --force-color --no-status --summarize --continue-on-failure || true ; \ + else \ + catkin build -DCMAKE_BUILD_TYPE=Release --force-color --no-status --summarize ; \ + fi ; \ fi +# setup command +ARG COMMAND=bash +ENV DEFAULT_CMD=${COMMAND} +CMD bash -c "${DEFAULT_CMD}" + ############ run ############################################################### FROM dependencies-install AS run # copy ROS install space from build stage COPY --from=build $WORKSPACE/install install RUN ldconfig -RUN echo "[[ -f $WORKSPACE/devel/setup.bash ]] && source $WORKSPACE/devel/setup.bash" >> ~/.bashrc && \ - echo "[[ -f $WORKSPACE/install/setup.bash ]] && source $WORKSPACE/install/setup.bash" >> ~/.bashrc # setup command ARG COMMAND diff --git a/scripts/build.sh b/scripts/build.sh index 0830164..4cd249e 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -17,25 +17,28 @@ build_image() { $(if [[ "${_ENABLE_IMAGE_PUSH}" == "true" ]]; then echo "--push"; else echo "--load"; fi) \ --build-arg BASE_IMAGE="${BASE_IMAGE}" \ --build-arg COMMAND="${COMMAND}" \ - $(if [[ -n "${RMW_IMPLEMENTATION}" ]]; then echo "--build-arg RMW_IMPLEMENTATION=${RMW_IMPLEMENTATION}"; fi) \ - $(if [[ -n "${ROS_DISTRO}" ]]; then echo "--build-arg ROS_DISTRO=${ROS_DISTRO}"; fi) \ - $(if [[ -n "${DISABLE_ROS_INSTALLATION}" ]]; then echo "--build-arg DISABLE_ROS_INSTALLATION=${DISABLE_ROS_INSTALLATION}"; fi) \ - $(if [[ -n "${GIT_HTTPS_SERVER}" ]]; then echo "--build-arg GIT_HTTPS_SERVER=${GIT_HTTPS_SERVER}"; fi) \ - $(if [[ -n "${GIT_HTTPS_USER}" ]]; then echo "--build-arg GIT_HTTPS_USER=${GIT_HTTPS_USER}"; fi) \ - $(if [[ -n "${GIT_HTTPS_PASSWORD}" ]]; then echo "--build-arg GIT_HTTPS_PASSWORD=${GIT_HTTPS_PASSWORD}"; fi) \ - $(if [[ -n "${GIT_SSH_PRIVATE_KEY}" ]]; then echo "--build-arg GIT_SSH_PRIVATE_KEY=${GIT_SSH_PRIVATE_KEY}"; fi) \ - $(if [[ -n "${GIT_SSH_KNOWN_HOST_KEYS}" ]]; then echo "--build-arg GIT_SSH_KNOWN_HOST_KEYS=${GIT_SSH_KNOWN_HOST_KEYS}"; fi) \ $(if [[ -n "${ADDITIONAL_DEBS_FILE}" ]]; then echo "--build-arg ADDITIONAL_DEBS_FILE=${ADDITIONAL_DEBS_FILE}"; fi) \ - $(if [[ -n "${ENABLE_RECURSIVE_ADDITIONAL_DEBS}" ]]; then echo "--build-arg ENABLE_RECURSIVE_ADDITIONAL_DEBS=${ENABLE_RECURSIVE_ADDITIONAL_DEBS}"; fi) \ $(if [[ -n "${ADDITIONAL_FILES_DIR}" ]]; then echo "--build-arg ADDITIONAL_FILES_DIR=${ADDITIONAL_FILES_DIR}"; fi) \ $(if [[ -n "${ADDITIONAL_PIP_FILE}" ]]; then echo "--build-arg ADDITIONAL_PIP_FILE=${ADDITIONAL_PIP_FILE}"; fi) \ - $(if [[ -n "${ENABLE_RECURSIVE_ADDITIONAL_PIP}" ]]; then echo "--build-arg ENABLE_RECURSIVE_ADDITIONAL_PIP=${ENABLE_RECURSIVE_ADDITIONAL_PIP}"; fi) \ $(if [[ -n "${BLACKLISTED_PACKAGES_FILE}" ]]; then echo "--build-arg BLACKLISTED_PACKAGES_FILE=${BLACKLISTED_PACKAGES_FILE}"; fi) \ - $(if [[ -n "${ENABLE_RECURSIVE_BLACKLISTED_PACKAGES}" ]]; then echo "--build-arg ENABLE_RECURSIVE_BLACKLISTED_PACKAGES=${ENABLE_RECURSIVE_BLACKLISTED_PACKAGES}"; fi) \ $(if [[ -n "${CUSTOM_SCRIPT_FILE}" ]]; then echo "--build-arg CUSTOM_SCRIPT_FILE=${CUSTOM_SCRIPT_FILE}"; fi) \ + $(if [[ -n "${DISABLE_ROS_INSTALLATION}" ]]; then echo "--build-arg DISABLE_ROS_INSTALLATION=${DISABLE_ROS_INSTALLATION}"; fi) \ + $(if [[ -n "${ENABLE_CONTINUE_BUILD_DESPITE_ERRORS}" ]]; then echo "--build-arg ENABLE_CONTINUE_BUILD_DESPITE_ERRORS=${ENABLE_CONTINUE_BUILD_DESPITE_ERRORS}"; fi) \ + $(if [[ -n "${ENABLE_CONTINUE_ROSDEP_INSTALL_DESPITE_ERRORS}" ]]; then echo "--build-arg ENABLE_CONTINUE_ROSDEP_INSTALL_DESPITE_ERRORS=${ENABLE_CONTINUE_ROSDEP_INSTALL_DESPITE_ERRORS}"; fi) \ + $(if [[ -n "${ENABLE_RECURSIVE_ADDITIONAL_DEBS}" ]]; then echo "--build-arg ENABLE_RECURSIVE_ADDITIONAL_DEBS=${ENABLE_RECURSIVE_ADDITIONAL_DEBS}"; fi) \ + $(if [[ -n "${ENABLE_RECURSIVE_ADDITIONAL_PIP}" ]]; then echo "--build-arg ENABLE_RECURSIVE_ADDITIONAL_PIP=${ENABLE_RECURSIVE_ADDITIONAL_PIP}"; fi) \ + $(if [[ -n "${ENABLE_RECURSIVE_BLACKLISTED_PACKAGES}" ]]; then echo "--build-arg ENABLE_RECURSIVE_BLACKLISTED_PACKAGES=${ENABLE_RECURSIVE_BLACKLISTED_PACKAGES}"; fi) \ $(if [[ -n "${ENABLE_RECURSIVE_CUSTOM_SCRIPT}" ]]; then echo "--build-arg ENABLE_RECURSIVE_CUSTOM_SCRIPT=${ENABLE_RECURSIVE_CUSTOM_SCRIPT}"; fi) \ - $(if [[ -n "${VCS_IMPORT_FILE}" ]]; then echo "--build-arg VCS_IMPORT_FILE=${VCS_IMPORT_FILE}"; fi) \ $(if [[ -n "${ENABLE_RECURSIVE_VCS_IMPORT}" ]]; then echo "--build-arg ENABLE_RECURSIVE_VCS_IMPORT=${ENABLE_RECURSIVE_VCS_IMPORT}"; fi) \ + $(if [[ -n "${ENABLE_ROS1_DEVEL_SPACE}" ]]; then echo "--build-arg ENABLE_ROS1_DEVEL_SPACE=${ENABLE_ROS1_DEVEL_SPACE}"; fi) \ + $(if [[ -n "${GIT_HTTPS_PASSWORD}" ]]; then echo "--build-arg GIT_HTTPS_PASSWORD=${GIT_HTTPS_PASSWORD}"; fi) \ + $(if [[ -n "${GIT_HTTPS_SERVER}" ]]; then echo "--build-arg GIT_HTTPS_SERVER=${GIT_HTTPS_SERVER}"; fi) \ + $(if [[ -n "${GIT_HTTPS_USER}" ]]; then echo "--build-arg GIT_HTTPS_USER=${GIT_HTTPS_USER}"; fi) \ + $(if [[ -n "${GIT_SSH_KNOWN_HOST_KEYS}" ]]; then echo "--build-arg GIT_SSH_KNOWN_HOST_KEYS=${GIT_SSH_KNOWN_HOST_KEYS}"; fi) \ + $(if [[ -n "${GIT_SSH_PRIVATE_KEY}" ]]; then echo "--build-arg GIT_SSH_PRIVATE_KEY=${GIT_SSH_PRIVATE_KEY}"; fi) \ + $(if [[ -n "${RMW_IMPLEMENTATION}" ]]; then echo "--build-arg RMW_IMPLEMENTATION=${RMW_IMPLEMENTATION}"; fi) \ + $(if [[ -n "${ROS_DISTRO}" ]]; then echo "--build-arg ROS_DISTRO=${ROS_DISTRO}"; fi) \ + $(if [[ -n "${VCS_IMPORT_FILE}" ]]; then echo "--build-arg VCS_IMPORT_FILE=${VCS_IMPORT_FILE}"; fi) \ . echo "Successfully built stage '${TARGET}' for platform '${PLATFORM}' as '${IMAGE}'" } diff --git a/scripts/ci.sh b/scripts/ci.sh index 8679a10..46bac52 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -14,43 +14,50 @@ require_var "BASE_IMAGE" require_var "IMAGE_NAME" IMAGE_TAG="${IMAGE_TAG:-latest}" [[ "${TARGET}" == *"run"* ]] && require_var "COMMAND" +BUILD_IMAGE_NAME="${BUILD_IMAGE_NAME:-${IMAGE_NAME}}" +BUILD_IMAGE_TAG="${BUILD_IMAGE_TAG:-${IMAGE_TAG}-build}" DEV_IMAGE_NAME="${DEV_IMAGE_NAME:-${IMAGE_NAME}}" DEV_IMAGE_TAG="${DEV_IMAGE_TAG:-${IMAGE_TAG}-dev}" SLIM_IMAGE_NAME="${SLIM_IMAGE_NAME:-${IMAGE_NAME}}" SLIM_IMAGE_TAG="${SLIM_IMAGE_TAG:-${IMAGE_TAG}-slim}" -IMAGE="${IMAGE_NAME}:${IMAGE_TAG}" -DEV_IMAGE="${DEV_IMAGE_NAME}:${DEV_IMAGE_TAG}" -SLIM_IMAGE="${SLIM_IMAGE_NAME}:${SLIM_IMAGE_TAG}" -ENABLE_SLIM="${ENABLE_SLIM:-true}" -SLIM_BUILD_ARGS="${SLIM_BUILD_ARGS:-'--sensor-ipc-mode proxy --continue-after=10 --show-clogs --http-probe=false'}" -ENABLE_SINGLEARCH_PUSH="${ENABLE_SINGLEARCH_PUSH:-false}" -RMW_IMPLEMENTATION="${RMW_IMPLEMENTATION:-}" -ROS_DISTRO="${ROS_DISTRO:-}" -DISABLE_ROS_INSTALLATION="${DISABLE_ROS_INSTALLATION:-}" -GIT_HTTPS_SERVER="${GIT_HTTPS_SERVER:-}" -GIT_HTTPS_USER="${GIT_HTTPS_USER:-}" -GIT_HTTPS_PASSWORD="${GIT_HTTPS_PASSWORD:-}" -GIT_SSH_PRIVATE_KEY="${GIT_SSH_PRIVATE_KEY:-}" -GIT_SSH_KNOWN_HOST_KEYS="${GIT_SSH_KNOWN_HOST_KEYS:-}" +_ENABLE_IMAGE_PUSH="${_ENABLE_IMAGE_PUSH:-false}" +_IMAGE_POSTFIX="${_IMAGE_POSTFIX:-""}" ADDITIONAL_DEBS_FILE="${ADDITIONAL_DEBS_FILE:-}" -ENABLE_RECURSIVE_ADDITIONAL_DEBS="${ENABLE_RECURSIVE_ADDITIONAL_DEBS:-}" ADDITIONAL_FILES_DIR="${ADDITIONAL_FILES_DIR:-}" ADDITIONAL_PIP_FILE="${ADDITIONAL_PIP_FILE:-}" -ENABLE_RECURSIVE_ADDITIONAL_PIP="${ENABLE_RECURSIVE_ADDITIONAL_PIP:-}" BLACKLISTED_PACKAGES_FILE="${BLACKLISTED_PACKAGES_FILE:-}" -ENABLE_RECURSIVE_BLACKLISTED_PACKAGES="${ENABLE_RECURSIVE_BLACKLISTED_PACKAGES:-}" +BUILD_IMAGE="${BUILD_IMAGE_NAME}:${BUILD_IMAGE_TAG}" CUSTOM_SCRIPT_FILE="${CUSTOM_SCRIPT_FILE:-}" +DEV_IMAGE="${DEV_IMAGE_NAME}:${DEV_IMAGE_TAG}" +DISABLE_ROS_INSTALLATION="${DISABLE_ROS_INSTALLATION:-}" +ENABLE_CONTINUE_BUILD_DESPITE_ERRORS="${ENABLE_CONTINUE_BUILD_DESPITE_ERRORS:-}" +ENABLE_CONTINUE_ROSDEP_INSTALL_DESPITE_ERRORS="${ENABLE_CONTINUE_ROSDEP_INSTALL_DESPITE_ERRORS:-}" +ENABLE_RECURSIVE_ADDITIONAL_DEBS="${ENABLE_RECURSIVE_ADDITIONAL_DEBS:-}" +ENABLE_RECURSIVE_ADDITIONAL_PIP="${ENABLE_RECURSIVE_ADDITIONAL_PIP:-}" +ENABLE_RECURSIVE_BLACKLISTED_PACKAGES="${ENABLE_RECURSIVE_BLACKLISTED_PACKAGES:-}" ENABLE_RECURSIVE_CUSTOM_SCRIPT="${ENABLE_RECURSIVE_CUSTOM_SCRIPT:-}" -VCS_IMPORT_FILE="${VCS_IMPORT_FILE:-}" ENABLE_RECURSIVE_VCS_IMPORT="${ENABLE_RECURSIVE_VCS_IMPORT:-}" -_ENABLE_IMAGE_PUSH="${_ENABLE_IMAGE_PUSH:-false}" -_IMAGE_POSTFIX="${_IMAGE_POSTFIX:-""}" +ENABLE_ROS1_DEVEL_SPACE="${ENABLE_ROS1_DEVEL_SPACE:-}" +ENABLE_SINGLEARCH_PUSH="${ENABLE_SINGLEARCH_PUSH:-false}" +ENABLE_SLIM="${ENABLE_SLIM:-true}" +GIT_HTTPS_PASSWORD="${GIT_HTTPS_PASSWORD:-}" +GIT_HTTPS_SERVER="${GIT_HTTPS_SERVER:-}" +GIT_HTTPS_USER="${GIT_HTTPS_USER:-}" +GIT_SSH_KNOWN_HOST_KEYS="${GIT_SSH_KNOWN_HOST_KEYS:-}" +GIT_SSH_PRIVATE_KEY="${GIT_SSH_PRIVATE_KEY:-}" +IMAGE="${IMAGE_NAME}:${IMAGE_TAG}" +RMW_IMPLEMENTATION="${RMW_IMPLEMENTATION:-}" +ROS_DISTRO="${ROS_DISTRO:-}" +SLIM_BUILD_ARGS="${SLIM_BUILD_ARGS:-'--sensor-ipc-mode proxy --continue-after=10 --show-clogs --http-probe=false'}" +SLIM_IMAGE="${SLIM_IMAGE_NAME}:${SLIM_IMAGE_TAG}" +VCS_IMPORT_FILE="${VCS_IMPORT_FILE:-}" # write image name for industrial_ci to output (GitHub-only) if [[ -n "${GITHUB_ACTIONS}" ]]; then industrial_ci_image="${IMAGE}" [[ "${TARGET}" == *"dev"* ]] && industrial_ci_image="${DEV_IMAGE}" + [[ "${TARGET}" == *"build"* ]] && industrial_ci_image="${BUILD_IMAGE}" [[ -n "${_IMAGE_POSTFIX}" ]] && industrial_ci_image="${industrial_ci_image}${_IMAGE_POSTFIX}" if [[ "${PLATFORM}" != *","* ]]; then industrial_ci_image="${industrial_ci_image}-${PLATFORM}" @@ -82,6 +89,7 @@ for PLATFORM in "${PLATFORMS[@]}"; do open_log_group "Build ${TARGET} image (${PLATFORM})" image="${IMAGE}" [[ "${TARGET}" == "dev" ]] && image="${DEV_IMAGE}" + [[ "${TARGET}" == "build" ]] && image="${BUILD_IMAGE}" [[ -n "${_IMAGE_POSTFIX}" ]] && image="${image}${_IMAGE_POSTFIX}" [[ "${_ENABLE_IMAGE_PUSH}" != "true" || "${ENABLE_SINGLEARCH_PUSH}" == "true" ]] && image="${image}-${PLATFORM}" IMAGE="${image}" build_image