├── industrial_ci ├── mockups │ ├── CATKIN_IGNORE │ ├── test_clang_tidy │ │ ├── src │ │ │ └── test_clang_tidy.cpp │ │ ├── .clang-tidy │ │ ├── package.xml │ │ └── CMakeLists.txt │ ├── industrial_ci_testpkg │ │ ├── src │ │ │ └── test_compiler.cpp │ │ ├── CHANGELOG.rst │ │ ├── test │ │ │ └── example_ros.test │ │ ├── CMakeLists.txt │ │ └── package.xml │ ├── format_tests │ │ └── cpp │ │ │ ├── LLVM │ │ │ └── example file.cpp │ │ │ └── WebKit │ │ │ ├── example file.cpp │ │ │ └── .clang-format │ ├── failing_test │ │ ├── CMakeLists.txt │ │ ├── test │ │ │ └── no_talker.test │ │ └── package.xml │ └── testpkg_broken_install │ │ ├── script │ │ └── sample_talker.py │ │ ├── package.xml │ │ └── CMakeLists.txt ├── python │ └── industrial_ci │ │ ├── __init__.py │ │ └── travis.py ├── setup.py ├── src │ ├── tests │ │ ├── black_check.sh │ │ ├── clang_format_check.sh │ │ ├── merge_fixes.py │ │ ├── debians.sh │ │ ├── ros_prerelease.sh │ │ ├── abi_check.sh │ │ └── source_tests.sh │ ├── folding │ │ ├── github_actions.sh │ │ ├── none.sh │ │ ├── gitlab.sh │ │ ├── quiet.sh │ │ └── travis.sh │ ├── builders │ │ ├── catkin_make_devel.sh │ │ ├── catkin_tools_isolated.sh │ │ ├── catkin_make_isolated_devel.sh │ │ ├── catkin_tools_devel.sh │ │ ├── catkin_tools_isolated_devel.sh │ │ ├── catkin_make.sh │ │ ├── catkin_make_isolated.sh │ │ ├── catkin_tools.sh │ │ └── colcon.sh │ ├── isolation │ │ ├── docker.env │ │ ├── shell.sh │ │ └── docker.sh │ ├── run.sh │ ├── keys │ │ ├── ros.asc │ │ └── snapshots.asc │ ├── ci_main.sh │ ├── env.sh │ ├── deprecated.sh │ ├── ros.sh │ └── util.sh ├── scripts │ ├── run_travis │ ├── run_ci │ └── rerun_ci ├── CMakeLists.txt ├── package.xml └── CHANGELOG.rst ├── .ci.rosinstall.kinetic ├── .travis.rosinstall ├── .github ├── action.js ├── action.sh └── workflows │ └── main.yml ├── action.yml ├── .travis.yml ├── ci.sh ├── bitbucket.sh ├── doc ├── .travis.yml ├── industrial_ci_action.yml └── migration_guide.md ├── gitlab.sh ├── travis.sh ├── .gitignore ├── .gitlab-ci.yml ├── README.rst └── LICENSE /industrial_ci/mockups/CATKIN_IGNORE: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /industrial_ci/python/industrial_ci/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /industrial_ci/mockups/test_clang_tidy/src/test_clang_tidy.cpp: -------------------------------------------------------------------------------- 1 | int *a = 0; 2 | -------------------------------------------------------------------------------- /industrial_ci/mockups/industrial_ci_testpkg/src/test_compiler.cpp: -------------------------------------------------------------------------------- 1 | #warning "Create compiler warning" 2 | -------------------------------------------------------------------------------- /.ci.rosinstall.kinetic: -------------------------------------------------------------------------------- 1 | - git: 2 | uri: https://github.com/ros/actionlib.git 3 | local-name: ros/actionlib 4 | version: indigo-devel 5 | -------------------------------------------------------------------------------- /industrial_ci/mockups/format_tests/cpp/LLVM/example file.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() { 5 | cout << "Check my format!"; 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /industrial_ci/mockups/format_tests/cpp/WebKit/example file.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() 5 | { 6 | cout << "Check my format!"; 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /.travis.rosinstall: -------------------------------------------------------------------------------- 1 | - git: 2 | uri: https://github.com/ros/std_msgs.git 3 | local-name: ros/std_msgs 4 | - git: 5 | uri: https://github.com/ros-industrial/industrial_ci.git 6 | local-name: industrial_ci 7 | -------------------------------------------------------------------------------- /.github/action.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var {spawnSync} = require('child_process'); 3 | var r = spawnSync(__dirname + '/action.sh', { stdio: 'inherit'}); 4 | if (r.error) { 5 | throw r.error; 6 | } 7 | process.exit(r.status !== null ? r.status : 1); 8 | -------------------------------------------------------------------------------- /industrial_ci/mockups/test_clang_tidy/.clang-tidy: -------------------------------------------------------------------------------- 1 | Checks: '-*, 2 | readability-identifier-naming, 3 | ' 4 | CheckOptions: 5 | - key: readability-identifier-naming.VariableCase 6 | value: UPPER_CASE 7 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'ROS industrial_ci' 2 | description: "Running various CI checks for ROS package repositories" 3 | 4 | inputs: 5 | config: 6 | description: 'Configuration in JSON format, e.g. from matrix' 7 | required: false 8 | runs: 9 | using: 'node20' 10 | main: '.github/action.js' 11 | -------------------------------------------------------------------------------- /industrial_ci/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | from catkin_pkg.python_setup import generate_distutils_setup 3 | 4 | # fetch values from package.xml 5 | setup_args = generate_distutils_setup( 6 | packages=['industrial_ci'], 7 | package_dir={'': 'python'}) 8 | 9 | setup(**setup_args) 10 | -------------------------------------------------------------------------------- /industrial_ci/mockups/test_clang_tidy/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | test_clang_tidy 4 | 0.0.0 5 | The test_clang_tidy package 6 | todo 7 | TODO 8 | catkin 9 | 10 | -------------------------------------------------------------------------------- /industrial_ci/mockups/failing_test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0.2) 2 | project(failing_test) 3 | 4 | find_package(catkin REQUIRED) 5 | 6 | catkin_package() 7 | 8 | if (CATKIN_ENABLE_TESTING) 9 | find_package(rostest REQUIRED) 10 | add_rostest(test/no_talker.test) 11 | endif() 12 | 13 | install(DIRECTORY test DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}) 14 | -------------------------------------------------------------------------------- /industrial_ci/mockups/testpkg_broken_install/script/sample_talker.py: -------------------------------------------------------------------------------- 1 | # Taken from http://wiki.ros.org/rospy/Overview/Publishers%20and%20Subscribers 2 | import rospy 3 | from std_msgs.msg import String 4 | 5 | pub = rospy.Publisher('spokenwords', String, queue_size=10) 6 | rospy.init_node('node_name') 7 | r = rospy.Rate(10) # 10hz 8 | while not rospy.is_shutdown(): 9 | pub.publish("hello world") 10 | r.sleep() 11 | -------------------------------------------------------------------------------- /industrial_ci/mockups/industrial_ci_testpkg/CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2 | Changelog for package industrial_ci_testpkg 3 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 4 | 5 | 0.3.1 (2016-10-24) 6 | ------------------ 7 | 8 | 0.3.0 (2016-09-07) 9 | ------------------ 10 | * [maintenance] Initial commit as part of refactoring `#67 `_ 11 | * Contributors: Isaac I.Y. Saito 12 | -------------------------------------------------------------------------------- /industrial_ci/mockups/test_clang_tidy/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0.2) 2 | project(test_clang_tidy) 3 | 4 | find_package(catkin REQUIRED) 5 | 6 | catkin_package() 7 | 8 | add_library(${PROJECT_NAME} 9 | src/test_clang_tidy.cpp 10 | ) 11 | install(TARGETS ${PROJECT_NAME} 12 | ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 13 | LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} 14 | RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} 15 | ) 16 | -------------------------------------------------------------------------------- /industrial_ci/mockups/failing_test/test/no_talker.test: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /industrial_ci/mockups/failing_test/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | failing_test 4 | 0.3.1 5 | packages with a failing test 6 | 7 | Isaac I. Y. Saito 8 | Isaac I. Y. Saito 9 | Apache License 2.0 10 | 11 | catkin 12 | rostest 13 | 14 | -------------------------------------------------------------------------------- /industrial_ci/mockups/industrial_ci_testpkg/test/example_ros.test: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /industrial_ci/src/tests/black_check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function prepare_black_check() { 4 | if [ -z "${ROS_DISTRO:-}" ]; then 5 | export DOCKER_IMAGE=${DOCKER_IMAGE:-python:3} 6 | export ROS_DISTRO=false 7 | fi 8 | } 9 | 10 | function install_black() { 11 | ici_install_pkgs_for_command pip3 python3-pip python3-setuptools python3-wheel 12 | ici_asroot pip3 install black 13 | } 14 | 15 | function run_black_check() { 16 | ici_exec_for_command black ici_step install_black install_black 17 | ici_step run_black_check black --check --color --diff --verbose --exclude "/\..*/" "$TARGET_WORKSPACE" # Exclude hidden directories. 18 | } 19 | -------------------------------------------------------------------------------- /industrial_ci/mockups/industrial_ci_testpkg/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.3) 2 | if(POLICY CMP0048) 3 | cmake_policy(SET CMP0048 NEW) 4 | endif() 5 | 6 | project(industrial_ci_testpkg) 7 | 8 | if(FAIL_CMAKE) 9 | message(FATAL_ERROR "CMake was requested to fail") 10 | endif() 11 | 12 | find_package(catkin REQUIRED) 13 | 14 | catkin_package() 15 | 16 | add_library(${PROJECT_NAME} 17 | src/test_compiler.cpp 18 | ) 19 | 20 | if (CATKIN_ENABLE_TESTING) 21 | find_package(rostest REQUIRED) 22 | add_rostest(test/example_ros.test) 23 | endif() 24 | 25 | install(DIRECTORY test DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}) 26 | -------------------------------------------------------------------------------- /industrial_ci/mockups/testpkg_broken_install/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | testpkg_broken_install 4 | 0.3.1 5 | Test purpose only for industrial_ci package. Primary purpose 6 | is to be a package with limited install rules. 7 | 8 | 9 | Isaac I. Y. Saito 10 | Isaac I. Y. Saito 11 | Apache License 2.0 12 | 13 | catkin 14 | rospy 15 | 16 | 17 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # This .travis.yml works to check "this" repository, namely `industrial_ci`. 2 | # A template for users can be found here: https://github.com/ros-industrial/industrial_ci/blob/master/doc/.travis.yml 3 | 4 | # Greatly inspired by JSK travis: https://github.com/jsk-ros-pkg/jsk_travis 5 | 6 | services: 7 | - docker 8 | 9 | language: generic 10 | 11 | git: 12 | quiet: true 13 | 14 | env: 15 | matrix: 16 | - ROS_DISTRO=noetic 17 | - ROS_DISTRO=noetic PRERELEASE=true 18 | 19 | matrix: 20 | include: 21 | - env: 22 | - ROS_DISTRO=noetic ISOLATION=shell 23 | os: linux 24 | dist: focal 25 | language: cpp 26 | 27 | script: 28 | - ./travis.sh 29 | -------------------------------------------------------------------------------- /industrial_ci/mockups/testpkg_broken_install/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.0.2) 2 | project(testpkg_broken_install) 3 | 4 | find_package(catkin REQUIRED COMPONENTS rospy) 5 | 6 | catkin_package() 7 | 8 | # Install script folder but not test folder (https://github.com/ros-industrial/industrial_ci/pull/177) 9 | install(DIRECTORY script DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} USE_SOURCE_PERMISSIONS) 10 | 11 | # Install something missing, to confirm that the install job fails while non-install job succeeds. 12 | # Suggested at https://github.com/ros-industrial/industrial_ci/pull/177#issuecomment-301688167 13 | install(DIRECTORY launch DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}) 14 | -------------------------------------------------------------------------------- /industrial_ci/mockups/industrial_ci_testpkg/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | industrial_ci_testpkg 4 | 0.3.1 5 | This package is for test purposes only. 6 | 7 | Isaac I. Y. Saito 8 | Isaac I. Y. Saito 9 | Apache License 2.0 10 | 11 | catkin 12 | rospy_tutorials 13 | rospy_tutorials 14 | rostest 15 | rostest 16 | 17 | 18 | -------------------------------------------------------------------------------- /industrial_ci/src/folding/github_actions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2019, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | function ici_start_fold() { 19 | shift 3 20 | echo -en "##[group]" 21 | } 22 | 23 | function ici_end_fold() { 24 | shift 4 25 | echo -e "##[endgroup]" 26 | } 27 | 28 | function ici_report_result() { 29 | echo "$1=$2" >> "$GITHUB_OUTPUT" 30 | } 31 | -------------------------------------------------------------------------------- /industrial_ci/src/builders/catkin_make_devel.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2021, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | # shellcheck source=industrial_ci/src/builders/catkin_tools.sh 19 | source "${ICI_SRC_PATH}/builders/catkin_make.sh" 20 | 21 | ici_warn "BUILDER=catkin_make_devel should only be used in addition to the other non-devel builders" 22 | 23 | function ici_extend_space { 24 | echo "$1/devel" 25 | } 26 | -------------------------------------------------------------------------------- /industrial_ci/src/builders/catkin_tools_isolated.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2021, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | # shellcheck source=industrial_ci/src/builders/catkin_tools.sh 19 | source "${ICI_SRC_PATH}/builders/catkin_tools.sh" 20 | 21 | function _catkin_config { 22 | local extend=$1; shift 23 | local ws=$1; shift 24 | ici_cmd ici_exec_in_workspace "$extend" "$ws" catkin config --install --isolate-devel 25 | } 26 | -------------------------------------------------------------------------------- /industrial_ci/src/builders/catkin_make_isolated_devel.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2019, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | # shellcheck source=industrial_ci/src/builders/catkin_make_isolated.sh 19 | source "${ICI_SRC_PATH}/builders/catkin_make_isolated.sh" 20 | 21 | ici_warn "BUILDER=catkin_make_isolated_devel should only be used in addition to the other non-devel builders" 22 | 23 | function ici_extend_space { 24 | echo "$1/devel" 25 | } 26 | -------------------------------------------------------------------------------- /industrial_ci/src/folding/none.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2019, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | function ici_start_fold() { 19 | shift 3 20 | ici_color_output "$ANSI_BLUE" ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" 21 | } 22 | 23 | function ici_end_fold() { 24 | shift 4 25 | echo "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" 26 | } 27 | 28 | function ici_report_result() { 29 | true 30 | } 31 | -------------------------------------------------------------------------------- /industrial_ci/scripts/run_travis: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | # Copyright (c) 2017, Mathias Lüdtke 5 | # All rights reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | import os.path 20 | import sys 21 | 22 | try: 23 | from industrial_ci.travis import main 24 | except ImportError: 25 | sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'python')) 26 | from industrial_ci.travis import main 27 | 28 | if __name__ == "__main__": 29 | main(os.path.abspath(os.path.dirname(__file__)), sys.argv) 30 | -------------------------------------------------------------------------------- /industrial_ci/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.12) 2 | project(industrial_ci) 3 | 4 | if("$ENV{ROS_VERSION}" EQUAL "2") 5 | cmake_policy(VERSION 3.5) 6 | 7 | find_package(ament_cmake REQUIRED) 8 | find_package(ament_cmake_python REQUIRED) 9 | ament_python_install_package(${PROJECT_NAME} PACKAGE_DIR python/${PROJECT_NAME}) 10 | ament_package() 11 | 12 | set(${PROJECT_NAME}_BIN_DESTINATION lib/${PROJECT_NAME}) 13 | set(${PROJECT_NAME}_SHARE_DESTINATION share/${PROJECT_NAME}) 14 | elseif("$ENV{ROS_VERSION}" EQUAL "1") 15 | find_package(catkin REQUIRED) 16 | catkin_python_setup() 17 | catkin_package() 18 | 19 | set(${PROJECT_NAME}_BIN_DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) 20 | set(${PROJECT_NAME}_SHARE_DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}) 21 | else() 22 | message(FATAL_ERROR "ROS_VERSION is neither 1 nor 2") 23 | endif() 24 | 25 | install(PROGRAMS scripts/run_ci scripts/rerun_ci scripts/run_travis 26 | DESTINATION ${${PROJECT_NAME}_BIN_DESTINATION} 27 | ) 28 | 29 | install(DIRECTORY src 30 | DESTINATION ${${PROJECT_NAME}_SHARE_DESTINATION} 31 | ) 32 | -------------------------------------------------------------------------------- /ci.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2016, Isaac I. Y. Saito 4 | # Copyright (c) 2017, Mathias Lüdtke 5 | # All rights reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | # This is the generic entrypoint for CI services. 20 | 21 | # 2016/05/18 http://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in 22 | DIR_THIS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 23 | 24 | export TARGET_REPO_PATH=${TARGET_REPO_PATH:-$(pwd)} 25 | export TARGET_REPO_NAME=${TARGET_REPO_NAME:-${TARGET_REPO_PATH##*/}} 26 | 27 | env "$@" bash "$DIR_THIS/industrial_ci/src/ci_main.sh" 28 | -------------------------------------------------------------------------------- /industrial_ci/src/folding/gitlab.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2019, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | function ici_start_fold() { 19 | shift 20 | local name=$1; shift 21 | local start=$1; shift 22 | ici_ansi_cleared_line "section_start:${start::-9}:${name}[collapsed=true]" 23 | } 24 | 25 | function ici_end_fold() { 26 | shift 27 | local name=$1; shift 28 | shift 29 | local end=$1; shift 30 | ici_ansi_cleared_line "section_end:${end::-9}:$name" 31 | } 32 | 33 | function ici_report_result() { 34 | true 35 | } 36 | -------------------------------------------------------------------------------- /bitbucket.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2016, Isaac I. Y. Saito 4 | # Copyright (c) 2017, Mathias Lüdtke 5 | # Copyright (c) 2018, Alexander Rössler 6 | # All rights reserved. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | 20 | # This is the entrypoint for BitBucket Pipelines only. 21 | 22 | # 2016/05/18 http://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in 23 | DIR_THIS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 24 | 25 | export TARGET_REPO_PATH=$BITBUCKET_CLONE_DIR 26 | export TARGET_REPO_NAME=${BITBUCKET_REPO_SLUG##*/} 27 | 28 | env "$@" bash "$DIR_THIS/industrial_ci/src/ci_main.sh" 29 | -------------------------------------------------------------------------------- /industrial_ci/src/builders/catkin_tools_devel.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2021, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | # shellcheck source=industrial_ci/src/builders/catkin_tools.sh 19 | source "${ICI_SRC_PATH}/builders/catkin_tools.sh" 20 | 21 | ici_warn "BUILDER=catkin_tools_devel should only be used in addition to the other non-devel builders" 22 | 23 | function ici_extend_space { 24 | echo "$1/devel" 25 | } 26 | 27 | function _catkin_config { 28 | local extend=$1; shift 29 | local ws=$1; shift 30 | ici_exec_in_workspace "$extend" "$ws" catkin config --init 31 | } 32 | -------------------------------------------------------------------------------- /industrial_ci/src/folding/quiet.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2019, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | function ici_start_fold() { 19 | ici_error "ici_start_fold is not implemented" 20 | } 21 | 22 | function ici_end_fold() { 23 | ici_error "ici_end_fold is not implemented" 24 | } 25 | 26 | function ici_report_result() { 27 | true 28 | } 29 | 30 | function ici_cmd { 31 | _ici_guard ici_label ici_quiet "$@" 32 | } 33 | 34 | function ici_filter { 35 | shift 36 | ici_quiet "$@" 37 | } 38 | 39 | function ici_step { 40 | shift 41 | _ici_guard ici_quiet "$@" 42 | } 43 | -------------------------------------------------------------------------------- /industrial_ci/src/builders/catkin_tools_isolated_devel.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2021, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | # shellcheck source=industrial_ci/src/builders/catkin_tools.sh 19 | source "${ICI_SRC_PATH}/builders/catkin_tools.sh" 20 | 21 | ici_warn "BUILDER=catkin_tools_isolated_devel should only be used in addition to the other non-devel builders" 22 | 23 | function ici_extend_space { 24 | echo "$1/devel" 25 | } 26 | 27 | function _catkin_config { 28 | local extend=$1; shift 29 | local ws=$1; shift 30 | ici_cmd ici_exec_in_workspace "$extend" "$ws" catkin config --isolate-devel 31 | } 32 | -------------------------------------------------------------------------------- /industrial_ci/src/isolation/docker.env: -------------------------------------------------------------------------------- 1 | _FOLDING_TYPE 2 | _DEFAULT_DEBS 3 | ABICHECK_URL 4 | ABICHECK_VERSION 5 | ADDITIONAL_DEBS 6 | APT_PROXY 7 | APTKEY_STORE_HTTPS 8 | APTKEY_STORE_SKS 9 | BUILDER 10 | CATKIN_LINT 11 | CATKIN_LINT_ARGS 12 | CC 13 | CFLAGS 14 | CLANG_FORMAT_CHECK 15 | CLANG_FORMAT_VERSION 16 | CLANG_TIDY 17 | CLANG_TIDY_ARGS 18 | CLANG_TIDY_BASE_REF 19 | CLANG_TIDY_JOBS 20 | CMAKE_ARGS 21 | CPPFLAGS 22 | CXX 23 | CXXFLAGS 24 | DEBUG_BASH 25 | DOWNSTREAM_CMAKE_ARGS 26 | DOWNSTREAM_WORKSPACE 27 | HASHKEY_SKS 28 | # EXPECT_EXIT_CODE, do not pass to make sure code is checked on the outer level only 29 | IMMEDIATE_TEST_OUTPUT 30 | NOT_TEST_BUILD 31 | NOT_TEST_DOWNSTREAM 32 | OS_NAME 33 | OS_CODE_NAME 34 | PARALLEL_BUILDS 35 | PARALLEL_TESTS 36 | PIP_BREAK_SYSTEM_PACKAGES 37 | PREFIX 38 | PRERELEASE 39 | PYLINT_ARGS 40 | PYLINT_CHECK 41 | PYLINT_EXCLUDE 42 | PYTHONUNBUFFERED 43 | ROSDEP_SKIP_KEYS 44 | ROSDISTRO_INDEX_VERSION 45 | ROSINSTALL_FILENAME 46 | ROS_DISTRO 47 | ROS_PYTHON_VERSION 48 | ROS_REPO 49 | ROS_REPOSITORY_KEY 50 | ROS_REPOSITORY_PATH 51 | TARGET_CMAKE_ARGS 52 | TARGET_REPO_NAME 53 | TARGET_REPO_PATH 54 | TARGET_WORKSPACE 55 | TERM 56 | TRACE 57 | UNDERLAY 58 | UPSTREAM_CMAKE_ARGS 59 | UPSTREAM_WORKSPACE 60 | VERBOSE_OUTPUT 61 | VERBOSE_TESTS 62 | -------------------------------------------------------------------------------- /industrial_ci/src/folding/travis.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2019, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | function ici_start_fold() { 19 | local tag=$1; shift 20 | local name=$1; shift 21 | local start=$1; shift 22 | ici_ansi_cleared_line "travis_fold:start:$name" 23 | ici_ansi_cleared_line "travis_time:start:$tag" 24 | 25 | } 26 | 27 | function ici_end_fold() { 28 | local tag=$1; shift 29 | local name=$1; shift 30 | local start=$1; shift 31 | local end=$1; shift 32 | ici_ansi_cleared_line "travis_time:end:$tag:start=$start,finish=$end,duration=$((end - start))" 33 | ici_ansi_cleared_line "travis_fold:end:$name" 34 | } 35 | 36 | function ici_report_result() { 37 | true 38 | } 39 | -------------------------------------------------------------------------------- /industrial_ci/src/isolation/shell.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2020, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | # ici_forward_mount VARNAME/FILE rw/ro [PATH] 19 | function ici_forward_mount() { 20 | true 21 | } 22 | 23 | # ici_forward_variable VARNAME [VALUE] 24 | function ici_forward_variable() { 25 | if [ -n "${2-}" ]; then 26 | export "$1"="$2" 27 | fi 28 | } 29 | 30 | function ici_isolate { 31 | if [ "${CI:-}" != true ] ; then 32 | ici_error 'ISOLATION=shell needs CI=true' 33 | fi 34 | if [ -z "${ROS_DISTRO:-}" ]; then 35 | ici_error "ROS_DISTRO is not set" 36 | elif [ "${ROS_DISTRO}" = "false" ]; then 37 | unset ROS_DISTRO 38 | fi 39 | if [ -n "${BASEDIR-}" ]; then 40 | mkdir -p "$BASEDIR" 41 | fi 42 | "${ICI_SRC_PATH}/run.sh" "$@" 43 | } 44 | -------------------------------------------------------------------------------- /doc/.travis.yml: -------------------------------------------------------------------------------- 1 | # This config uses industrial_ci (https://github.com/ros-industrial/industrial_ci.git). 2 | # For troubleshooting, see readme (https://github.com/ros-industrial/industrial_ci/blob/master/README.rst) 3 | 4 | language: generic # optional, just removes the language badge 5 | 6 | services: 7 | - docker 8 | 9 | # include the following block if the C/C++ build artifacts should get cached by Travis, 10 | # CCACHE_DIR needs to get set as well to actually fill the cache 11 | cache: 12 | directories: 13 | - $HOME/.ccache 14 | 15 | git: 16 | quiet: true # optional, silences the cloning of the target repository 17 | 18 | # configure the build environment(s) 19 | # https://github.com/ros-industrial/industrial_ci/blob/master/doc/index.rst#variables-you-can-configure 20 | env: 21 | global: # global settings for all jobs 22 | - CCACHE_DIR=$HOME/.ccache # enables C/C++ caching in industrial_ci 23 | matrix: # each line is a job 24 | - ROS_DISTRO="lunar" ROS_REPO=main # overrides the default 25 | - ROS_DISTRO="kinetic" 26 | - ROS_DISTRO="melodic" 27 | 28 | # allow failures, e.g. for unsupported distros 29 | matrix: 30 | allow_failures: 31 | - env: ROS_DISTRO="lunar" ROS_REPO=main 32 | 33 | # clone and run industrial_ci 34 | install: 35 | - git clone --quiet --depth 1 https://github.com/ros-industrial/industrial_ci.git .industrial_ci -b master 36 | script: 37 | - .industrial_ci/travis.sh 38 | -------------------------------------------------------------------------------- /gitlab.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2016, Isaac I. Y. Saito 4 | # Copyright (c) 2017, Mathias Lüdtke 5 | # All rights reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | # This is the entrypoint for Gitlab CI only. 20 | 21 | # 2016/05/18 http://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in 22 | DIR_THIS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 23 | 24 | export TARGET_REPO_PATH=$CI_PROJECT_DIR 25 | export TARGET_REPO_NAME=$CI_PROJECT_NAME 26 | export _FOLDING_TYPE=gitlab 27 | 28 | if [ -n "$SSH_PRIVATE_KEY" ]; then 29 | if [ "$CI_DISPOSABLE_ENVIRONMENT" != true ] && ! [ -f /.dockerenv ] ; then 30 | echo "SSH auto set-up cannot be used in non-disposable environments" 31 | exit 1 32 | fi 33 | 34 | # start SSH agent 35 | # shellcheck disable=SC2046 36 | eval $(ssh-agent -s) 37 | # add key to agent 38 | ssh-add <(echo "$SSH_PRIVATE_KEY") || { res=$?; echo "could not add ssh key"; exit $res; } 39 | 40 | if [ -n "$SSH_SERVER_HOSTKEYS" ]; then 41 | mkdir -p ~/.ssh 42 | # setup known hosts 43 | echo "$SSH_SERVER_HOSTKEYS" > ~/.ssh/known_hosts 44 | fi 45 | fi 46 | 47 | env "$@" bash "$DIR_THIS/industrial_ci/src/ci_main.sh" 48 | -------------------------------------------------------------------------------- /travis.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2016, Isaac I. Y. Saito 4 | # Copyright (c) 2018, Mathias Lüdtke 5 | # All rights reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | # This is the entrypoint for Travis CI only. 20 | 21 | # 2016/05/18 http://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in 22 | DIR_THIS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 23 | 24 | export TARGET_REPO_PATH=$TRAVIS_BUILD_DIR 25 | export TARGET_REPO_NAME=${TRAVIS_REPO_SLUG##*/} 26 | export _FOLDING_TYPE=travis 27 | 28 | # Update libseccomp to allow statx syscalls (https://travis-ci.community/t/docker-build-environments/7216/4) 29 | sudo apt-get update -qq && sudo apt-get install -y -qq libseccomp2 30 | 31 | if [ "$ABICHECK_MERGE" = "auto" ]; then 32 | export ABICHECK_MERGE=false 33 | [ "$TRAVIS_PULL_REQUEST" = "false" ] || ABICHECK_MERGE=true 34 | fi 35 | 36 | function watch_output() { 37 | while read -r -t "${_GUARD_INTERVAL:-540}" || 38 | { [[ $? -gt 128 ]] && 39 | echo -en "${ANSI_YELLOW}...industrial_ci is still running...${ANSI_RESET}"; } 40 | do 41 | echo "$REPLY" 42 | done 43 | } 44 | 45 | set -o pipefail 46 | env "$@" stdbuf -oL -eL bash "$DIR_THIS"/industrial_ci/src/ci_main.sh |& watch_output 47 | -------------------------------------------------------------------------------- /industrial_ci/scripts/run_ci: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2017, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 19 | 20 | if [ -n "$1" ] && [[ ! "$1" =~ "=" ]]; then 21 | if [ -d "$1" ]; then 22 | repo_dir=$1 23 | else 24 | echo "'$1' is not a directory" 25 | exit 1 26 | fi 27 | shift 28 | else 29 | repo_dir=. 30 | fi 31 | 32 | export TARGET_REPO_PATH 33 | TARGET_REPO_PATH=$(cd "$repo_dir" && pwd) 34 | export TARGET_REPO_NAME=${TARGET_REPO_PATH##*/} 35 | echo "Testing $TARGET_REPO_PATH" 36 | 37 | if [ -f "$script_dir/../src/ci_main.sh" ]; then # devel space 38 | ci_dir="$script_dir/.." 39 | elif [ -f "$script_dir/../../share/industrial_ci/src/ci_main.sh" ]; then # install space 40 | ci_dir="$script_dir/../../share/industrial_ci/" 41 | else 42 | ci_dir=$(python2 -c "import rospkg; print rospkg.RosPack().get_path('industrial_ci')" 2>/dev/null) || { echo "could not find ci_main.sh"; exit 1; } 43 | fi 44 | 45 | env "$@" /bin/bash "$(readlink -e "$ci_dir/src/ci_main.sh")" 46 | ret=$? 47 | 48 | if [ "$ret" == "0" ]; then 49 | echo "All tests succeeded" 50 | else 51 | echo "Tests failed exit code '$ret'" 52 | fi 53 | 54 | exit "$ret" 55 | -------------------------------------------------------------------------------- /.github/action.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2020, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | # This is the entrypoint for GitHub Actions only. 19 | 20 | # 2016/05/18 http://stackoverflow.com/questions/59895/can-a-bash-script-tell-what-directory-its-stored-in 21 | 22 | set -euo pipefail 23 | 24 | DIR_THIS="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 25 | 26 | export TARGET_REPO_PATH=$GITHUB_WORKSPACE 27 | export TARGET_REPO_NAME=${GITHUB_REPOSITORY##*/} 28 | export _FOLDING_TYPE=github_actions 29 | 30 | ICI_SRC_PATH="$DIR_THIS/../industrial_ci/src" 31 | source "$ICI_SRC_PATH/util.sh" 32 | 33 | if [ -n "${INPUT_CONFIG-}" ]; then 34 | ici_exec_for_command jq ici_error "In order to use the config parameter, please install jq" 35 | vars=$(jq -r 'keys[] as $k | "export \($k)=\(.[$k]|tojson)" | gsub("\\$\\$";"\\$")' <<< "$INPUT_CONFIG" | grep "^export [A-Z][A-Z_]*=") 36 | echo "$vars" 37 | eval "$vars" 38 | fi 39 | 40 | if [ "${ABICHECK_MERGE:-}" = "auto" ]; then 41 | export ABICHECK_MERGE=false 42 | [ "$GITHUB_EVENT_NAME" != "pull_request" ] || ABICHECK_MERGE=true 43 | fi 44 | 45 | if [ "${ACT:-}" = true ]; then 46 | export _BUNDLE_ICI=true 47 | _FOLDING_TYPE=none 48 | ici_warn "Detected act, bundling industrial_ci" 49 | fi 50 | 51 | env "$@" bash "$ICI_SRC_PATH/ci_main.sh" 52 | -------------------------------------------------------------------------------- /industrial_ci/src/builders/catkin_make.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2019, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | function _append_job_opts() { 19 | local -n _append_job_opts_res=$1 20 | local jobs 21 | ici_parse_jobs jobs "$2" "$3" 22 | if [ "$jobs" -gt 0 ]; then 23 | _append_job_opts_res+=("-j$jobs" "-l$jobs") 24 | fi 25 | } 26 | function _run_catkin_make () { 27 | local target=$1; shift 28 | local extend=$1; shift 29 | local ws=$1; shift 30 | ici_cmd ici_exec_in_workspace "$extend" "$ws" catkin_make "$@" --make-args "$target" 31 | } 32 | 33 | function builder_setup { 34 | ici_install_pkgs_for_command catkin_make "ros-${ROS_DISTRO}-catkin" 35 | } 36 | 37 | function builder_run_build { 38 | local extend=$1; shift 39 | local ws=$1; shift 40 | local opts=() 41 | _append_job_opts opts PARALLEL_BUILDS 0 42 | _run_catkin_make install "$extend" "$ws" "${opts[@]}" "$@" 43 | } 44 | 45 | function builder_run_tests { 46 | local extend=$1; shift 47 | local ws=$1; shift 48 | local opts=() 49 | _append_job_opts opts PARALLEL_TESTS 1 50 | _run_catkin_make run_tests "$extend" "$ws" "${opts[@]}" "$@" 51 | } 52 | 53 | function builder_test_results { 54 | local extend=$1; shift 55 | local ws=$1; shift 56 | ici_cmd ici_exec_in_workspace "$extend" "$ws" catkin_test_results --verbose 57 | } 58 | -------------------------------------------------------------------------------- /industrial_ci/src/tests/clang_format_check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2018, Jonathan Hechtbauer 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | function prepare_clang_format_check() { 19 | true 20 | } 21 | 22 | function run_clang_format_check() { 23 | local err=0 24 | local path 25 | ici_make_temp_dir path 26 | 27 | # Check whether a specific version of clang-format is desired 28 | local clang_format_executable="clang-format${CLANG_FORMAT_VERSION:+-$CLANG_FORMAT_VERSION}" 29 | 30 | ici_time_start install_clang_format 31 | ici_apt_install git-core "$clang_format_executable" 32 | ici_time_end # install_clang_format 33 | 34 | local sources=() 35 | ici_parse_env_array sources TARGET_WORKSPACE 36 | ici_step "prepare_sourcespace" ici_prepare_sourcespace "$path" "${sources[@]}" 37 | 38 | ici_time_start run_clang_format_check 39 | while read -r file; do 40 | ici_log "Checking '${file#"$path/"}'" 41 | if ! $clang_format_executable -style="$CLANG_FORMAT_CHECK" "$file" | git diff --exit-code "$file" - ; then 42 | err=$((err +1)) 43 | fi 44 | done < <(ici_find_nonhidden "$path" -iname '*.h' -or -iname '*.hpp' -or -iname '*.c' -or -iname '*.cc' -or -iname '*.cpp' -or -iname '*.cxx') 45 | 46 | if [ "$err" -ne "0" ]; then 47 | ici_error "Clang format check failed for $err file(s)." 48 | fi 49 | ici_log 'Clang format check went successful.' 50 | ici_time_end # run_clang_format_check 51 | } 52 | -------------------------------------------------------------------------------- /industrial_ci/src/builders/catkin_make_isolated.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2019, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | function _append_job_opts() { 19 | local -n _append_job_opts_res=$1 20 | local jobs 21 | ici_parse_jobs jobs "$2" "$3" 22 | if [ "$jobs" -gt 0 ]; then 23 | _append_job_opts_res+=("-j$jobs" "-l$jobs") 24 | fi 25 | } 26 | 27 | function _run_catkin_make_isolated () { 28 | local target=$1; shift 29 | local extend=$1; shift 30 | local ws=$1; shift 31 | ici_cmd ici_exec_in_workspace "$extend" "$ws" catkin_make_isolated --build-space "$ws/build" --devel-space "$ws/devel" --install-space "$ws/install" --make-args "$target" "$@" 32 | } 33 | 34 | function builder_setup { 35 | ici_install_pkgs_for_command catkin_make_isolated "ros-${ROS_DISTRO}-catkin" 36 | } 37 | 38 | function builder_run_build { 39 | local extend=$1; shift 40 | local ws=$1; shift 41 | local opts=() 42 | _append_job_opts opts PARALLEL_BUILDS 0 43 | _run_catkin_make_isolated install "$extend" "$ws" "${opts[@]}" "$@" 44 | } 45 | 46 | function builder_run_tests { 47 | local extend=$1; shift 48 | local ws=$1; shift 49 | local opts=() 50 | _append_job_opts opts PARALLEL_TESTS 1 51 | _run_catkin_make_isolated run_tests "$extend" "$ws" "${opts[@]}" 52 | } 53 | 54 | function builder_test_results { 55 | local extend=$1; shift 56 | local ws=$1; shift 57 | ici_cmd ici_exec_in_workspace "$extend" "$ws" catkin_test_results --verbose 58 | } 59 | -------------------------------------------------------------------------------- /industrial_ci/src/tests/merge_fixes.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | # Copyright (c) 2022, Robert Haschke 5 | # All rights reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | import yaml 20 | import sys 21 | 22 | 23 | def key(item): 24 | name = item.get("DiagnosticName") 25 | msg = item.get("DiagnosticMessage") 26 | file = msg.get("FilePath") 27 | offset = msg.get("FileOffset") 28 | return name, file, offset 29 | 30 | def merge_fixes(files): 31 | """Merge all fixes files into mergefile""" 32 | # The fixes suggested by clang-tidy >= 4.0.0 are given under 33 | # the top level key 'Diagnostics' in the output yaml files 34 | mergefile = files[0] 35 | mergekey = "Diagnostics" 36 | merged = [] 37 | seen = set() # efficiently remember fixes already inserted 38 | 39 | def have(x): 40 | k = key(x) 41 | return k in seen or seen.add(k) 42 | 43 | def unique(seq): 44 | return [x for x in seq if not have(x)] 45 | 46 | for file in files: 47 | try: 48 | with open(file, 'r') as inp: 49 | content = yaml.safe_load(inp) 50 | if not content: 51 | continue # Skip empty files. 52 | merged.extend(unique(content.get(mergekey, []))) 53 | except FileNotFoundError: 54 | pass 55 | 56 | with open(mergefile, 'w') as out: 57 | if merged: 58 | # Assemble output dict with MainSourceFile=''. 59 | output = {'MainSourceFile': '', mergekey: merged} 60 | yaml.safe_dump(output, out) 61 | 62 | 63 | if __name__ == "__main__": 64 | merge_fixes(sys.argv[1:]) 65 | -------------------------------------------------------------------------------- /industrial_ci/scripts/rerun_ci: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | # Copyright (c) 2018, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing@, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 19 | 20 | function show_help { 21 | cat - <<'EOF' 22 | Usage: 23 | rerun_ci --list 24 | rerun_ci [--clean] TARGET_PATH [PARAM=VALUE>]... 25 | rerun_ci --rm TARGET_PATH [PARAM=VALUE>]... 26 | EOF 27 | } 28 | 29 | case "$1" in 30 | "--list") 31 | mapfile -t images < <(docker images -q "industrial-ci/rerun_ci/*") 32 | exec docker image inspect --format '{{index .RepoTags 0}} - {{.Comment}}' "${images[@]}" 2> /dev/null 33 | ;; 34 | "--rm") 35 | remove=true 36 | shift 37 | ;; 38 | "--clean") 39 | clean=true 40 | shift 41 | ;; 42 | "-h" | "--help" | "") 43 | show_help 44 | exit 0 45 | ;; 46 | esac 47 | 48 | if [ ! -d "$1" ]; then 49 | show_help 50 | exit 1 51 | fi 52 | 53 | repo_dir=$(cd "$1" && pwd) 54 | shift 55 | 56 | DOCKER_COMMIT_MSG="$repo_dir $*" 57 | env_hash=$(sha256sum <<< "$DOCKER_COMMIT_MSG") 58 | DOCKER_COMMIT="industrial-ci/rerun_ci/$(basename "$repo_dir"):${env_hash:0:12}" 59 | 60 | if [ "$remove" ]; then 61 | exec docker rmi "$DOCKER_COMMIT" 62 | elif [ "$clean" ]; then 63 | docker rmi "$DOCKER_COMMIT" 64 | fi 65 | 66 | 67 | force_env=("DOCKER_COMMIT=$DOCKER_COMMIT" "DOCKER_COMMIT_MSG=$DOCKER_COMMIT_MSG") 68 | keep_env=("DOCKER_PORT=$DOCKER_PORT" "HOME=$HOME" "SSH_AUTH_SOCK=$SSH_AUTH_SOCK" "TERM=$TERM") 69 | 70 | if docker image inspect "$DOCKER_COMMIT" &> /dev/null; then 71 | force_env+=("DOCKER_IMAGE=$DOCKER_COMMIT" "DOCKER_PULL=false") 72 | fi 73 | 74 | env -i "${keep_env[@]}" "$script_dir/run_ci" "$repo_dir" "$@" "${force_env[@]}" || ret=$? 75 | 76 | echo "Please do not forget to clean-up: docker rmi $DOCKER_COMMIT" 77 | 78 | exit "$ret" 79 | -------------------------------------------------------------------------------- /industrial_ci/src/builders/catkin_tools.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2019, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | function _append_job_opts() { 19 | local -n _append_job_opts_res=$1 20 | local jobs 21 | ici_parse_jobs jobs "$2" "$3" 22 | if [ "$jobs" -eq 1 ]; then 23 | _append_job_opts_res+=("-j1" "-p1") 24 | elif [ "$jobs" -gt 1 ]; then 25 | _append_job_opts_res+=("-j$jobs") 26 | fi 27 | } 28 | 29 | function builder_setup { 30 | ici_install_pkgs_for_command catkin "${PYTHON_VERSION_NAME}-catkin-tools" "ros-$ROS_DISTRO-catkin" "${PYTHON_VERSION_NAME}-osrf-pycommon" 31 | } 32 | 33 | function _catkin_config { 34 | local extend=$1; shift 35 | local ws=$1; shift 36 | ici_exec_in_workspace "$extend" "$ws" catkin config --install 37 | } 38 | 39 | function builder_run_build { 40 | local extend=$1; shift 41 | local ws=$1; shift 42 | local opts=() 43 | if [ "${VERBOSE_OUTPUT:-false}" != false ]; then 44 | opts+=("-vi") 45 | fi 46 | _append_job_opts opts PARALLEL_BUILDS 0 47 | _catkin_config "$extend" "$ws" 48 | ici_cmd ici_exec_in_workspace "$extend" "$ws" catkin build "${opts[@]}" --summarize --no-status "$@" 49 | } 50 | 51 | function builder_run_tests { 52 | local extend=$1; shift 53 | local ws=$1; shift 54 | local opts=() 55 | if [ "${VERBOSE_TESTS:-false}" != false ]; then 56 | opts+=(-v) 57 | fi 58 | if [ "$IMMEDIATE_TEST_OUTPUT" == true ]; then 59 | opts+=(-i) 60 | fi 61 | _append_job_opts opts PARALLEL_TESTS 1 62 | ici_cmd ici_exec_in_workspace "$extend" "$ws" catkin run_tests "${opts[@]}" --no-status 63 | } 64 | 65 | function builder_test_results { 66 | local extend=$1; shift 67 | local ws=$1; shift 68 | ici_cmd ici_exec_in_workspace "$extend" "$ws" catkin_test_results --verbose 69 | } 70 | -------------------------------------------------------------------------------- /doc/industrial_ci_action.yml: -------------------------------------------------------------------------------- 1 | # This config uses industrial_ci (https://github.com/ros-industrial/industrial_ci.git). 2 | # For troubleshooting, see README (https://github.com/ros-industrial/industrial_ci/blob/master/README.rst) 3 | 4 | name: CI 5 | 6 | on: # this determines when this workflow is run 7 | push: 8 | # branches: [ master, melodic-devel ] # when master or melodic-devel branch is pushed to 9 | pull_request: 10 | # branches: [ master ] # when there is a pull request against master 11 | # schedule: # uncomment to run periodically 12 | # - cron: '0 4 * * *' # every day at 4 AM (UTC) 13 | workflow_dispatch: # allow manually starting this workflow 14 | 15 | jobs: 16 | industrial_ci: 17 | name: ROS ${{ matrix.ROS_DISTRO }} (${{ matrix.ROS_REPO }}) 18 | runs-on: ubuntu-latest 19 | strategy: 20 | # fail-fast: false # uncomment if failing jobs should not cancel the others immediately 21 | matrix: # matrix is the product of entries 22 | ROS_DISTRO: [melodic] 23 | ROS_REPO: [testing, main] 24 | # exclude: # specific configuration can be excludes 25 | # - {ROS_DISTRO: melodic, ROS_REPO: testing} 26 | include: # add additional configurations 27 | - {ROS_DISTRO: kinetic, ROS_REPO: testing} 28 | env: 29 | CCACHE_DIR: "${{ github.workspace }}/.ccache" # directory for ccache (and how we enable ccache in industrial_ci) 30 | steps: 31 | - uses: actions/checkout@v4 # clone target repository 32 | - uses: actions/cache@v4 # fetch/store the directory used by ccache before/after the ci run 33 | with: 34 | path: ${{ env.CCACHE_DIR }} 35 | # This configuration will always create a new ccache cache starting off from the previous one (if any). 36 | # In this simple version it will be shared between all builds of the same ROS_REPO and ROS_REPO 37 | # and might need some fine-tuning to match the use case 38 | key: ccache-${{ matrix.ROS_DISTRO }}-${{ matrix.ROS_REPO }}-${{github.run_id}} 39 | restore-keys: | 40 | ccache-${{ matrix.ROS_DISTRO }}-${{ matrix.ROS_REPO }}- 41 | - uses: 'ros-industrial/industrial_ci@master' # run industrial_ci 42 | env: # either pass all entries explicitly 43 | ROS_DISTRO: ${{ matrix.ROS_DISTRO }} 44 | ROS_REPO: ${{ matrix.ROS_REPO }} 45 | # with: # or pass the full matrix as config 46 | # config: ${{toJSON(matrix)}} 47 | -------------------------------------------------------------------------------- /industrial_ci/package.xml: -------------------------------------------------------------------------------- 1 | 2 | industrial_ci 3 | 0.10.0 4 | This package contains CI (Continuous Integration) configuration that any ROS-powered packages can commonly use. Some notable feature: 5 |
    6 |
  • Checks if your package builds, installs without issues. If unit/system tests are defined run them. ROS Prerelease Test can optionally be run.
  • 7 |
  • Proven to cover the general requirements of the ROS-based robotics repositories. Easily configurable.
  • 8 |
  • Users can add custom pre/post processes.
  • 9 |
  • Covers ROS Hydro, Indigo, Jade, Kinetic, Lunar, Melodic distribution
  • 10 |
  • This package provides scripts for `Bitbucket CI`, `Gitlab CI`, and `Travis CI` only, but it can be easily adapted for other CI services.
  • 11 |
12 |
13 | Apache License 2.0 14 | Isaac I. Y. Saito 15 | Mathias Lüdtke 16 | Miguel Prada 17 | Isaac I. Y. Saito 18 | Mathias Lüdtke 19 | 20 | http://wiki.ros.org/industrial_ci 21 | https://github.com/ros-industrial/industrial_ci 22 | https://github.com/ros-industrial/industrial_ci/issues 23 | 24 | catkin 25 | ament_cmake 26 | ament_cmake_python 27 | ros_environment 28 | roslib 29 | 30 | coreutils 31 | python-yaml 32 | python3-yaml 33 | 34 | 35 | catkin 36 | ament_cmake 37 | 38 |
39 | -------------------------------------------------------------------------------- /industrial_ci/src/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2020, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | ## Greatly inspired by JSK travis https://github.com/jsk-ros-pkg/jsk_travis 19 | 20 | ## This is a "common" script that can be run on travis CI at a downstream github repository. 21 | ## See ./README.rst for the detailed usage. 22 | 23 | set -e # exit script on errors 24 | [[ "${BASH_VERSINFO[0]}_${BASH_VERSINFO[1]}" < "4_4" ]] || set -u 25 | _CLEANUP=${_CLEANUP-} 26 | 27 | # shellcheck source=industrial_ci/src/env.sh 28 | source "${ICI_SRC_PATH}/env.sh" 29 | 30 | # shellcheck source=industrial_ci/src/util.sh 31 | source "${ICI_SRC_PATH}/util.sh" 32 | 33 | # shellcheck source=industrial_ci/src/ros.sh 34 | source "${ICI_SRC_PATH}/ros.sh" 35 | 36 | # shellcheck source=industrial_ci/src/workspace.sh 37 | source "${ICI_SRC_PATH}/workspace.sh" 38 | 39 | ici_setup 40 | 41 | if [ "$DEBUG_BASH" = true ]; then set -x; fi # print trace if DEBUG 42 | 43 | ici_configure_ros 44 | 45 | export TARGET_WORKSPACE=${TARGET_WORKSPACE:-$TARGET_REPO_PATH} 46 | export BASEDIR=${BASEDIR:-$HOME} 47 | 48 | export LANG=${LANG:-C.UTF-8} 49 | export LC_ALL=${LC_ALL:-C.UTF-8} 50 | export TERM=${TERM:-dumb} 51 | 52 | if [ -z "${CC:-}" ]; then unset CC; fi 53 | if [ -z "${CFLAGS:-}" ]; then unset CFLAGS; fi 54 | if [ -z "${CPPFLAGS:-}" ]; then unset CPPFLAGS; fi 55 | if [ -z "${CXX:-}" ]; then unset CXX; fi 56 | if [ -z "${CXXFLAGS:-}" ]; then unset CXXLAGS; fi 57 | 58 | TEST=$1; shift 59 | ici_source_component TEST tests 60 | 61 | ici_step "init" ici_init_apt 62 | 63 | if [ -n "${UNDERLAY:-}" ]; then 64 | if [ ! -f "$UNDERLAY/setup.bash" ] && [ "$UNDERLAY" != "/opt/ros/$ROS_DISTRO" ]; then 65 | ici_error "UNDERLAY '$UNDERLAY' does not contain a setup.bash" 66 | fi 67 | else 68 | if [ -n "${ROS_DISTRO:-}" ]; then 69 | export UNDERLAY=${UNDERLAY:-/opt/ros/$ROS_DISTRO} 70 | fi 71 | fi 72 | 73 | "$@" || ici_exit 74 | 75 | ici_hook "after_script" || ici_exit 76 | 77 | ici_exit 0 78 | -------------------------------------------------------------------------------- /industrial_ci/src/keys/ros.asc: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PUBLIC KEY BLOCK----- 2 | Version: GnuPG v1 3 | 4 | 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 41 | =9IZg 42 | -----END PGP PUBLIC KEY BLOCK----- 43 | -------------------------------------------------------------------------------- /industrial_ci/src/ci_main.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2015, Isaac I. Y. Saito 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | ## Greatly inspired by JSK travis https://github.com/jsk-ros-pkg/jsk_travis 19 | 20 | ## This is a "common" script that can be run on travis CI at a downstream github repository. 21 | ## See ./README.rst for the detailed usage. 22 | 23 | set -e # exit script on errors 24 | [[ "${BASH_VERSINFO[0]}_${BASH_VERSINFO[1]}" < "4_4" ]] || set -u 25 | 26 | export ICI_SRC_PATH; ICI_SRC_PATH="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" # The path on CI service (e.g. Travis CI) to industrial_ci src dir. 27 | _CLEANUP="" 28 | 29 | # shellcheck source=industrial_ci/src/env.sh 30 | source "${ICI_SRC_PATH}/env.sh" 31 | if [ "$DEBUG_BASH" = true ]; then set -x; fi # print trace if DEBUG 32 | 33 | # shellcheck source=industrial_ci/src/util.sh 34 | source "${ICI_SRC_PATH}/util.sh" 35 | 36 | # shellcheck source=industrial_ci/src/deprecated.sh 37 | source "${ICI_SRC_PATH}/deprecated.sh" 38 | 39 | # shellcheck source=industrial_ci/src/ros.sh 40 | source "${ICI_SRC_PATH}/ros.sh" 41 | 42 | ici_setup 43 | 44 | export ISOLATION=${ISOLATION:-docker} 45 | if [ "${CI:-}" != true ] ; then 46 | if [ "${ISOLATION}" = "shell" ]; then 47 | ici_warn 'ISOLATION=shell needs CI=true, falling back to ISOLATION=docker' 48 | fi 49 | ISOLATION=docker 50 | fi 51 | ici_source_component ISOLATION isolation 52 | 53 | ici_configure_ros 54 | 55 | # Start prerelease, and once it finishs then finish this script too. 56 | if [ "$PRERELEASE" = true ]; then 57 | TEST=ros_prerelease 58 | elif [ -n "$ABICHECK_URL" ]; then 59 | TEST=abi_check 60 | elif [ -n "$CLANG_FORMAT_CHECK" ]; then 61 | TEST=clang_format_check 62 | elif [ "$BLACK_CHECK" = true ]; then 63 | TEST=black_check 64 | elif [ -z "$TEST" ]; then 65 | TEST=source_tests 66 | fi 67 | 68 | ici_source_component TEST tests 69 | 70 | ici_log "Running test '$TEST'" 71 | name=$(basename "$TEST") 72 | name=${name%.*} 73 | 74 | "prepare_$name" || ici_exit 75 | ici_isolate "$TEST" "run_${name}" || ici_exit 76 | ici_exit 0 77 | -------------------------------------------------------------------------------- /industrial_ci/src/builders/colcon.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2019, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | _colcon_event_handlers=(desktop_notification- status- terminal_title-) 19 | 20 | function builder_setup { 21 | ici_install_pkgs_for_command colcon python3-colcon-common-extensions 22 | if [ "$ROS_DISTRO" = "kinetic" ] || [ "$ROS_DISTRO" = "ardent" ]; then 23 | ici_install_pkgs_for_command pip3 python3-pip 24 | ici_asroot pip3 install -U setuptools==30.3.0 25 | fi 26 | } 27 | 28 | function builder_run_build { 29 | local extend=$1; shift 30 | local ws=$1; shift 31 | local opts=(--event-handlers "${_colcon_event_handlers[@]}") 32 | if [ "${VERBOSE_OUTPUT:-false}" != false ]; then 33 | opts+=("console_cohesion+") 34 | fi 35 | local jobs 36 | ici_parse_jobs jobs PARALLEL_BUILDS 0 37 | if [ "$jobs" -eq 1 ]; then 38 | opts+=(--executor sequential) 39 | elif [ "$jobs" -gt 1 ]; then 40 | opts+=(--executor parallel --parallel-workers "$jobs") 41 | fi 42 | ici_cmd ici_exec_in_workspace "$extend" "$ws" colcon build "${opts[@]}" "$@" 43 | } 44 | 45 | function builder_run_tests { 46 | local extend=$1; shift 47 | local ws=$1; shift 48 | local output_handler 49 | if [ "$IMMEDIATE_TEST_OUTPUT" == true ]; then 50 | output_handler="console_direct+" 51 | else 52 | output_handler="console_cohesion+" 53 | fi 54 | local opts=(--event-handlers "${_colcon_event_handlers[@]}" "${output_handler}") 55 | local jobs 56 | ici_parse_jobs jobs PARALLEL_TESTS 1 57 | if [ "$jobs" -eq 1 ]; then 58 | opts+=(--executor sequential --ctest-args -j1) 59 | elif [ "$jobs" -gt 1 ]; then 60 | opts+=(--executor parallel --parallel-workers "$jobs") 61 | fi 62 | ici_cmd ici_exec_in_workspace "$extend" "$ws" colcon test "${opts[@]}" 63 | } 64 | 65 | function builder_test_results { 66 | local extend=$1; shift 67 | local ws=$1; shift 68 | ici_cmd ici_exec_in_workspace "$extend" "$ws" colcon test-result --verbose 69 | } 70 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 98 | __pypackages__/ 99 | 100 | # Celery stuff 101 | celerybeat-schedule 102 | celerybeat.pid 103 | 104 | # SageMath parsed files 105 | *.sage.py 106 | 107 | # Environments 108 | .env 109 | .venv 110 | env/ 111 | venv/ 112 | ENV/ 113 | env.bak/ 114 | venv.bak/ 115 | 116 | # Spyder project settings 117 | .spyderproject 118 | .spyproject 119 | 120 | # Rope project settings 121 | .ropeproject 122 | 123 | # mkdocs documentation 124 | /site 125 | 126 | # mypy 127 | .mypy_cache/ 128 | .dmypy.json 129 | dmypy.json 130 | 131 | # Pyre type checker 132 | .pyre/ 133 | 134 | # pytype static type analyzer 135 | .pytype/ 136 | 137 | # Cython debug symbols 138 | cython_debug/ 139 | -------------------------------------------------------------------------------- /industrial_ci/mockups/format_tests/cpp/WebKit/.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: WebKit 4 | AccessModifierOffset: -4 5 | AlignAfterOpenBracket: DontAlign 6 | AlignConsecutiveAssignments: false 7 | AlignConsecutiveDeclarations: false 8 | AlignEscapedNewlinesLeft: false 9 | AlignOperands: false 10 | AlignTrailingComments: false 11 | AllowAllParametersOfDeclarationOnNextLine: true 12 | AllowShortBlocksOnASingleLine: false 13 | AllowShortCaseLabelsOnASingleLine: false 14 | AllowShortFunctionsOnASingleLine: All 15 | AllowShortIfStatementsOnASingleLine: false 16 | AllowShortLoopsOnASingleLine: false 17 | AlwaysBreakAfterDefinitionReturnType: None 18 | AlwaysBreakAfterReturnType: None 19 | AlwaysBreakBeforeMultilineStrings: false 20 | AlwaysBreakTemplateDeclarations: false 21 | BinPackArguments: true 22 | BinPackParameters: true 23 | BraceWrapping: 24 | AfterClass: false 25 | AfterControlStatement: false 26 | AfterEnum: false 27 | AfterFunction: true 28 | AfterNamespace: false 29 | AfterObjCDeclaration: false 30 | AfterStruct: false 31 | AfterUnion: false 32 | BeforeCatch: false 33 | BeforeElse: false 34 | IndentBraces: false 35 | BreakBeforeBinaryOperators: All 36 | BreakBeforeBraces: WebKit 37 | BreakBeforeTernaryOperators: true 38 | BreakConstructorInitializersBeforeComma: true 39 | ColumnLimit: 0 40 | CommentPragmas: '^ IWYU pragma:' 41 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 42 | ConstructorInitializerIndentWidth: 4 43 | ContinuationIndentWidth: 4 44 | Cpp11BracedListStyle: false 45 | DerivePointerAlignment: false 46 | DisableFormat: false 47 | ExperimentalAutoDetectBinPacking: false 48 | ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] 49 | IncludeCategories: 50 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 51 | Priority: 2 52 | - Regex: '^(<|"(gtest|isl|json)/)' 53 | Priority: 3 54 | - Regex: '.*' 55 | Priority: 1 56 | IndentCaseLabels: false 57 | IndentWidth: 4 58 | IndentWrappedFunctionNames: false 59 | KeepEmptyLinesAtTheStartOfBlocks: true 60 | MacroBlockBegin: '' 61 | MacroBlockEnd: '' 62 | MaxEmptyLinesToKeep: 1 63 | NamespaceIndentation: Inner 64 | ObjCBlockIndentWidth: 4 65 | ObjCSpaceAfterProperty: true 66 | ObjCSpaceBeforeProtocolList: true 67 | PenaltyBreakBeforeFirstCallParameter: 19 68 | PenaltyBreakComment: 300 69 | PenaltyBreakFirstLessLess: 120 70 | PenaltyBreakString: 1000 71 | PenaltyExcessCharacter: 1000000 72 | PenaltyReturnTypeOnItsOwnLine: 60 73 | PointerAlignment: Left 74 | ReflowComments: true 75 | SortIncludes: true 76 | SpaceAfterCStyleCast: false 77 | SpaceBeforeAssignmentOperators: true 78 | SpaceBeforeParens: ControlStatements 79 | SpaceInEmptyParentheses: false 80 | SpacesBeforeTrailingComments: 1 81 | SpacesInAngles: false 82 | SpacesInContainerLiterals: true 83 | SpacesInCStyleCastParentheses: false 84 | SpacesInParentheses: false 85 | SpacesInSquareBrackets: false 86 | Standard: Cpp03 87 | TabWidth: 8 88 | UseTab: Never 89 | ... 90 | 91 | -------------------------------------------------------------------------------- /industrial_ci/src/env.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2020, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | export PYTHONUNBUFFERED=${PYTHONUNBUFFERED-1} 19 | 20 | export ROS_DISTRO=${ROS_DISTRO:-} 21 | export ROS_REPOSITORY_PATH=${ROS_REPOSITORY_PATH:-} 22 | export ROS_REPO=${ROS_REPO:-} 23 | export ROS_REPOSITORY_KEY=${ROS_REPOSITORY_KEY:-"$ICI_SRC_PATH/keys/ros.asc"} 24 | export ROSDISTRO_INDEX_VERSION=${ROSDISTRO_INDEX_VERSION:-} 25 | 26 | export DEBUG_BASH=${DEBUG_BASH:-false} 27 | export TEST=${TEST:-} 28 | 29 | export EXPECT_EXIT_CODE=${EXPECT_EXIT_CODE:-0} 30 | export APTKEY_STORE_SKS=${APTKEY_STORE_SKS:-hkp://keyserver.ubuntu.com:80} 31 | export APTKEY_STORE_HTTPS=${APTKEY_STORE_HTTPS:-} 32 | export HASHKEY_SKS=${HASHKEY_SKS:-} 33 | export ADDITIONAL_DEBS=${ADDITIONAL_DEBS:-} 34 | 35 | export ABICHECK_URL=${ABICHECK_URL:-} 36 | export ABICHECK_VERSION=${ABICHECK_VERSION:-} 37 | export ABICHECK_MERGE=${ABICHECK_MERGE:-false} 38 | 39 | export APT_PROXY=${APT_PROXY:-} 40 | 41 | export BLACK_CHECK=${BLACK_CHECK:-false} 42 | export BUILDER=${BUILDER:-} 43 | 44 | export CATKIN_LINT=${CATKIN_LINT:-false} 45 | export CATKIN_LINT_ARGS=${CATKIN_LINT_ARGS:-} 46 | 47 | export PYLINT_ARGS=${PYLINT_ARGS:-} 48 | export PYLINT_CHECK=${PYLINT_CHECK:-false} 49 | export PYLINT_EXCLUDE=${PYLINT_EXCLUDE:-} 50 | 51 | export CLANG_FORMAT_CHECK=${CLANG_FORMAT_CHECK:-} 52 | export CLANG_FORMAT_VERSION=${CLANG_FORMAT_VERSION:-} 53 | 54 | export CLANG_TIDY=${CLANG_TIDY:-false} 55 | export CLANG_TIDY_ARGS=${CLANG_TIDY_ARGS:-} 56 | export CLANG_TIDY_BASE_REF=${CLANG_TIDY_BASE_REF:-} 57 | export CLANG_TIDY_JOBS=${CLANG_TIDY_JOBS:-} 58 | 59 | export CCACHE_DIR=${CCACHE_DIR:-} 60 | 61 | export CMAKE_ARGS=${CMAKE_ARGS:-} 62 | 63 | export DOWNSTREAM_CMAKE_ARGS=${DOWNSTREAM_CMAKE_ARGS:-} 64 | export DOWNSTREAM_WORKSPACE=${DOWNSTREAM_WORKSPACE:-} 65 | 66 | export IMMEDIATE_TEST_OUTPUT=${IMMEDIATE_TEST_OUTPUT:-false} 67 | export NOT_TEST_BUILD=${NOT_TEST_BUILD:-false} 68 | export NOT_TEST_DOWNSTREAM=${NOT_TEST_DOWNSTREAM:-false} 69 | export PARALLEL_BUILDS=${PARALLEL_BUILDS:-0} 70 | export PARALLEL_TESTS=${PARALLEL_TESTS:-1} 71 | 72 | export PRERELEASE=${PRERELEASE:-false} 73 | 74 | case "${OS_CODE_NAME-}" in 75 | # https://wiki.debian.org/DebianReleases#Production_Releases 76 | "jessie"|"stretch"|"buster"|"bullseye"|"bookwork"|"trixie") 77 | export OS_NAME=debian 78 | ;; 79 | *) 80 | export OS_NAME=${OS_NAME:-ubuntu} 81 | ;; 82 | esac 83 | 84 | export ROSDEP_SKIP_KEYS=${ROSDEP_SKIP_KEYS:-} 85 | export TARGET_CMAKE_ARGS=${TARGET_CMAKE_ARGS:-} 86 | 87 | export UPSTREAM_CMAKE_ARGS=${UPSTREAM_CMAKE_ARGS:-} 88 | export UPSTREAM_WORKSPACE=${UPSTREAM_WORKSPACE:-} 89 | 90 | export PREFIX=${PREFIX:-} 91 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | # The following block is needed for the shared Docker-based runner 2 | # For local runners you might want to enable the overlay driver: 3 | # https://docs.gitlab.com/ce/ci/docker/using_docker_build.html#using-the-overlayfs-driver 4 | 5 | image: docker:git # docker and git clients 6 | 7 | # The docker runner does not expose /tmp to the docker-in-docker service 8 | # This config ensures that the temp folder is located inside the project directory (e.g. for prerelease tests or SSH agent forwarding) 9 | variables: 10 | TMPDIR: "${CI_PROJECT_DIR}.tmp" # 11 | CCACHE_DIR: ${CI_PROJECT_DIR}/ccache 12 | 13 | cache: 14 | key: "${CI_JOB_NAME}" # https://docs.gitlab.com/ee/ci/caching/#sharing-caches-across-different-branches 15 | paths: 16 | - ccache 17 | 18 | # enable docker-in-docker 19 | services: 20 | - docker:20.10.16-dind 21 | 22 | before_script: 23 | - apk add --update bash coreutils tar grep # install industrial_ci dependencies 24 | # for regular users: - git clone --quiet --depth 1 https://github.com/ros-industrial/industrial_ci .industrial_ci -b master 25 | - mkdir .industrial_ci && cp -a * .industrial_ci # this is only needed for branch testing of industrial_ci itself 26 | 27 | # setup the actual tests 28 | 29 | indigo: 30 | script: .industrial_ci/gitlab.sh 31 | variables: 32 | ROS_DISTRO: "indigo" 33 | TARGET_WORKSPACE: 'industrial_ci/mockups/industrial_ci_testpkg' 34 | 35 | kinetic: 36 | script: .industrial_ci/gitlab.sh ROS_DISTRO=kinetic # alternate syntax 37 | 38 | 39 | noetic: 40 | image: ros:noetic 41 | script: ./gitlab.sh 42 | before_script: [] 43 | services: [] 44 | variables: 45 | ISOLATION: shell 46 | 47 | humble: 48 | script: .industrial_ci/gitlab.sh 49 | variables: 50 | TARGET_WORKSPACE: ". github:ros-controls/control_msgs#galactic-devel" 51 | ROS_DISTRO: "humble" 52 | PRERELEASE: "true" 53 | CCACHE_DIR: 54 | 55 | dashing: 56 | script: .industrial_ci/gitlab.sh ROS_DISTRO=dashing 57 | 58 | # some internal tests 59 | 60 | docker_pull: 61 | script: 62 | - docker pull ros:kinetic 63 | - docker tag ros:kinetic industrial-ci/ubuntu:xenial 64 | - .industrial_ci/gitlab.sh ROS_DISTRO=kinetic DOCKER_IMAGE="industrial-ci/ubuntu:xenial" EXPECT_EXIT_CODE=1 65 | 66 | docker_no_pull: 67 | script: 68 | - docker pull ros:kinetic 69 | - docker tag ros:kinetic industrial-ci/ubuntu:xenial 70 | - .industrial_ci/gitlab.sh ROS_DISTRO=kinetic DOCKER_IMAGE="industrial-ci/ubuntu:xenial" DOCKER_PULL=false 71 | 72 | test_arm: 73 | script: 74 | - docker run --rm --privileged multiarch/qemu-user-static --reset --credential yes --persistent yes 75 | - export DOCKER_DEFAULT_PLATFORM=linux/arm/v7 76 | - .industrial_ci/gitlab.sh DOCKER_IMAGE='arm32v7/ros:melodic-ros-core' BEFORE_INIT='[[ $(uname -p) == armv7l ]] && exit 42' EXPECT_EXIT_CODE=42 77 | 78 | 79 | test_junit_docker: 80 | script: .industrial_ci/gitlab.sh TARGET_WORKSPACE=". gh:ros/filters.git#noetic-devel" 81 | variables: 82 | ROS_DISTRO: noetic 83 | BASEDIR: ${CI_PROJECT_DIR}/.workspaces 84 | artifacts: 85 | when: always 86 | reports: 87 | junit: ${BASEDIR}/target_ws/**/test_results/**/*.xml 88 | 89 | test_junit_shell: 90 | image: ros:noetic 91 | script: ./gitlab.sh TARGET_WORKSPACE=". gh:ros/filters.git#noetic-devel" 92 | before_script: [] 93 | services: [] 94 | variables: 95 | ISOLATION: shell 96 | BASEDIR: ${CI_PROJECT_DIR}/.workspaces 97 | artifacts: 98 | when: always 99 | reports: 100 | junit: ${BASEDIR}/target_ws/**/test_results/**/*.xml 101 | 102 | -------------------------------------------------------------------------------- /industrial_ci/src/deprecated.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2015, Isaac I. Y. Saito 4 | # Copyright (c) 2017, Mathias Lüdtke 5 | # All rights reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | ici_enforce_deprecated BEFORE_SCRIPT "Please migrate to new hook system." 20 | ici_enforce_deprecated CATKIN_CONFIG "Explicit catkin configuration is not available anymore." 21 | ici_enforce_deprecated INJECT_QEMU "Please check https://github.com/ros-industrial/industrial_ci/blob/master/doc/migration_guide.md#inject_qemu" 22 | ici_enforce_deprecated DOCKER_FILE "Please build image separately" 23 | 24 | if [ -n "${NOT_TEST_INSTALL:-}" ]; then 25 | if [ "$NOT_TEST_INSTALL" != true ]; then 26 | ici_enforce_deprecated NOT_TEST_INSTALL "testing installed test files has been removed." 27 | else 28 | ici_mark_deprecated NOT_TEST_INSTALL "testing installed test files has been removed, NOT_TEST_INSTALL=false is superfluous" 29 | fi 30 | fi 31 | 32 | if [ -n "${DOCKER_BASE_IMAGE:-}" ]; then 33 | ici_mark_deprecated DOCKER_BASE_IMAGE "Please set DOCKER_IMAGE=$DOCKER_BASE_IMAGE directly" 34 | export DOCKER_IMAGE=$DOCKER_BASE_IMAGE 35 | fi 36 | 37 | for v in BUILD_PKGS_WHITELIST PKGS_DOWNSTREAM TARGET_PKGS USE_MOCKUP; do 38 | ici_enforce_deprecated "$v" "Please migrate to new workspace definition" 39 | done 40 | 41 | for v in CATKIN_PARALLEL_JOBS CATKIN_PARALLEL_TEST_JOBS ROS_PARALLEL_JOBS ROS_PARALLEL_TEST_JOBS; do 42 | ici_mark_deprecated "$v" "Please migrate to PARALLEL_BUILDS and/or PARALLEL_TESTS" 43 | done 44 | 45 | ici_mark_deprecated ROSINSTALL_FILENAME "Please migrate to new UPSTREAM_WORKSPACE format" 46 | ici_mark_deprecated UBUNTU_OS_CODE_NAME "Was renamed to OS_CODE_NAME." 47 | ici_mark_deprecated DEFAULT_DOCKER_IMAGE "Official ROS Docker images are not the default anymore" 48 | 49 | if [ -n "${USE_MOCKUP:-}" ]; then 50 | if [ -z "$TARGET_WORKSPACE" ]; then 51 | export TARGET_WORKSPACE="$USE_MOCKUP" 52 | ici_warn "Replacing 'USE_MOCKUP=$USE_MOCKUP' with 'TARGET_WORKSPACE=$TARGET_WORKSPACE'" 53 | else 54 | ici_error "USE_MOCKUP is not supported anymore, please migrate to 'TARGET_WORKSPACE=$TARGET_WORKSPACE $USE_MOCKUP'" 55 | fi 56 | fi 57 | 58 | # legacy support for UPSTREAM_WORKSPACE and USE_DEB 59 | if [ "${UPSTREAM_WORKSPACE:-}" = "debian" ]; then 60 | ici_warn "Setting 'UPSTREAM_WORKSPACE=debian' is superfluous and gets removed" 61 | unset UPSTREAM_WORKSPACE 62 | fi 63 | 64 | if [ "${USE_DEB:-}" = true ]; then 65 | if [ "${UPSTREAM_WORKSPACE:-debian}" != "debian" ]; then 66 | ici_error "USE_DEB and UPSTREAM_WORKSPACE are in conflict" 67 | fi 68 | ici_warn "Setting 'USE_DEB=true' is superfluous" 69 | fi 70 | 71 | if [ "${UPSTREAM_WORKSPACE:-}" = "file" ] || [ "${USE_DEB:-true}" != true ]; then 72 | ROSINSTALL_FILENAME="${ROSINSTALL_FILENAME:-.travis.rosinstall}" 73 | if [ -f "$TARGET_REPO_PATH/$ROSINSTALL_FILENAME.${ROS_DISTRO:?ROS_DISTRO not set}" ]; then 74 | ROSINSTALL_FILENAME="$ROSINSTALL_FILENAME.$ROS_DISTRO" 75 | fi 76 | 77 | if [ "${USE_DEB:-true}" != true ]; then # means UPSTREAM_WORKSPACE=file 78 | if [ "${UPSTREAM_WORKSPACE:-file}" != "file" ]; then 79 | ici_error "USE_DEB and UPSTREAM_WORKSPACE are in conflict" 80 | fi 81 | ici_warn "Replacing 'USE_DEB=false' with 'UPSTREAM_WORKSPACE=$ROSINSTALL_FILENAME'" 82 | else 83 | ici_warn "Replacing 'UPSTREAM_WORKSPACE=file' with 'UPSTREAM_WORKSPACE=$ROSINSTALL_FILENAME'" 84 | fi 85 | export UPSTREAM_WORKSPACE="$ROSINSTALL_FILENAME" 86 | fi 87 | 88 | if [ "${DOCKER_PULL:-true}" = true ]; then 89 | ici_migrate_hook prepare_docker_image pull_docker_image 90 | else 91 | ici_removed_hook prepare_docker_image "Hook 'prepare_docker_image' got removed." 92 | fi 93 | 94 | ici_mark_deprecated DOCKER_COMMIT_CREDENTIALS "Credentials will be copied, but never committed!" 95 | 96 | ici_rename_deprecated HASHKEY_SKS ROS_REPOSITORY_KEY 97 | ici_rename_deprecated APTKEY_STORE_HTTPS ROS_REPOSITORY_KEY 98 | ici_rename_deprecated ROSDEP_SOURCES_VERSION ROSDISTRO_INDEX_VERSION 99 | -------------------------------------------------------------------------------- /industrial_ci/src/tests/debians.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2021, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | # Based on https://github.com/ros-industrial/industrial_ci/issues/697#issuecomment-876293987 19 | 20 | 21 | function make_repo() { 22 | local repo=$1; shift 23 | ici_guard rm -rf "$repo" 24 | ici_guard mkdir -p "$repo" 25 | ici_guard touch "$repo/Packages" 26 | } 27 | 28 | function update_repo() ( 29 | local repo=$1; shift 30 | ici_guard apt-ftparchive packages "$repo" > "$repo/Packages" 31 | ici_guard apt-ftparchive release -o APT::FTPArchive::Release::Origin=industrial_ci "$repo" > "$repo/Release" 32 | ) 33 | 34 | function use_repo() ( 35 | local repo=$1; shift 36 | ici_guard ici_asroot rm -f /etc/apt/apt.conf.d/docker-clean 37 | echo "deb [trusted=yes] file://$repo ./" | >/dev/null ici_guard ici_asroot tee /etc/apt/sources.list.d/ici_debians.list 38 | echo -e 'Package: *\nPin: release o=industrial_ci\nPin-Priority: 1000' | >/dev/null ici_guard ici_asroot tee /etc/apt/preferences.d/ici_debians 39 | ici_guard ici_asroot apt-get -o APT::Sandbox::User=root update -qq 40 | ) 41 | 42 | function forward_mounts() { 43 | ici_forward_mount WORKSPACE rw 44 | ici_forward_mount "$WORKSPACE/archives" rw /var/cache/apt/archives 45 | if [ -n "${DOCKER_PORT:-}" ]; then 46 | ici_forward_variable DOCKER_HOST "$DOCKER_PORT" 47 | elif [ -e /var/run/docker.sock ]; then 48 | ici_forward_mount /var/run/docker.sock rw 49 | fi 50 | } 51 | 52 | function prepare_debians() { 53 | export WORKSPACE; WORKSPACE=$(mktemp -d) 54 | ici_guard mkdir "$WORKSPACE/archives" 55 | forward_mounts 56 | } 57 | 58 | function build_debian() ( 59 | local pkg_path=$1; shift 60 | local repo=$1; shift 61 | use_repo "$repo" 62 | 63 | ici_guard cd "$pkg_path" 64 | ici_cmd ici_filter "Setting up" ici_asroot apt-get build-dep -y -qq . 65 | ici_cmd ici_quiet dpkg-buildpackage -b -uc -us 66 | ici_guard mv ../*.deb "$repo" 67 | ) 68 | 69 | function isolate_build_debian() ( 70 | local pkg_path=$1; shift 71 | local repo=$1; shift 72 | for hook in $(env | grep -o '^\(BEFORE\|AFTER\)_[^=]*'); do 73 | unset "$hook" 74 | done 75 | export _FOLDING_TYPE=quiet 76 | DOCKER_PULL=false ici_isolate debians build_debian "$pkg_path" "$repo" || ici_exit 77 | ) 78 | 79 | function build_package() { 80 | local pkg_path=$1; shift 81 | local repo=$1; shift 82 | 83 | use_repo "$repo" 84 | ici_install_pkgs_for_command dpkg-buildpackage dpkg-dev 85 | 86 | ( ici_guard cd "$pkg_path" && ici_cmd bloom-generate rosdebian --ros-distro="$ROS_DISTRO" --debian-inc="ici~"; ) || ici_exit 87 | # https://github.com/ros-infrastructure/bloom/pull/643 88 | echo 11 > "$pkg_path"/debian/compat 89 | 90 | isolate_build_debian "$pkg_path" "$repo" || ici_exit 91 | update_repo "$repo" 92 | } 93 | 94 | function test_install_packages() { 95 | local repo=$1; shift 96 | ( ici_guard cd "$repo" && ici_apt_install ./*.deb; ) 97 | } 98 | 99 | function run_debians() { 100 | ici_guard source "${ICI_SRC_PATH}/isolation/docker.sh" 101 | forward_mounts 102 | 103 | export BUILDER=colcon 104 | ici_source_builder 105 | ici_step "${BUILDER}_setup" builder_setup 106 | ici_step "setup_bloom" ici_install_pkgs_for_command bloom-generate python3-bloom debhelper 107 | ici_step "setup_apt_utils" ici_install_pkgs_for_command apt-ftparchive apt-utils 108 | ici_step "setup_docker" ici_install_pkgs_for_command docker docker.io 109 | ici_step "setup_rosdep" ici_setup_rosdep 110 | 111 | local repo="$WORKSPACE/repository" 112 | make_repo "$repo" 113 | 114 | for name in upstream target downstream; do 115 | local sources=() 116 | local current="$WORKSPACE/${name}_ws/src" 117 | ici_parse_env_array sources "${name^^}_WORKSPACE" 118 | if [ -n "${sources[*]}" ]; then 119 | ici_step "prepare_${name}_sourcespace" ici_prepare_sourcespace "$current" "${sources[@]}" 120 | 121 | while read -r -a pkg; do 122 | ici_step "build_${pkg[0]}" build_package "$current/${pkg[1]}" "$repo" 123 | done < <(ici_guard cd "$current" && ici_guard colcon list -t) 124 | fi 125 | done 126 | 127 | ici_step "test_install_packages" test_install_packages "$repo" 128 | 129 | ici_log "Debian packages:" 130 | ici_redirect find "$repo" -name '*.deb' -exec basename {} \; 131 | } 132 | -------------------------------------------------------------------------------- /industrial_ci/src/tests/ros_prerelease.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2016, Isaac I. Y. Saito 4 | # Copyright (c) 2017, Mathias Lüdtke 5 | # All rights reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | # ros_prerelease.sh script runs ROS Pre-release Test. 20 | # It is dependent on environment variables that need to be exported in advance 21 | # (As of version 0.4.4 most of them are defined in env.sh). 22 | 23 | function setup_ros_buildfarm() { 24 | ici_apt_install python3-pip python3-setuptools python3-wheel python3-venv python3-vcstool 25 | ici_cmd python3 -mvenv /tmp/ros_buildfarm --system-site-packages 26 | ici_cmd ici_quiet /tmp/ros_buildfarm/bin/pip3 install git+https://github.com/ros-infrastructure/ros_buildfarm.git 27 | } 28 | 29 | function setup_ros_prerelease() { 30 | ici_asroot useradd -u 1010 --non-unique -m -d "$WORKSPACE/home" ci 31 | 32 | if ! [ -d "$WORKSPACE/home/.ccache" ]; then 33 | ici_asroot mkdir -p "$WORKSPACE/home/.ccache" 34 | fi 35 | 36 | if [ -e /var/run/docker.sock ]; then 37 | ici_asroot groupadd -o -g "$(stat -c%g /var/run/docker.sock)" host_docker 38 | ici_asroot usermod -a -G host_docker ci 39 | fi 40 | 41 | ici_setup_git_client 42 | ici_install_pkgs_for_command docker docker.io 43 | ici_install_pkgs_for_command sudo sudo 44 | ici_install_pkgs_for_command lsb_release lsb-release 45 | setup_ros_buildfarm 46 | } 47 | 48 | function prepare_prerelease_workspaces() { 49 | local ws_upstream=() 50 | ici_parse_env_array ws_upstream UPSTREAM_WORKSPACE 51 | local ws_target=() 52 | ici_parse_env_array ws_target TARGET_WORKSPACE 53 | local workspace=$1 54 | local reponame=$2 55 | local targetname=$3 56 | ici_with_ws "$workspace/ws" ici_prepare_sourcespace "$workspace/ws/src/" "${ws_upstream[@]}" "${ws_target[@]}" 57 | 58 | if ! [ -d "$workspace/ws/src/$reponame" ]; then 59 | mv "$workspace/ws/src/$targetname" "$workspace/ws/src/$reponame" 60 | fi 61 | 62 | local overlay=() 63 | ici_parse_env_array overlay DOWNSTREAM_WORKSPACE 64 | ici_with_ws "$workspace/ws_overlay" ici_prepare_sourcespace "$workspace/ws_overlay/src/" "${overlay[@]}" 65 | ici_asroot chown -R ci "$workspace" 66 | } 67 | 68 | function prepare_ros_prerelease() { 69 | if [ "$ROS_VERSION_EOL" = true ]; then 70 | ici_error "$ROS_DISTRO is EOL, pre-releases test are not supported anymore." 71 | fi 72 | if [ "$BUILDER" != "colcon" ]; then 73 | export BUILDER=catkin_make_isolated 74 | fi 75 | export WORKSPACE; WORKSPACE=$(mktemp -d) 76 | if [ -z "${ROSDISTRO_INDEX_URL:-}" ]; then 77 | if [ "$ROS_VERSION" -eq 2 ]; then 78 | export ROSDISTRO_INDEX_URL="https://raw.githubusercontent.com/ros2/ros_buildfarm_config/ros2/index.yaml" 79 | else 80 | export ROSDISTRO_INDEX_URL="https://raw.githubusercontent.com/ros-infrastructure/ros_buildfarm_config/production/index.yaml" 81 | fi 82 | fi 83 | export PRERELEASE_DISTRO="$ROS_DISTRO" 84 | 85 | ici_parse_env_array opts DOCKER_RUN_OPTS 86 | for e in TRAVIS OS_NAME OS_CODE_NAME OS_ARCH PRERELEASE_DOWNSTREAM_DEPTH PRERELEASE_REPONAME PRERELEASE_EXCLUDE_PKG ROSDISTRO_INDEX_URL PRERELEASE_DISTRO; do 87 | ici_forward_variable "$e" 88 | done 89 | 90 | ici_forward_mount WORKSPACE rw 91 | 92 | if [ -n "${DOCKER_PORT:-}" ]; then 93 | ici_forward_variable DOCKER_HOST "$DOCKER_PORT" 94 | elif [ -e /var/run/docker.sock ]; then 95 | ici_forward_mount /var/run/docker.sock rw 96 | fi 97 | if [ -n "${CCACHE_DIR}" ]; then 98 | ici_forward_mount CCACHE_DIR rw "$WORKSPACE/home/.ccache" 99 | CCACHE_DIR= # prevent cachedir from beeing added twice 100 | fi 101 | export DOCKER_IMAGE=${DOCKER_IMAGE:-ros:noetic-ros-core} 102 | } 103 | 104 | function run_ros_prerelease() { 105 | ici_source_builder 106 | ici_step "${BUILDER}_setup" builder_setup 107 | 108 | ici_step "setup_ros_prerelease" setup_ros_prerelease 109 | 110 | # Environment vars. 111 | local downstream_depth=${PRERELEASE_DOWNSTREAM_DEPTH:-"0"} 112 | local reponame=${PRERELEASE_REPONAME:-$TARGET_REPO_NAME} 113 | local exclude_pkg=${PRERELEASE_EXCLUDE_PKG:-""} 114 | 115 | ici_step "prepare_prerelease_workspaces" ici_cmd prepare_prerelease_workspaces "$WORKSPACE" "$reponame" "$(basename "$TARGET_REPO_PATH")" 116 | ici_step 'generate_prerelease_script' ici_cmd sudo -EH -u ci /tmp/ros_buildfarm/bin/python -m ros_buildfarm.scripts.prerelease.generate_prerelease_script "${ROSDISTRO_INDEX_URL}" "$PRERELEASE_DISTRO" default "$OS_NAME" "$OS_CODE_NAME" "${OS_ARCH:-amd64}" --build-tool "$BUILDER" --level "$downstream_depth" --output-dir "$WORKSPACE" --custom-repo "$reponame::::" --exclude-pkg "$exclude_pkg" 117 | 118 | # patch prerelease_build_underlay.sh to create test_results, if no tests were run 119 | # shellcheck disable=SC2016 120 | ici_asroot sed -i '/test_result_EXECUTABLE="colcon"/a mkdir -p "$WORKSPACE/ws/test_results"' "$WORKSPACE/prerelease_build_underlay.sh" 121 | 122 | local setup_sh= 123 | if [ -f "${UNDERLAY:?}/setup.sh" ]; then 124 | setup_sh=". $UNDERLAY/setup.sh && " 125 | fi 126 | ABORT_ON_TEST_FAILURE=1 ici_step "run_prerelease_script" ici_cmd sudo -EH -u ci sh -c "${setup_sh}cd '$WORKSPACE' && exec ./prerelease.sh -y" 127 | 128 | ici_log 'ROS Prerelease Test went successful.' 129 | } 130 | -------------------------------------------------------------------------------- /industrial_ci/src/isolation/docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2017, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | export DOCKER_COMMIT=${DOCKER_COMMIT:-} 19 | export DOCKER_COMMIT_MSG=${DOCKER_COMMIT_MSG:-} 20 | export DOCKER_CREDENTIALS=${DOCKER_CREDENTIALS-.docker .gitconfig .ssh .subversion} 21 | export DOCKER_PULL=${DOCKER_PULL:-true} 22 | export _BUNDLE_ICI=${_BUNDLE_ICI:-false} 23 | 24 | # ici_forward_mount VARNAME/FILE rw/ro [PATH] 25 | function ici_forward_mount() { 26 | local p=$1 27 | local v= 28 | if ! [ -e "$1" ]; then 29 | v=$1 30 | p=${!1:-} 31 | fi 32 | if [ -n "$p" ]; then 33 | local p_abs 34 | p_abs=$(readlink -m "$p") 35 | local p_inner=${3:-$p_abs} 36 | _docker_run_opts+=(-v "$p_abs:$p_inner:$2") 37 | if [ -n "$v" ]; then 38 | ici_forward_variable "$v" "$p_inner" 39 | fi 40 | fi 41 | } 42 | 43 | # ici_forward_variable VARNAME [VALUE] 44 | function ici_forward_variable() { 45 | if [ -n "${2-}" ]; then 46 | _docker_run_opts+=(-e "$1=$2") 47 | else 48 | _docker_run_opts+=(-e "$1") 49 | fi 50 | } 51 | 52 | ####################################### 53 | # rerun the CI script in docker container end exit the outer script 54 | # 55 | # Globals: 56 | # DOCKER_IMAGE (read-only) 57 | # ICI_SRC_PATH (read-only) 58 | # TARGET_REPO_PATH (read-only) 59 | # Arguments: 60 | # (None) 61 | # Returns: 62 | # (None) 63 | ####################################### 64 | function ici_isolate() { 65 | local file=${1}; shift 66 | 67 | if [ "${DOCKER_IMAGE-x}" = "" ]; then 68 | ici_error "Empty string passed to DOCKER_IMAGE. Specify a valid docker image or unset the environment variable to use the default image." 69 | fi 70 | 71 | if [ -n "${OS_CODE_NAME-}" ]; then 72 | DOCKER_IMAGE=${DOCKER_IMAGE:-${OS_NAME}:$OS_CODE_NAME} # scheme works for all supported OS images 73 | elif [ -z "${DOCKER_IMAGE-}" ]; then 74 | ici_error "Please set ROS_DISTRO, OS_CODE_NAME or DOCKER_IMAGE." 75 | fi 76 | 77 | if [ "$DOCKER_PULL" != false ]; then 78 | ici_step "pull_docker_image" ici_cmd docker pull "$DOCKER_IMAGE" 79 | fi 80 | 81 | if [ -z "${ROS_DISTRO:-}" ]; then 82 | ROS_DISTRO=$(docker image inspect --format "{{.Config.Env}}" "${DOCKER_IMAGE}" | grep -o -P "(?<=ROS_DISTRO=)[a-z]*") || ici_error "ROS_DISTRO is not set" 83 | elif [ "${ROS_DISTRO}" = "false" ]; then 84 | unset ROS_DISTRO 85 | fi 86 | 87 | ici_forward_mount TARGET_REPO_PATH ro 88 | if [ "$_BUNDLE_ICI" = true ]; then 89 | ici_forward_variable ICI_SRC_PATH 90 | else 91 | ici_forward_mount ICI_SRC_PATH ro 92 | fi 93 | ici_forward_mount BASEDIR rw 94 | ici_forward_mount CCACHE_DIR rw 95 | ici_forward_mount SSH_AUTH_SOCK rw # forward ssh agent into docker container 96 | ici_forward_mount GITHUB_OUTPUT rw # for ici_report_result in GitHub Actions 97 | 98 | local run_opts 99 | ici_parse_env_array run_opts DOCKER_RUN_OPTS 100 | 101 | for hook in $(env | grep -o '^\(BEFORE\|AFTER\)_[^=]*'); do 102 | ici_forward_variable "$hook" 103 | done 104 | 105 | ici_run_cmd_in_docker "${_docker_run_opts[@]}" "${run_opts[@]}" \ 106 | -t \ 107 | --entrypoint '' \ 108 | -w "$TARGET_REPO_PATH" \ 109 | "$DOCKER_IMAGE" \ 110 | /bin/bash "$ICI_SRC_PATH/run.sh" "$file" "$@" 111 | } 112 | ####################################### 113 | # wrapper for running a command in docker 114 | # 115 | # * enables environment passing 116 | # * set-ups SSH auth socket forwarding 117 | # * stops on interrupt signal 118 | # 119 | # Globals: 120 | # ICI_SRC_PATH (read-only) 121 | # SSH_AUTH_SOCK (read-only) 122 | # Arguments: 123 | # all argumentes will be forwarded 124 | # Returns: 125 | # (None) 126 | ####################################### 127 | function ici_run_cmd_in_docker() { 128 | local credentials=() 129 | ici_parse_env_array credentials DOCKER_CREDENTIALS 130 | local to_copy=() 131 | local cleanup="" 132 | 133 | for d in "${credentials[@]}"; do 134 | if [ -e "$HOME/$d" ]; then 135 | to_copy+=(~/"$d") 136 | # shellcheck disable=SC2088 137 | cleanup=$(ici_join_array : "$cleanup" "~/$d") 138 | fi 139 | done 140 | 141 | local opts=(--env-file "${ICI_SRC_PATH}/isolation/docker.env") 142 | if [ -z "$DOCKER_COMMIT" ]; then 143 | opts+=(--rm) 144 | else 145 | opts+=(-e "_CLEANUP=$cleanup") 146 | fi 147 | 148 | local cid 149 | cid=$(ici_cmd docker create --init "${opts[@]}" "$@") 150 | 151 | # detect user inside container 152 | local image 153 | image=$(ici_guard docker inspect --format='{{.Config.Image}}' "$cid") 154 | local docker_query=() 155 | # shellcheck disable=SC2016 156 | IFS=" " read -r -a docker_query <<< "$(docker run --rm --entrypoint '/bin/sh' "$image" -c 'echo "$(id -u) $(id -g) $HOME"')" 157 | 158 | # pass common credentials to container 159 | for d in "${to_copy[@]}"; do 160 | ici_warn "Copy credentials: $d" 161 | docker_cp "$d" "$cid:${docker_query[*]:2}/" "${docker_query[0]}" "${docker_query[1]}" 162 | done 163 | 164 | if [ "$_BUNDLE_ICI" = true ]; then 165 | tar -cPf - "$ICI_SRC_PATH" | docker cp - "$cid:/" 166 | fi 167 | 168 | trap '>/dev/null ici_label ici_quiet docker kill --signal=SIGTERM $cid && >/dev/null docker wait $cid' INT 169 | ( trap '' INT && ici_label docker start -a "$cid" > >(sed 's/\r$//') ) & 170 | local ret=0 171 | wait %% || ret=$? 172 | 173 | if [ -n "$DOCKER_COMMIT" ]; then 174 | local msg=() 175 | if [ -n "$DOCKER_COMMIT_MSG" ]; then 176 | msg=(-m "$DOCKER_COMMIT_MSG") 177 | fi 178 | ici_cmd docker commit "${msg[@]}" "$cid" "$DOCKER_COMMIT" 179 | ici_cmd ici_quiet docker rm "$cid" 180 | fi 181 | return "$ret" 182 | } 183 | 184 | # work-around for https://github.com/moby/moby/issues/34096 185 | # ensures that copied files are owned by the target user 186 | function docker_cp { 187 | set -o pipefail 188 | tar --numeric-owner --owner="${3:-root}" --group="${4:-root}" -c -f - -C "$(dirname "$1")" "$(basename "$1")" | docker cp - "$2" 189 | set +o pipefail 190 | } 191 | -------------------------------------------------------------------------------- /industrial_ci/src/tests/abi_check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2017, Mathias Lüdtke 4 | # All rights reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | function _install_universal_ctags() { 19 | ici_apt_install autoconf automake pkg-config 20 | ici_import_repository /tmp github:universal-ctags/ctags.git#master 21 | (ici_guard cd /tmp/ctags && ./autogen.sh && ./configure && ici_asroot make install) || ici_exit 22 | rm -rf /tmp/ctags 23 | } 24 | 25 | function _import_and_make_install() { 26 | local repo=$1; shift 27 | ici_import_repository /tmp "github:$repo.git#master" 28 | local dir; dir=/tmp/$(basename "$repo") 29 | (ici_guard cd "$dir" && ici_asroot make install prefix=/usr) || ici_exit 30 | rm -rf "$dir" 31 | } 32 | 33 | function _install_vtable_dumper() { 34 | ici_apt_install libelf-dev make 35 | _import_and_make_install lvc/vtable-dumper 36 | } 37 | 38 | function _install_abi_dumper() { 39 | ici_apt_install binutils elfutils perl make 40 | _import_and_make_install lvc/abi-dumper 41 | } 42 | 43 | function _install_abi_compliance_checker() { 44 | ici_apt_install perl make 45 | _import_and_make_install lvc/abi-compliance-checker 46 | } 47 | 48 | function abi_install_dumper() { 49 | ici_exec_for_command vtable-dumper ici_quiet _install_vtable_dumper 50 | ici_exec_for_command abi-dumper ici_quiet _install_abi_dumper 51 | ici_exec_for_command ctags ici_quiet _install_universal_ctags 52 | } 53 | 54 | function abi_install_compliance_checker() { 55 | ici_exec_for_command abi-compliance-checker ici_quiet _install_abi_compliance_checker 56 | } 57 | 58 | function abi_dump_libraries() { 59 | abi_install_dumper 60 | 61 | local extend=$1; shift 62 | local output=$1; shift 63 | 64 | local ld_library_path 65 | ld_library_path=$(ici_source_setup "$extend" && echo "$LD_LIBRARY_PATH") 66 | 67 | mkdir -p "$output" 68 | for d in "$extend"/*/lib "$extend/lib"; do 69 | for l in "$d"/*.so; do 70 | if [ "$l" != "$d/*.so" ]; then 71 | abi-dumper "$l" -ld-library-path "$ld_library_path" -o "$output/$(basename "$l" .so).dump" -public-headers "$d/../include" "$@" 72 | fi 73 | done 74 | done 75 | } 76 | 77 | function abi_process_workspace() { 78 | local extend=$1; shift 79 | local workspace=$1; shift 80 | local tag=$1; shift 81 | local version=${1:-$tag} 82 | 83 | local cflags="-g -Og" 84 | local cmake_args=(--cmake-args "-DCMAKE_C_FLAGS=$cflags" "-DCMAKE_CXX_FLAGS=$cflags") 85 | 86 | ici_step "install_${tag}_dependencies" ici_install_dependencies "$extend" "$ROSDEP_SKIP_KEYS" "$workspace/src" 87 | ici_step "abi_build_${tag}" builder_run_build "$extend" "$workspace" "${cmake_args[@]}" 88 | ici_step "abi_dump_${tag}" abi_dump_libraries "$(ici_extend_space "$workspace")" "$workspace/abi_dumps" -lver "$version" 89 | } 90 | 91 | function abi_configure() { 92 | if [ "$ABICHECK_MERGE" = true ]; then 93 | ici_exec_for_command git ici_error "ABICHECK_MERGE=true needs git client" 94 | local ref_list 95 | if ici_split_array ref_list "$(cd "$TARGET_REPO_PATH" && git rev-list --parents -n 1 HEAD)" && [ "${#ref_list[@]}" -gt 2 ]; then 96 | ABICHECK_VERSION="${ref_list[1]}" 97 | ABICHECK_URL="#${ABICHECK_VERSION}" 98 | else 99 | ici_error "Could not find merge commit for ABI check" 100 | fi 101 | fi 102 | 103 | if [ -z "$ABICHECK_VERSION" ]; then 104 | if [[ $ABICHECK_URL =~ [@#]([[:alnum:]_.-]+)$ ]]; then 105 | ABICHECK_VERSION=${BASH_REMATCH[1]} 106 | else 107 | local target_ext 108 | target_ext=$(grep -Pio '\.(zip|tar\.\w+|tgz|tbz2)\Z' <<< "${ABICHECK_URL%%\?*}" || echo "") 109 | if [ -n "$target_ext" ]; then 110 | ABICHECK_VERSION=$(basename "$ABICHECK_URL" "$target_ext") 111 | else 112 | ici_warn "could not determine ABICHECK_VERSION" 113 | ABICHECK_VERSION=unknown 114 | fi 115 | fi 116 | fi 117 | } 118 | 119 | function abi_report() { 120 | local base_dumps=$1; shift 121 | local target_dumps=$1; shift 122 | local reports_dir=$1; shift 123 | 124 | abi_install_compliance_checker 125 | ici_install_pkgs_for_command links links 126 | 127 | mkdir -p "$reports_dir" 128 | 129 | local broken=() 130 | for n in "$target_dumps"/*.dump; do 131 | local l; l=$(basename "$n" ".dump") 132 | local o="$base_dumps/$l.dump" 133 | if [ -f "$o" ]; then 134 | ici_time_start "abi_check_$l" 135 | local ret=0 136 | abi-compliance-checker -report-path "$reports_dir/$l.html" -l "$l" -n "$n" -o "$o" || ret=$? 137 | if [ "$ret" -eq "0" ]; then 138 | ici_time_end # abi_check_* 139 | elif [ "$ret" -eq "1" ]; then 140 | links -dump "$reports_dir/$l.html" 141 | broken+=("$l") 142 | ici_time_end "${ANSI_YELLOW}" "$ret" # abi_check_*, yellow 143 | elif [ "$ret" -eq "7" ]; then 144 | ici_warn "'$(basename "$l" .dump)': Invalid input ABI dump. Perhaps this library does not any export symbols." 145 | ici_time_end "${ANSI_YELLOW}" 146 | else 147 | return "$ret" 148 | fi 149 | fi 150 | done 151 | 152 | if [ "${#broken[@]}" -gt "0" ]; then 153 | ici_error "Broken libraries: ${broken[*]}" 154 | fi 155 | } 156 | 157 | function prepare_abi_check() { 158 | if [ "$ABICHECK_MERGE" = "auto" ]; then 159 | ici_error "ABICHECK_MERGE auto mode is available for travis and github only. " 160 | fi 161 | if [ -z "$ABICHECK_URL" ]; then 162 | ici_error "Please set ABICHECK_URL" 163 | fi 164 | 165 | ici_check_builder 166 | 167 | abi_configure # handle merge and detect version 168 | } 169 | 170 | function run_abi_check() { 171 | if [[ $ABICHECK_URL =~ ^[@#]([[:alnum:]_.-]+)$ ]]; then 172 | ABICHECK_URL="git+file://${TARGET_REPO_PATH}${ABICHECK_URL}" 173 | fi 174 | 175 | base_ws=$BASEDIR/${PREFIX}base_ws 176 | upstream_ws=$BASEDIR/${PREFIX}upstream_ws 177 | target_ws=$BASEDIR/${PREFIX}target_ws 178 | 179 | ici_with_ws "$base_ws" ici_step "abi_get_base" ici_prepare_sourcespace "$base_ws/src" "$ABICHECK_URL" 180 | 181 | ici_source_builder 182 | ici_step "${BUILDER}_setup" builder_setup 183 | ici_step "setup_rosdep" ici_setup_rosdep 184 | 185 | if [ -n "$CCACHE_DIR" ]; then 186 | ici_step "setup_ccache" ici_apt_install ccache 187 | export PATH="/usr/lib/ccache:$PATH" 188 | fi 189 | 190 | extend=${UNDERLAY:?} 191 | 192 | if [ -n "$UPSTREAM_WORKSPACE" ]; then 193 | ici_with_ws "$upstream_ws" ici_build_workspace "upstream" "$extend" "$upstream_ws" 194 | extend="$(ici_extend_space "$upstream_ws")" 195 | fi 196 | 197 | mkdir -p "$target_ws/src" 198 | ici_import_directory "$target_ws/src" "$TARGET_REPO_PATH" 199 | 200 | ici_step "abi_install_compliance_checker" abi_install_compliance_checker 201 | ici_step "abi_install_dumper" abi_install_dumper 202 | 203 | ici_with_ws "$target_ws" abi_process_workspace "$extend" "$target_ws" target 204 | ici_with_ws "$base_ws" abi_process_workspace "$extend" "$base_ws" base "$ABICHECK_VERSION" 205 | 206 | abi_report "$base_ws/abi_dumps" "$target_ws/abi_dumps" "$BASEDIR/abicheck/$ABICHECK_VERSION" 207 | } 208 | -------------------------------------------------------------------------------- /industrial_ci/src/keys/snapshots.asc: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PUBLIC KEY BLOCK----- 2 | Comment: Hostname: 3 | Version: Hockeypuck 2.2 4 | 5 | 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 119 | =vAxZ 120 | -----END PGP PUBLIC KEY BLOCK----- 121 | -------------------------------------------------------------------------------- /industrial_ci/python/industrial_ci/travis.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | # Copyright (c) 2017, Mathias Lüdtke 5 | # All rights reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | from __future__ import print_function 20 | 21 | import difflib 22 | import os 23 | import os.path 24 | import re 25 | import subprocess 26 | import sys 27 | 28 | import yaml 29 | 30 | # find config file either in first argument or curret working directory 31 | def find_config_file(args, names): 32 | def test_file(dir): # test if one of the file names is present 33 | for n in names: 34 | p = os.path.join(dir, n) 35 | if os.path.isfile(p): 36 | return os.path.abspath(p) 37 | return None 38 | 39 | if len(args) > 0: # test first argument if available 40 | arg0=args[0] 41 | if os.path.isfile(arg0): 42 | return os.path.abspath(arg0),args[1:] 43 | p = test_file(arg0) 44 | if p is not None: 45 | return p, args[1:] 46 | return test_file(os.getcwd()), args 47 | 48 | # parse range tuples from arguments 49 | def parse_ranges(args, offset=0): 50 | r = [] 51 | def apply_offset(i): # adjust for user offsets 52 | ao = int(i) + offset 53 | if ao < 0: 54 | raise ValueError("%s is not in supported range" % str(i)) 55 | return ao 56 | 57 | for a in args: 58 | if '-' in a: # range string 59 | p1, p2 = a.split('-', 2) 60 | if p1 == '' and len(r) == 0: # -X 61 | p1 = 0 62 | else: # X-[Y] 63 | p1 = apply_offset(p1) 64 | if p2 == '': # [X]- 65 | r.append((p1, -1)) 66 | break 67 | r.append((p1, apply_offset(p2)+1)) # X-Y 68 | else: 69 | i = apply_offset(a) 70 | r.append((i, i+1)) 71 | return r 72 | 73 | def apply_ranges(ranges, num): 74 | for start,end in ranges: 75 | if end == -1: 76 | end = num 77 | for i in range(start,end): 78 | yield i 79 | 80 | 81 | def read_yaml(p): 82 | with open(p) as f: 83 | return yaml.safe_load(f) 84 | 85 | # read global and job-specific envs from 86 | def read_env(env): 87 | m = env 88 | g = '' 89 | if isinstance(env, dict): 90 | m = env['matrix'] 91 | if 'global' in env: 92 | g = ' '.join(env['global']) 93 | return g, m 94 | 95 | def read_allow_failures(config): 96 | try: 97 | af = config['matrix']['allow_failures'] 98 | except: 99 | return list() 100 | return list(x['env'] for x in af) 101 | 102 | def read_num_include(config): 103 | try: 104 | return len(config['matrix']['include']) 105 | except: 106 | return 0 107 | 108 | def parse_extra_args(args): 109 | try: 110 | extra = args.index('--') 111 | return args[0:extra], args[extra+1:] 112 | except ValueError: 113 | return args, [] 114 | 115 | env_assigment = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*=") 116 | def gen_env(e): 117 | if env_assigment.match(e): 118 | return e 119 | return '%s=%s' % (e, os.getenv(e, '')) 120 | 121 | # from https://github.com/travis-ci/travis-build/blob/73bf69a439bb546520a5e5b6b6847fb5424a7c9f/lib/travis/build/env/var.rb#L5 122 | travis_env = re.compile(r"([\w]+)=((?:[^\"'`\ ]?(\"|'|`).*?((? 0): 177 | print('Globals: %s' % str(highlight_diff(global_env))) 178 | jobs = len(job_envs) 179 | digits = len(str(jobs)) 180 | for i in range(jobs): 181 | print('Job %s%s: %s' % ( str(i+1).rjust(digits), 182 | ' (allow_failures)' if job_envs[i] in allow_failures else '', 183 | highlight_diff(job_envs[i]) if job_envs[i] is not None else "")) 184 | print("run all with %s -" % sys.argv[0]) 185 | sys.exit(0) 186 | 187 | ranges = parse_ranges(args, -1) 188 | 189 | run_ci = [os.path.join(scripts_dir, "run_ci"), os.path.dirname(path), filter_env(global_env)] 190 | run_ci_diff = [os.path.join(scripts_dir, "run_ci"), os.path.dirname(path), highlight_diff(global_env, 44)] 191 | 192 | bash = ['env', '-i'] +list(map(gen_env, ['DOCKER_PORT', 'HOME', 'PATH', 'SSH_AUTH_SOCK', 'TERM'])) + ['bash','-e'] 193 | 194 | selection = set(apply_ranges(ranges, len(job_envs))) 195 | 196 | for i in selection: 197 | if job_envs[i] is None: 198 | print("\033[1;43mSkipped job %d, because jobs from 'include' section are not supported\033[1;m" %(i+1,)) 199 | continue 200 | cmd = ' '.join(run_ci + [filter_env(job_envs[i])] + list(map(gen_env, extra_env))) 201 | cmd_diff = ' '.join(run_ci_diff + [highlight_diff(job_envs[i], 44)] + list(map(gen_env, extra_env))) 202 | print('\033[1;44mRunning job %d%s: %s\033[1;m' %(i+1, ' (allow_failures)' if job_envs[i] in allow_failures else '', cmd_diff)) 203 | 204 | proc = subprocess.Popen(bash, stdin=subprocess.PIPE) 205 | proc.communicate(cmd.encode()) 206 | if proc.returncode: 207 | print('\033[1;41mFailed job %d: %s\033[1;m' %(i+1, cmd)) 208 | if job_envs[i] not in allow_failures: 209 | sys.exit(proc.returncode) 210 | 211 | -------------------------------------------------------------------------------- /industrial_ci/src/ros.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2015, Isaac I. Y. Saito 4 | # Copyright (c) 2017, Mathias Lüdtke 5 | # All rights reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | function _ros1_defaults { 20 | export OS_CODE_NAME=${OS_CODE_NAME:-$1} 21 | export ROS1_DISTRO=${ROS1_DISTRO:-$ROS_DISTRO} 22 | export BUILDER=${BUILDER:-catkin_tools} 23 | export ROS_VERSION=1 24 | export ROS_VERSION_EOL=false 25 | export ROS_VERSION_FINAL="final" 26 | export ROS_PYTHON_VERSION=${ROS_PYTHON_VERSION:-2} 27 | } 28 | 29 | function _ros2_defaults { 30 | export OS_CODE_NAME=${OS_CODE_NAME:-$1} 31 | export ROS2_DISTRO=${ROS2_DISTRO:-$ROS_DISTRO} 32 | export BUILDER=${BUILDER:-colcon} 33 | export ROS_VERSION=2 34 | export ROS_VERSION_EOL=false 35 | export ROS_VERSION_FINAL="final" 36 | export ROS_PYTHON_VERSION=3 37 | } 38 | 39 | function _ros_is_eol { 40 | export ROS_VERSION_EOL=true 41 | export ROSDISTRO_INDEX_VERSION=${ROSDISTRO_INDEX_VERSION:-$1} 42 | } 43 | 44 | function _set_ros_defaults { 45 | case "$ROS_DISTRO" in 46 | "indigo"|"jade") 47 | _ros1_defaults "trusty" 48 | _ros_is_eol "kinetic/2021-05-11" 49 | export _ROS_KEYRING=/etc/apt/trusted.gpg.d/ros-archive-keyring.gpg # signed-by is not supported 50 | ;; 51 | "kinetic") 52 | _ros1_defaults "xenial" 53 | _ros_is_eol "kinetic/2021-05-11" 54 | ;; 55 | "lunar") 56 | _ros1_defaults "xenial" 57 | _ros_is_eol "kinetic/2021-05-11" 58 | ;; 59 | "melodic") 60 | _ros1_defaults "bionic" 61 | _ros_is_eol "melodic/2023-06-27" 62 | ;; 63 | "noetic") 64 | _ros1_defaults "focal" 65 | export ROS_PYTHON_VERSION=3 66 | if [ "$OS_NAME" = "debian" ]; then 67 | _ros_is_eol "noetic/2023-03-02" 68 | export ROS_VERSION_FINAL_DEBIAN=true 69 | else 70 | _ros_is_eol "noetic/2025-05-29" 71 | fi 72 | ;; 73 | "ardent") 74 | _ros2_defaults "xenial" 75 | _ros_is_eol "dashing/2021-06-10" 76 | ;; 77 | "bouncy"|"crystal") 78 | _ros2_defaults "bionic" 79 | _ros_is_eol "dashing/2021-06-10" 80 | ;; 81 | "dashing") 82 | _ros2_defaults "bionic" 83 | _ros_is_eol "dashing/2021-06-10" 84 | ;; 85 | "eloquent") 86 | _ros2_defaults "bionic" 87 | _ros_is_eol "eloquent/2020-12-12" 88 | ;; 89 | "foxy") 90 | _ros2_defaults "focal" 91 | _ros_is_eol "foxy/2023-06-20" 92 | ;; 93 | "galactic") 94 | _ros2_defaults "focal" 95 | _ros_is_eol "galactic/2022-12-09" 96 | ;; 97 | "humble") 98 | _ros2_defaults "jammy" 99 | ;; 100 | "iron") 101 | _ros2_defaults "jammy" 102 | _ros_is_eol "iron/2024-12-04" 103 | ;; 104 | "jazzy") 105 | _ros2_defaults "noble" 106 | ;; 107 | "kilted") 108 | _ros2_defaults "noble" 109 | ;; 110 | "rolling") 111 | _ros2_defaults "noble" 112 | if [ "$OS_CODE_NAME" == "jammy" ]; then 113 | if [ -z "$ROSDISTRO_INDEX_VERSION" ]; then 114 | ici_warn "Pinning rolling to latest support version on jammy: 2024-02-28" 115 | export ROSDISTRO_INDEX_VERSION=rolling/2024-02-28 116 | fi 117 | fi 118 | ;; 119 | "false") 120 | unset ROS_DISTRO 121 | ;; 122 | *) 123 | ici_error "ROS_DISTRO '$ROS_DISTRO' is not supported" 124 | ;; 125 | esac 126 | 127 | if [ "$ROS_PYTHON_VERSION" = 2 ]; then 128 | export PYTHON_VERSION_NAME=python 129 | elif [ "$ROS_PYTHON_VERSION" = 3 ]; then 130 | export PYTHON_VERSION_NAME=python3 131 | fi 132 | 133 | } 134 | 135 | function _use_snapshot() { 136 | local osname="ubuntu" 137 | if [ "$1" = "$ROS_VERSION_FINAL" ] && [ "${ROS_VERSION_FINAL_DEBIAN:-false}" = true ]; then 138 | osname="debian" 139 | fi 140 | export ROS_REPOSITORY_PATH="http://snapshots.ros.org/${ROS_DISTRO?ROS_DISTRO needs to be set}/$1/$osname" 141 | export ROS_REPOSITORY_KEY="$ICI_SRC_PATH/keys/snapshots.asc" 142 | } 143 | 144 | function _use_repo_or_final_snapshot() { 145 | if [ "$ROS_VERSION_EOL" = true ]; then 146 | if [ "$ROS_REPO" != "testing" ]; then 147 | ici_warn "'$ROS_DISTRO' is in end-of-life state, ROS_REPO='$ROS_REPO' is superfluous" 148 | fi 149 | if [ -n "$ROS_VERSION_FINAL" ]; then 150 | _use_snapshot "$ROS_VERSION_FINAL" 151 | return 152 | fi 153 | fi 154 | export ROS_REPOSITORY_PATH="$1" 155 | if [ "${ROS_REPO}" = "ros-shadow-fixed" ]; then 156 | ici_warn "ROS_REPO='ros-shadow-fixed' was renamed to ROS_REPO='testing'" 157 | fi 158 | } 159 | 160 | function _get_prefix() { 161 | if [ "$ROS_VERSION" -eq 2 ]; then 162 | echo ros2 163 | else 164 | echo ros 165 | fi 166 | } 167 | 168 | function ici_set_ros_repository_path { 169 | local current_repository_path=$1; shift 170 | if [ -z "${ROS_REPOSITORY_PATH}" ]; then 171 | case "$ROS_REPO" in 172 | "building") 173 | _use_repo_or_final_snapshot "http://repositories.ros.org/ubuntu/building/" 174 | ;; 175 | "main") 176 | _use_repo_or_final_snapshot "http://packages.ros.org/$(_get_prefix)/ubuntu" 177 | ;; 178 | "ros") 179 | if [ "$ROS_VERSION" -eq 2 ]; then 180 | ici_warn "ROS_REPO=ros would select the ROS1 repository, please use ROS_REPO=main" 181 | fi 182 | _use_repo_or_final_snapshot "http://packages.ros.org/$(_get_prefix)/ubuntu" 183 | ;; 184 | "ros1") 185 | _use_repo_or_final_snapshot "http://packages.ros.org/ros/ubuntu" 186 | ;; 187 | "ros2") 188 | _use_repo_or_final_snapshot "http://packages.ros.org/ros2/ubuntu" 189 | ;; 190 | "") 191 | if [ -n "$current_repository_path" ]; then 192 | export ROS_REPOSITORY_PATH=$current_repository_path 193 | return 194 | fi 195 | ici_warn "Using default ROS_REPO=testing" 196 | export ROS_REPO=testing 197 | ;& 198 | "testing") 199 | _use_repo_or_final_snapshot "http://packages.ros.org/$(_get_prefix)-testing/ubuntu" 200 | ;; 201 | "ros-shadow-fixed"|"ros-testing") 202 | if [ "$ROS_VERSION" -eq 2 ]; then 203 | ici_warn "ROS_REPO=$ROS_REPO would select the ROS1 repository, please use ROS_REPO=testing" 204 | fi 205 | _use_repo_or_final_snapshot "http://packages.ros.org/$(_get_prefix)-testing/ubuntu" 206 | ;; 207 | "ros1-testing") 208 | _use_repo_or_final_snapshot "http://packages.ros.org/ros-testing/ubuntu" 209 | ;; 210 | "ros2-testing") 211 | _use_repo_or_final_snapshot "http://packages.ros.org/ros2-testing/ubuntu" 212 | ;; 213 | "final"|????-??-??) 214 | _use_snapshot "${ROS_REPO}" 215 | ;; 216 | "false") 217 | export ROS_REPOSITORY_PATH=$current_repository_path 218 | ;; 219 | *) 220 | ici_error "ROS repo '$ROS_REPO' is not supported" 221 | ;; 222 | esac 223 | fi 224 | } 225 | 226 | function ici_configure_ros() { 227 | if [ -n "${ROS_DISTRO}" ]; then 228 | _set_ros_defaults 229 | fi 230 | } 231 | -------------------------------------------------------------------------------- /industrial_ci/src/tests/source_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright (c) 2015, Isaac I. Y. Saito 4 | # Copyright (c) 2019, Mathias Lüdtke 5 | # All rights reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | ## Greatly inspired by JSK travis https://github.com/jsk-ros-pkg/jsk_travis 20 | 21 | # source_tests.sh script runs integration tests for the target ROS packages. 22 | # It is dependent on environment variables that need to be exported in advance 23 | # (As of version 0.4.4 most of them are defined in env.sh). 24 | 25 | function install_catkin_lint { 26 | local catkin_lint_pkg="catkin-lint" 27 | if [ "$ROS_PYTHON_VERSION" == "2" ]; then 28 | catkin_lint_pkg="catkin-lint<1.6.23" 29 | fi 30 | ici_install_pypi_pkgs_for_command catkin_lint "$catkin_lint_pkg" 31 | } 32 | 33 | function run_clang_tidy { 34 | local regex="$1/.*" 35 | local -n _run_clang_tidy_warnings=$2 36 | local -n _run_clang_tidy_errors=$3 37 | local db=$4 38 | shift 4 39 | 40 | local build; build="$(dirname "$db")" 41 | local name; name="$(basename "$build")" 42 | ici_time_start "clang_tidy_check_$name" 43 | 44 | # create an array of all files listed in $db filtered by the source tree 45 | mapfile -t files < <(grep -oP "(?<=\"file\": \")($regex)(?=\")" "$db") 46 | local num_all_files="${#files[@]}" 47 | if [ "$num_all_files" -gt 0 ] && [ -n "$CLANG_TIDY_BASE_REF" ] ; then 48 | ici_log "Filtering for files that actually changed since $CLANG_TIDY_BASE_REF" 49 | # Need to run git in actual source dir: $files[@] refer to source dir and $PWD is read-only 50 | local src_dir 51 | src_dir=$(grep -oP "(?<=CMAKE_HOME_DIRECTORY:INTERNAL=).*" "$build/CMakeCache.txt") 52 | pushd "$src_dir" > /dev/null || true 53 | if git fetch -q origin "$CLANG_TIDY_BASE_REF" 2> /dev/null; then # git might fail, e.g. operating on catkin_tools_prebuild 54 | # Filter for changed files, using sed to augment full path again (which git strips away) 55 | mapfile -t files < <(git diff --name-only --diff-filter=MA FETCH_HEAD..HEAD -- "${files[@]}" | sed "s#^#$(git rev-parse --show-toplevel)/#") 56 | fi 57 | popd > /dev/null || true 58 | fi 59 | if [ "${#files[@]}" -eq 0 ]; then 60 | ici_log "${#files[@]}/$num_all_files source files need checking" 61 | ici_time_end 62 | return 0 63 | fi 64 | 65 | local max_jobs="${CLANG_TIDY_JOBS:-$(nproc)}" 66 | if ! [ "$max_jobs" -ge 1 ]; then 67 | ici_error "CLANG_TIDY_JOBS=$CLANG_TIDY_JOBS is invalid." 68 | fi 69 | 70 | local err=0 71 | ici_log "run clang-tidy for ${#files[@]}/$num_all_files file(s) in $max_jobs process(es)." 72 | set -o pipefail 73 | printf "%s\0" "${files[@]}" | xargs --null run-clang-tidy "-j$max_jobs" "-header-filter=\"$regex\"" "-p=$build" "$@" 2>&1 | tee "$db.tidy.log" || err=$? 74 | set +o pipefail 75 | 76 | if [ "$err" -ne "0" ]; then 77 | _run_clang_tidy_errors+=("$name") 78 | ici_time_end "${ANSI_RED}" "$err" 79 | elif grep -q "warning: " "$db.tidy.log"; then 80 | _run_clang_tidy_warnings+=("$name") 81 | ici_time_end "${ANSI_YELLOW}" 82 | else 83 | ici_time_end 84 | fi 85 | } 86 | 87 | function run_clang_tidy_check { 88 | local target_ws=$1 89 | local errors=() 90 | local warnings=() 91 | local clang_tidy_args=() 92 | ici_parse_env_array clang_tidy_args CLANG_TIDY_ARGS 93 | 94 | ici_step "install_clang_tidy" ici_install_pkgs_for_command clang-tidy clang-tidy "$(apt-cache depends --recurse --important clang | grep "^libclang-common-.*")" 95 | if [ -n "$CLANG_TIDY_BASE_REF" ]; then 96 | ici_setup_git_client 97 | fi 98 | 99 | ici_hook "before_clang_tidy_checks" 100 | 101 | # replace -export-fixes with temporary file 102 | local fixes_final="" 103 | local fixes_tmp 104 | local num_args=${#clang_tidy_args[@]} 105 | fixes_tmp=$(mktemp) 106 | for (( i=0; i`__). 15 | This is the refactored version with ROS2 support, the old version can be found in the `legacy branch `__. 16 | Please check the `migration guide `__ as well. 17 | 18 | .. contents:: Table of Contents 19 | :depth: 2 20 | 21 | Detailed documentation 22 | ======================== 23 | 24 | Other than the brief introduction in this page, you can also check `the detailed doc here <./doc/index.rst>`__. 25 | 26 | Introduction 27 | ============ 28 | 29 | This package contains `CI (Continuous Integration) `__ scripts that any ROS-powered packages can commonly use. 30 | Some notable feature: 31 | 32 | * Checks if your package builds, installs without issues. If unit/system tests are defined run them. `ROS Prerelease Test `__ can optionally be run. 33 | * Proven to cover the general requirements of the ROS-based robotics repositories. Easily configurable. 34 | * Users can add custom pre/post processes. 35 | * Covers ROS1 Indigo, Jade, Kinetic, Lunar, Melodic, Noetic and ROS2 distributions. 36 | * This repo provides scripts for `Bitbucket CI`, `Gitlab CI`, `GitHub Actions` and `Travis CI` only, but it can be easily adapted for other CI services. 37 | 38 | For a brief overall introduction, you could also check a presentation: 39 | 40 | * `ROS-Industrial community meeting `__ 41 | 42 | Quick Start 43 | ============ 44 | 45 | With a few steps, you can start in your client repository using CI confiurations stored in `industrial_ci`. 46 | 47 | For Travis CI 48 | -------------- 49 | 50 | 1. Activate CI for your github repository on `Travis CI `__). 51 | 52 | a) You may do so either at https://travis-ci.com/github/YOUR_GITHUB_ORGANIZATION or at https://travis-ci.com/github/YOUR_GITHUB_USER (depending on where your repository sits). 53 | b) Activate CI beta for your bitbucket repository is similar, but the target link that your status badge directs to needs to be modified from https://travis-ci.com/USERNAME/REPO_NAME to https://travis-ci.com/bitbucket/USERNAME/REPO_NAME. By default, the generated link directs to a github repository. 54 | 55 | 2. Add `.travis.yml` file to your repository root (`complete template `__): 56 | 57 | :: 58 | 59 | language: generic 60 | services: 61 | - docker 62 | 63 | env: 64 | matrix: 65 | - ROS_DISTRO="indigo" 66 | 67 | install: 68 | - git clone --quiet --depth 1 https://github.com/ros-industrial/industrial_ci.git .industrial_ci -b master 69 | script: 70 | - .industrial_ci/travis.sh 71 | 72 | * Note: The name `.industrial_ci` is NO longer REQUIRED for the cloned folder starting version 0.3.2; you can pick any name (recommended practice to keep the folder hidden (by prepending "."). 73 | 74 | For Gitlab CI 75 | ------------- 76 | 77 | 1. Enable CI for your repo. Please refer to `official doc `__ for the steps to do so. Note for Gitlab CI, necessary steps might be different between hosted version (i.e. the one on gitlab.com) v.s. the one on your own server, which Gitlab doesn't always clarify in its documentation. 78 | 79 | 1. For your server version, enable a runner for your Gitlab project which uses the Docker executor. See instructions on how to `install `__ and `register `__ such a runner with your Gitlab instance if you haven't done so yet. 80 | 81 | 2. In `.gitlab-ci.yml` file in your client repo, add the following minimal configuration (this snippet can be the entire content of the file), replacing indigo for your chosen distro: 82 | 83 | :: 84 | 85 | image: docker:git 86 | services: 87 | - docker:dind 88 | before_script: 89 | - apk add --update bash coreutils tar 90 | - git clone --quiet --depth 1 https://github.com/ros-industrial/industrial_ci .industrial_ci -b master 91 | indigo: 92 | script: .industrial_ci/gitlab.sh ROS_DISTRO=indigo 93 | 94 | 95 | For Bitbucket Pipelines 96 | ----------------------- 97 | 98 | 1. Enable CI for your repo. Please refer to `official doc `__ for the steps to do so. 99 | 2. In the `bitbucket-pipelines.yml` file in your client repo, add the following minimal configuration (this snippet can be the entire content of the file), replacing indigo for your chosen distro: 100 | 101 | :: 102 | 103 | image: docker:git 104 | 105 | pipelines: 106 | default: 107 | - step: 108 | services: 109 | - docker 110 | script: 111 | - apk add --update bash coreutils tar 112 | - git clone --quiet --depth 1 https://github.com/ros-industrial/industrial_ci .industrial_ci -b master 113 | - .industrial_ci/bitbucket.sh ROS_DISTRO=indigo 114 | 115 | definitions: 116 | services: 117 | docker: 118 | memory: 2048 119 | 120 | 121 | For GitHub Actions 122 | ----------------------- 123 | 124 | 1. Create `.github/workflows/industrial_ci_action.yml` (industrial_ci_action.yml is arbitrary, `complete template `__) with the following configuration, (this snippet can be the entire content of the file), replacing melodic for your chosen distro: 125 | 126 | :: 127 | 128 | name: CI 129 | 130 | on: [push, pull_request] 131 | 132 | jobs: 133 | industrial_ci: 134 | strategy: 135 | matrix: 136 | env: 137 | - {ROS_DISTRO: melodic, ROS_REPO: testing} 138 | - {ROS_DISTRO: melodic, ROS_REPO: main} 139 | runs-on: ubuntu-latest 140 | steps: 141 | - uses: actions/checkout@v4 142 | - uses: 'ros-industrial/industrial_ci@master' 143 | env: ${{matrix.env}} 144 | 145 | For Google Cloud Build 146 | ---------------------- 147 | 1. Connect your source code repository to your Google Cloud Project. Please refer to the `official documentation `__ for the steps to do so. 148 | 2. In the `cloudbuild.yaml` file in your client repo, add the following minimal configuration 149 | 150 | :: 151 | 152 | steps: 153 | - name: 'ros:melodic' 154 | entrypoint: 'bash' 155 | args: 156 | - '-c' 157 | - |- 158 | git clone --depth 1 https://github.com/ros-industrial/industrial_ci .industrial_ci -b master 159 | .industrial_ci/ci.sh 160 | env: 161 | - 'ISOLATION=shell' 162 | - 'CI=true' 163 | 164 | Concrete examples of config files 165 | ------------------------------------- 166 | 167 | - A `template for Travis CI `__. 168 | - For development branch intended for ROS Indigo: `ros_canopen `__ 169 | - For development branch intended for ROS Indigo onward: 170 | - `example 1 `__ (Indigo and Jade compatible). 171 | - `example 2 `__ (Indigo, Jade, Kinetic compatible. Also runs `ROS Prerelease Test `__). 172 | - For development branch intended for ROS Kinetic: `industrial_core `__ 173 | - For more complexed example: `.travis.yml `__ from the same repo. You can see how options are used. 174 | - For Gitlab CI, a small `sample config <./.gitlab-ci.yml>`__. 175 | 176 | Metrics 177 | ======== 178 | 179 | There might not an easy way to precisely count how many repositories out there are using `industrial_ci`. Counting that number isn't even our priority at all, but we're often simply curious. Here's some ways that give us some clues for the usage metrics: 180 | 181 | - `Searching Github repos that contain string industrial_ci `__) (with some duplicates. Excluding industrial_ci repo): 182 | 183 | - 1,841 (Jan 2, 2019) 184 | - 675 (May 15, 2018) 185 | - 457 (Dec 12, 2017) 186 | - 142 (Jan 20, 2017) 187 | 188 | - Github--> `Graphs` --> `Traffic` view (visible only to admins). 189 | 190 | - Dec 30, 2018 191 | 192 | .. figure:: http://ros-industrial.github.io/industrial_ci/images/industrial_ci_traffic_20181230.png 193 | 194 | - May 15, 2018 195 | 196 | .. figure:: http://ros-industrial.github.io/industrial_ci/images/industrial_ci_20180515_traffic.png 197 | 198 | - Dec 12, 2017 199 | 200 | .. figure:: http://ros-industrial.github.io/industrial_ci/images/industrial_ci_traffic_20171212.png 201 | 202 | - Jan 20, 2017 203 | 204 | .. figure:: http://ros-industrial.github.io/industrial_ci/images/industrial_ci_traffic_20170120.png 205 | 206 | EoF 207 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /doc/migration_guide.md: -------------------------------------------------------------------------------- 1 | # Migration guide 2 | 3 | This guide covers the migration from the [legacy](https://github.com/ros-industrial/industrial_ci/tree/legacy) version. 4 | 5 | ## What's new? 6 | 7 | The new version comes with a number of improvements: 8 | 9 | * Added support for catkin_make, catkin_make_isolated and colcon 10 | * Use [vcstool](https://github.com/dirk-thomas/vcstool)(`vcs`) instead of `wstool` to support \*.rosinstall and \*.repos files 11 | * Added support for ROS2, and vcstool (rosinstall or repos files) 12 | * Available as GitHub Action 13 | * Separate upstream and downstream [workspaces](index.rst#workspace-management), even for prerelease tests 14 | * Fine-grained [hook system](index.rst#customize-within-the-ci-process) for customization 15 | * Writable target folder 16 | 17 | ## What's the catch? 18 | 19 | Some features are not supported anymore: 20 | 21 | * Support of ROS hydro 22 | * Devel space builds 23 | * Testing installed \*.test files 24 | * Building Docker images 25 | * Injecting QEMU (see [`INJECT_QEMU`](#inject_qemu)) 26 | 27 | If you depend on these, you can still use the [legacy](https://github.com/ros-industrial/industrial_ci/tree/legacy) version. 28 | 29 | ## How can I migrate? 30 | 31 | First of all, you have to switch to the master branch in your CI config: 32 | ``` 33 | git clone --quiet --depth 1 https://github.com/ros-industrial/industrial_ci.git .industrial_ci -b master 34 | ``` 35 | 36 | There is a big chance that the new version works out of the box. 37 | However, the workspace layout and the locations are changed. 38 | 39 | Special care must be taken, if you use any of these variables: 40 | 41 | * [`ABICHECK_URL`](#abicheck_url) 42 | * [`ADDITIONAL_DEBS`](#additional_debs) 43 | * [`AFTER_SCRIPT`](#after_script) 44 | * [`APTKEY_STORE_HTTPS`](#aptkey_store_https) 45 | * [`APTKEY_STORE_SKS`](#aptkey_store_sks) 46 | * [`AFTER_SCRIPT`](#after_script) 47 | * [`BEFORE_SCRIPT`](#before_script) 48 | * [`BUILD_PKGS_WHITELIST`](#build_pkgs_whitelist) 49 | * [`BUILDER`](#builder) 50 | * [`CATKIN_CONFIG`](#catkin_config) 51 | * [`CATKIN_PARALLEL_JOBS`](#catkin_parallel_jobs) 52 | * [`CATKIN_PARALLEL_TEST_JOBS`](#catkin_parallel_test_jobs) 53 | * [`CMAKE_ARGS`](#cmake_args) 54 | * [`DOCKER_BASE_IMAGE`](#docker_base_image) 55 | * [`DOCKER_BUILD_OPTS`](#docker_build_opts) 56 | * [`DOCKER_FILE`](#docker_file) 57 | * [`DOCKER_IMAGE`](#docker_image) 58 | * [`HASHKEY_SKS`](#hashkey_sks) 59 | * [`NOT_TEST_INSTALL`](#not_test_install) 60 | * [`INJECT_QEMU`](#inject_qemu) 61 | * [`PKGS_DOWNSTREAM`](#pkgs_downstream) 62 | * [`ROSINSTALL_FILENAME`](#rosinstall_filename) 63 | * [`ROS_PARALLEL_JOBS`](#ros_parallel_jobs) 64 | * [`ROS_PARALLEL_TEST_JOBS`](#ros_parallel_test_jobs) 65 | * [`ROS_REPOSITORY_PATH`](#ros_repository_path) 66 | * [`TARGET_PKGS`](#target_pkgs) 67 | * [`UBUNTU_OS_CODE_NAME`](#ubuntu_os_code_name) 68 | * [`UPSTREAM_WORKSPACE`](#upstream_workspace) 69 | * [`USE_DEB`](#use_deb) 70 | * [`VERBOSE_OUTPUT`](#verbose_output) 71 | * [`VERBOSE_TESTS`](#verbose_tests) 72 | * [`USE_MOCKUP`](#use_mockup) 73 | 74 | ## Changes summary 75 | 76 | ### Workspace layout 77 | 78 | The workspace layout has changed (new [workspace management](index.rst#workspace-management)). 79 | The target workspace is now located in `$BASEDIR/${PREFIX}target_ws`. 80 | The upstream workspace packages are now located in `$BASEDIR/${PREFIX}upstream_ws`. 81 | 82 | ### Job control 83 | 84 | `industrial_ci` does not set defaults for the number of build jobs anymore. 85 | `PARALLEL_BUILDS=N` can be used to enforce a limit. 86 | The number of parallel test is now limited to 1 per default to allow for reproducible tests. 87 | Specify `PARALLEL_TESTS=true` or `PARALLEL_TESTS=N` to opt out. 88 | 89 | ### Hook system 90 | 91 | The customization support via `BEFORE_SCRIPT` and `AFTER_SCRIPT` has been refactored into a flexible [hook system](index.rst#customize-within-the-ci-process), which offers script support for every step in the workflow. 92 | 93 | The new system can read exposed variables and use the `industrial_ci` functions. 94 | The [workspace layout has changed](#workspace-layout), so your scripts might need to get adapted accordingly. 95 | To simplify the migration the script hooks can read the workspace location from the `base_ws` (ABI check only), `downstream_ws`,`target_ws` and `upstream_ws` variables. 96 | In addition steps that deal with workspaces expose the `current_ws` variable. 97 | Please note that the variables can be used in the script option itself, but not in invoked scripts. 98 | You have to pass them into your script, e.g. 99 | ``` 100 | AFTER_SETUP_UPSTREAM_WORKSPACE='./my_script.sh "$current_ws"' 101 | ``` 102 | (*For Gitlab CI you have to use `$$variable` to prevent the premature substitution*) 103 | 104 | Furthermore, the hook will get run without a ROS environment (`setup.bash`). 105 | If you need this environment, you can use the `rosenv` helper. 106 | Optionally, it takes a command to be executed. 107 | 108 | Examples: 109 | 110 | * `AFTER_SETUP_UPSTREAM_WORKSPACE='rosenv && echo "$ROS_DISTRO'"` 111 | * `AFTER_SETUP_UPSTREAM_WORKSPACE='rosenv ./my_script.sh'` 112 | 113 | ## Affected variables 114 | 115 | ### ABICHECK_URL 116 | 117 | Everything should work as before, but git-protocol will get used by default. 118 | In addition, the extended [definition syntax](index.rst#workspace-definition) is supported. 119 | 120 | ### ADDITIONAL_DEBS 121 | 122 | This variable is still supported and is now implemented for all tests. 123 | 124 | ### AFTER_SCRIPT 125 | 126 | This variable is still supported, but the [script environment has changed](#hook-system). 127 | 128 | ### APTKEY_STORE_HTTPS 129 | 130 | It is not a fallback for [`APTKEY_STORE_SKS`](#aptkey_store_sks) anymore, but will disable it and download the key from the provided URL directly. 131 | Please migrate to `ROS_REPOSITORY_KEY`, which combines [`APTKEY_STORE_HTTPS`](#aptkey_store_https) and [`HASHKEY_SKS`](#hashkey_sks) 132 | 133 | ### APTKEY_STORE_SKS 134 | 135 | Will only be used if [`APTKEY_STORE_HTTPS`](#aptkey_store_https) is not set, without a fall-back. 136 | 137 | ### BEFORE_SCRIPT 138 | 139 | Due to the new [workspace management](index.rst#workspace-management), the `BEFORE_SCRIPT` variable became ambiguous and was therefore removed. 140 | However, the new [hook system](index.rst#customize-within-the-ci-process) offers a lot of alternatives. 141 | 142 | If you did not use [`UPSTREAM_WORKSPACE`](#upstream_workspace)(other than `debian`) or [`USE_DEB=false`](#use_deb), you can just substitute `BEFORE_SCRIPT` with `AFTER_SETUP_TARGET_WORKSPACE`. This will execute your script in the same sequence as before. 143 | If you did use the upstream settings, you might need to substitute with `AFTER_SETUP_UPSTREAM_WORKSPACE` (or both). 144 | 145 | In general you can as well use any other hook that is suitable for your script. 146 | Please note that the [script environment has changed](#hook-system). 147 | 148 | ### BUILD_PKGS_WHITELIST 149 | 150 | This variable is not supported anymore. 151 | Instead, you could remove the unrelated folders (see [workspace management](index.rst#workspace-management)). 152 | 153 | ### BUILDER 154 | 155 | This variable was not used before, but it was listed as an option. 156 | If you specified it anyway, please set it to `catkin_tools` or remove it to allow for automatic selection. 157 | 158 | ### CATKIN_CONFIG 159 | 160 | This variable is not supported anymore. 161 | As an alternative you could set: 162 | * `CC` and `CFLAGS` for C compiler settings 163 | * `CXX` and `CPPFLAGS`/`CXXLAGS` for C++ compiler settings 164 | * `CMAKE_ARGS` for CMake settings 165 | 166 | If you need catkin_tools-specific settings, especially `--no-install`, you should use the [legacy](https://github.com/ros-industrial/industrial_ci/tree/legacy) version. 167 | Or even better: Add support for the install space. 168 | 169 | ### CATKIN_PARALLEL_JOBS 170 | 171 | This is not supported anymore, use `PARALLEL_BUILDS` instead (see [job control](#job-control) as well). 172 | 173 | ### CATKIN_PARALLEL_TEST_JOBS 174 | 175 | This is not supported anymore. The number of parallel test jobs is limited to 1 per default. 176 | Specify `PARALLEL_TESTS=true` to remove this limit (see [job control](#job-control) as well). 177 | 178 | ### CMAKE_ARGS 179 | 180 | This variable was introduced recently and is still supported, but its content will be passed to all workspaces. 181 | `DOWNSTREAM_CMAKE_ARGS`, `TARGET_CMAKE_ARGS` and `UPSTREAM_CMAKE_ARGS` can be used for more fine-grained control. 182 | 183 | ### DOCKER_BASE_IMAGE 184 | 185 | This variable is not needed anymore. Please specify [DOCKER_IMAGE](#docker_image) instead. 186 | 187 | ### DOCKER_BUILD_OPTS 188 | 189 | This variable is not used anymore, because support for building Docker images was removed. 190 | 191 | ### DOCKER_FILE 192 | 193 | This variable is not used anymore, because support for building Docker images was removed. 194 | 195 | ### DOCKER_IMAGE 196 | 197 | This variable is still supported, but the [workspace layout has changed](#workspace-layout). 198 | 199 | ### HASHKEY_SKS 200 | 201 | Will only be used if [`APTKEY_STORE_HTTPS`](#aptkey_store_https) is not set. 202 | Please migrate to `ROS_REPOSITORY_KEY`, which combines [`APTKEY_STORE_HTTPS`](#aptkey_store_https) and [`HASHKEY_SKS`](#hashkey_sks) 203 | 204 | ### INJECT_QEMU 205 | 206 | This option was removed. It is not needed for newer versions of `qemu-user-static` (host OS: Ubuntu cosmic or newer, Debian buster or newer). 207 | For older versions, please try 208 | ``` 209 | docker run --rm --privileged multiarch/qemu-user-static --reset --credential yes --persistent yes 210 | ``` 211 | 212 | ### NOT_TEST_INSTALL 213 | 214 | This feature was removed, please use the [legacy](https://github.com/ros-industrial/industrial_ci/tree/legacy) version. 215 | 216 | ### PKGS_DOWNSTREAM 217 | 218 | This variable is not supported anymore. 219 | Instead, you could specify `DOWNSTREAM_WORKSPACE` (see [workspace management](index.rst#workspace-management)). 220 | 221 | ### ROSINSTALL_FILENAME 222 | 223 | This variable is deprecated, and should get migrated. 224 | 225 | If you do not set `UPSTREAM_WORKSPACE=file` as well, `ROSINSTALL_FILENAME` can just be removed. 226 | Otherwise, set `UPSTREAM_WORKSPACE` to the value of `$ROSINSTALL_FILENAME` or `$ROSINSTALL_FILENAME.$ROS_DISTRO` explicitly (no auto-branching anymore). 227 | If your rosinstall file contains your target repository as well, you might want to [filter](index.rst#workspace-management) it out: 228 | `UPSTREAM_WORKSPACE=my_file_name -path_to_target_repo`. 229 | 230 | ### ROS_PARALLEL_JOBS 231 | 232 | This variable does not get processed by `industrial_ci` anymore, instead it just gets passed to the build tool. 233 | As an alternative, `PARALLEL_BUILDS` can be used (see [job control](#job-control) as well). 234 | 235 | ### ROS_PARALLEL_TEST_JOBS 236 | 237 | This is not supported anymore. The number of parallel test jobs is limited to 1 per default. 238 | Specify `PARALLEL_TESTS=true` to remove this limit (see [job control](#job-control) as well). 239 | 240 | ### ROS_REPOSITORY_PATH 241 | 242 | This variable is supported as-is. 243 | If it is set to `http://packages.ros.org/ros-shadow-fixed/ubuntu` or `http://packages.ros.org/ros-testing/ubuntu`, it can be removed completely or replaced by `ROS_REPO=testing` (default). 244 | If it is set to `http://packages.ros.org/ros/ubuntu`, it could get shortened to `ROS_REPO=ros` to make `industrial_ci` use the [official ROS Docker](https://hub.docker.com/_/ros) images, if possible. 245 | 246 | ### TARGET_PKGS 247 | 248 | This variable is not supported anymore. 249 | Instead, you could remove the unrelated folders (see [workspace management](index.rst#workspace-management)). 250 | 251 | ### UBUNTU_OS_CODE_NAME 252 | 253 | Still works, but is deprecated. Just substitute it with `OS_CODE_NAME` 254 | 255 | ### UPSTREAM_WORKSPACE 256 | 257 | `UPSTREAM_WORKSPACE=debian` is superfluous and can simply get removed. 258 | In case of `UPSTREAM_WORKSPACE=file` it can get set to the value of `$ROSINSTALL_FILENAME` (default: .travis.rosinstall) or `$ROSINSTALL_FILENAME.$ROS_DISTRO` explicitly (no auto-branching anymore). 259 | 260 | If your rosinstall file contains your target repository as well, you might want to [filter](index.rst#workspace-management) it out: 261 | `UPSTREAM_WORKSPACE=my_file_name_or_URL -path_to_target_repo`. 262 | 263 | ### USE_DEB 264 | 265 | `USE_DEB=true` is superfluous and can simply get removed. 266 | `USE_DEB=false` is the same as `UPSTREAM_WORKSPACE=file` and should [get migrated](#upstream_workspace). 267 | 268 | ### USE_MOCKUP 269 | 270 | Is not used anymore, just substitute it with `TARGET_WORKSPACE` 271 | 272 | ### VERBOSE_OUTPUT 273 | 274 | Is only implemented for `BUILDER=catkin_tools` 275 | 276 | ### VERBOSE_TESTS 277 | 278 | Is only implemented for `BUILDER=catkin_tools` 279 | -------------------------------------------------------------------------------- /industrial_ci/CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2 | Changelog for package industrial_ci 3 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 4 | 5 | 0.10.0 (2020-04-08) 6 | ------------------- 7 | * [maintenance] major refactoring 8 | * [improve] introduce PARALLEL_TESTS to disable the test jobs limit of 1 9 | * [improve] refactored folding to support different types: none, Gitlab CI, GitHub Actions, Travis CI 10 | * [capability] implemented clang-tidy check 11 | * [improve] added support for ROS_PYTHON_VERSION and ROS1 noetic 12 | * [capability] added support for ROS2 (ardent to foxy) 13 | * [improve] added support for BUILDER: catkin_tools, colcon, catkin_make, catkin_make_isolated 14 | * [improve] new chained workspace layout: upstream, target, downstream 15 | * [capability] implemented new hook system and helpers 16 | * [capability] implemented workspace helpers with vcs support 17 | * [maintenance] remove support for INJECT_QEMU 18 | * [maintenance] remove support for CATKIN_CONFIG 19 | * [maintenance] drop support for ROS hydro 20 | * [maintenance] removed ROS install tests 21 | * Contributors: Alexander Gutenkunst, Felix Messmer, Mathias Lüdtke, Mikael Arguedas 22 | 23 | 0.9.0 (2020-04-08) 24 | ------------------ 25 | * [maintenance] deprecated legacy version 26 | * [fix] updated ROS repository keys 27 | * [improve] use snapshots repository for EOL distros 28 | * Contributors: Felix Messmer, Mathias Lüdtke, Matthijs van der Burgh 29 | 30 | 0.8.0 (2019-05-22) 31 | ------------------ 32 | * [fix] ABICHECK_MERGE check, https://github.com/ros-industrial/industrial_ci/issues/258, https://github.com/ros-industrial/industrial_ci/issues/322 33 | * [capability] Introduce shellcheck 34 | * [improve] Continue supporting EOLed ROS distros (Jade, Indigo). https://github.com/ros-industrial/industrial_ci/issues/352 35 | * [improve] implemented CMAKE_ARGS (recommended over CATKIN_CONFIG) 36 | * Contributors: Isaac I.Y. Saito, Mathias Lüdtke 37 | 38 | 0.7.0 (2019-01-02) 39 | ------------------ 40 | * [capability] Add clang-format check (`#320 `_, `#340 `_) 41 | * [capability] Re-use previous local CI run `#279 `_ 42 | * [capability] Allow reuse Docker image `#341 `_ 43 | * [capability] Automatically set ROS_DISTRO from Docker image if not specified `#280 `_ 44 | * [capability] ROS melodic support `#271 `_ 45 | * [deprecation] USE_DEB, UBUNTU_OS_CODE_NAME 46 | * [fix] Run Travis CI locally `#331 `_, `#265 `_ 47 | * [maintenance] remove rosdep hack `#287 `_ 48 | * [improve] Better output text `#328 `_ 49 | * [improve] Speed up CI by skipping Docker pull `#283 `_ 50 | * Contributors: Felix Messmer, Isaac I.Y. Saito, Jonathan Hechtbauer, Mathias Lüdtke, Miguel Prada, Wolfgang Merkt 51 | 52 | 0.6.0 (2018-01-13) 53 | ------------------ 54 | * [capability] You can run industrial_ci locally on your computer using configuration in your .travis.yml `#230 `_ 55 | * [capability] Inject QEMU `#237 `_ from ipa-mdl/feature/inject-qemu 56 | * [improve] Easier to use your custom Docker image `#259 `_ 57 | * Contributors: Isaac I.Y. Saito, Mathias Lüdtke 58 | 59 | 0.5.1 (2017-12-29) 60 | ------------------ 61 | * [fix] Workaround for the regression in "docker cp" `moby/moby#34096 `_ (`#248 `_). 62 | * Gitlab CI users need to take an action. See `this post `_ 63 | * [improve] Verbose catkin test results `#251 `_ 64 | * Contributors: Mathias Lüdtke 65 | 66 | 0.5.0 (2017-12-12) 67 | ------------------ 68 | * [fix] ROS Prerelease Test by updating to the latest Docker CE `#238 `_ 69 | * [capability] ABI check based on abi-compliance-checker `#199 `_ 70 | * [capability] catkin_lint feature. `#219 `_ 71 | * [capability] implemented ROSDEP_SKIP_KEYS feature `#184 `_ 72 | * [enhance] Add support for ARM platform `#236 `_ 73 | * Many more bug fixes. 74 | * Contributors: Mathias Lüdtke, Miguel Prada, Isaac I.Y. Saito 75 | 76 | 0.4.0 (2017-06-29) 77 | ------------------ 78 | * [capability] ROS buildfarm-powered pre-release tests can now run for even the repositories that are not listed in rosdistro https://github.com/ros-industrial/industrial_ci/pull/145 79 | * [capability] support for ROS lunar 80 | * [capability] Enable support for gitlab `#120 `_ 81 | * [capability] OS selection option https://github.com/ros-industrial/industrial_ci/pull/174 82 | * [capability] Option for reusing build artifact by ccache https://github.com/ros-industrial/industrial_ci/pull/182 83 | * [capability] Allow subversion in .rosintall file https://github.com/ros-industrial/industrial_ci/pull/179 84 | * [enhance] Speed up jobs by building into install space directly https://github.com/ros-industrial/industrial_ci/pull/150 85 | * [enhance] Allow passing 'catkin config' parameters (addresses `#176 `_). https://github.com/ros-industrial/industrial_ci/pull/177 86 | * [enhance] apt/deb handling in docker image https://github.com/ros-industrial/industrial_ci/issues/164, https://github.com/ros-industrial/industrial_ci/pull/158 87 | * Contributors: Benjamin Maidel, Isaac I.Y. Saito, Iñigo Martínez, Jon Azpiazu, Mathias Lüdtke 88 | 89 | 0.3.3 (2017-02-09) 90 | ------------------ 91 | * [capability] Added a script to run industrial_ci on a local host in a Docker container. `#116 `_. 92 | * Contributors: Mathias Lüdtke 93 | 94 | 0.3.2 (2017-01-20) 95 | ------------------ 96 | * [capability] New variables: CATKIN_WORKSPACE, DEBUG_BASH, EXPECT_EXIT_CODE, AFTER_SCRIPT (see `document `_ for detail) 97 | * [capability] Choose verbose output `#94 `_ 98 | * [capability] enable/disable verbose output (`#94 `_) 99 | * [capability] Support private github repositories on kinetic (`#92 `_) 100 | * [fix, capability] Script terminates when rosdep install fails. Remove manifest.xml handling `#95 `_ 101 | * [fix][ci_main.sh] Fix to not terminate falsely. (`#84 `_) 102 | * [fix] ROS prerelease test using code in the pull request. (`#85 `_) 103 | * [fix] ROS prerelease test on Kinetic. (`#83 `_) 104 | * [fix] Kinetic testing fix (environment variables passed to docker container) (`#82 `_) 105 | * [fix] Many build/install issues https://github.com/ros-industrial/industrial_ci/pull/110, https://github.com/ros-industrial/industrial_ci/pull/109 (`#92 `_) 106 | * [doc] Split readme into quick start and detail. More beginner doc. https://github.com/ros-industrial/industrial_ci/pull/113 107 | * [maintenance] Change license to Apache 2.0 (addresses `#17 `_). 108 | * [maintenance] Major code refactoring. Generalizing function and variable names (removing mention to specific CI system) https://github.com/ros-industrial/industrial_ci/pull/108 109 | * [maintenance] Add maintainer. 110 | * Contributors: Benjamin Maidel, Isaac I.Y. Saito, Mathias Lüdtke 111 | 112 | 0.3.1 (2016-10-24) 113 | ------------------ 114 | * [fix] usermod error on docker-based ROS Prerelease (see https://github.com/ros-industrial/ros_canopen/pull/193#issuecomment-254575036). (`#81 `_) 115 | * Contributors: Mathias Lüdtke, Isaac I.Y. Saito 116 | 117 | 0.3.0 (2016-09-07) 118 | ------------------ 119 | * [fix] Catch apt error for ADDITIONAL_DEB (Fix `#78 `_). (`#79 `_) 120 | * [feat] ROS Hydro compatible (Only use catkin_test_results --verbose if it exists, `#77 `_) 121 | * [feat] Allow failure for now the jade source build (see https://github.com/ros-industrial/industrial_core/pull/144#issuecomment-223186764). 122 | * [improve] Use install space by default (addresses `#54 `_). 123 | * [maintenance] Refactoring `#67 `_ 124 | * Contributors: Dave Coleman, Robert Haschke Edward Venator, Isaac I.Y. Saito 125 | 126 | 0.2.2 (2016-05-13) 127 | ------------------ 128 | * [fix] Remove wrong duplicate prerelease test code block. `#40 `_ 129 | * [sys] Adjust to ROS Indigo's up-to-date ros.key acquision. `#42 `_ 130 | * Contributors: Isaac I.Y. Saito, Gijs van der Hoorn, Mathias Lüdtke 131 | 132 | 0.2.1 (2016-05-06) 133 | ------------------ 134 | * [feat] Add docker-based ROS prerelease test. `#35 `_ 135 | * [fix] Correct environment variable exportation to subprocesses. 136 | * [fix] Better script termination with 'set -e'. 137 | * [fix] broken link in README `#37 `_ 138 | * [fix] apt-get quiet option `#33 `_ 139 | * [sys] Extract util functions 140 | * [sys] Remove meaningless Travis jobs 141 | * [doc] Some clarifications. 142 | * [improve] More fold Travis result (wstool version and localname info) `#38 `_ 143 | * Contributors: Mathias Lüdtke, Dave Coleman, Victor Lamoine, Isaac I.Y. Saito 144 | 145 | 0.2.0 (2016-04-19) 146 | ------------------ 147 | * Adjust to catkin_tools 0.4.0 `#31 `_ 148 | * Contributors: Isaac I.Y. Saito 149 | 150 | 0.1.3 (2016-04-14) 151 | ------------------ 152 | * [fix] Temporarilly disable `rospack plugin` line (fixes `#26 `_). `#28 `_ 153 | * [fix] missing an arg for specifying the number parallel job. 154 | * Fix undeclared args for the number parallel job `#22 `_ 155 | * [doc] Clarify parallel job args. 156 | * Contributors: Isaac I.Y. Saito 157 | 158 | 0.1.2 (2016-02-08) 159 | ------------------ 160 | * [fix] Move a patch that becomes available via DEB to older ROS distro only section (`#20 `_) 161 | * [feat] Add option to not test (`#16 `_) 162 | * Contributors: Isaac I.Y. Saito, Gijs van der Hoorn 163 | 164 | 0.1.1 (2016-01-05) 165 | ------------------ 166 | * [feat] Better variable name for downstream pkgs 167 | * [doc] Many improvements including replacing "git submodule" with "git clone" 168 | * [enhance] Output enhancement and cleanup 169 | * [enhance] Turn off status line (`#4 `_) 170 | * [sys] Remove a tentative workaround for a test location issue (https://github.com/ros/ros_comm/pull/668) 171 | * Contributors: Isaac I.Y. Saito, Mathias Lüdtke 172 | 173 | 0.1.0 (2015-12-08) 174 | ------------------ 175 | * Init commit of travis config and scripts 176 | * Add license and copyright header 177 | * Contributors: Shaun Edwards, Isaac I.Y. Saito 178 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | paths-ignore: 6 | - '**.md' 7 | - '**.rst' 8 | pull_request: 9 | paths-ignore: 10 | - '**.md' 11 | - '**.rst' 12 | schedule: 13 | - cron: "0 0 * * *" # every day at midnight 14 | 15 | jobs: 16 | shellcheck: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v4 20 | - uses: docker://koalaman/shellcheck-alpine 21 | with: 22 | args: /bin/sh -c "shellcheck -x *.sh industrial_ci/scripts/*_ci industrial_ci/src/*.sh industrial_ci/src/*/*.sh" 23 | 24 | distro: 25 | strategy: 26 | fail-fast: false 27 | matrix: 28 | distro: 29 | - indigo 30 | - jade 31 | - kinetic 32 | - lunar 33 | - melodic 34 | - noetic 35 | - ardent 36 | - bouncy 37 | - crystal 38 | - dashing 39 | - eloquent 40 | - foxy 41 | - galactic 42 | - humble 43 | - iron 44 | - jazzy 45 | - kilted 46 | include: 47 | - distro: rolling 48 | ubuntu: jammy 49 | - distro: rolling 50 | ubuntu: 51 | runs-on: ubuntu-latest 52 | steps: 53 | - uses: actions/checkout@v4 54 | - name: ardent does not support conditions in package.xml 55 | run: | 56 | echo "BEFORE_BUILD_TARGET_WORKSPACE=sed -i /condition/d /root/target_ws/src/industrial_ci/industrial_ci/package.xml" >> "$GITHUB_ENV" 57 | if: matrix.distro == 'ardent' 58 | - name: set OS_CODE_NAME 59 | run: | 60 | echo "OS_CODE_NAME=${{ matrix.ubuntu }}" >> "$GITHUB_ENV" 61 | if: ${{ matrix.ubuntu }} 62 | - uses: './' 63 | env: 64 | ROS_DISTRO: ${{ matrix.distro }} 65 | 66 | prerelease: 67 | strategy: 68 | fail-fast: false 69 | matrix: 70 | ROS_DISTRO: [humble, jazzy, kilted] 71 | runs-on: ubuntu-latest 72 | steps: 73 | - uses: actions/checkout@v4 74 | - name: ros industrial-ci 75 | uses: './' 76 | env: 77 | PRERELEASE: true 78 | ROS_DISTRO: ${{ matrix.ROS_DISTRO }} 79 | ici: 80 | env: 81 | TRACE: true 82 | strategy: 83 | fail-fast: false 84 | matrix: 85 | include: 86 | - {ROS_DISTRO: melodic, TARGET_WORKSPACE: 'industrial_ci/mockups/industrial_ci_testpkg', VERBOSE_OUTPUT: true, CATKIN_LINT: true, AFTER_SCRIPT: '[ "$$(command -v catkin_lint)" = /usr/local/bin/catkin_lint ]'} 87 | - {ROS_DISTRO: melodic, TARGET_WORKSPACE: 'industrial_ci/mockups/industrial_ci_testpkg', CATKIN_LINT: true, ADDITIONAL_DEBS: 'python-catkin-lint', AFTER_SCRIPT: '[ "$$(command -v catkin_lint)" = /usr/bin/catkin_lint ]'} 88 | - {ROS_DISTRO: melodic, TARGET_WORKSPACE: 'industrial_ci/mockups/industrial_ci_testpkg', CMAKE_ARGS: '-DFAIL_CMAKE=true', EXPECT_EXIT_CODE: 1} 89 | - {ROS_DISTRO: melodic, TARGET_WORKSPACE: 'industrial_ci/mockups/industrial_ci_testpkg', CATKIN_LINT: pedantic, EXPECT_EXIT_CODE: 1} 90 | - {ROS_DISTRO: melodic, TARGET_WORKSPACE: 'industrial_ci/mockups/industrial_ci_testpkg', ROSDEP_SKIP_KEYS: "rospy_tutorials rostest", EXPECT_EXIT_CODE: 1} 91 | - {ROS_DISTRO: melodic, TARGET_WORKSPACE: 'industrial_ci/mockups/testpkg_broken_install', EXPECT_EXIT_CODE: 1} 92 | - {ROS_DISTRO: melodic, UPSTREAM_WORKSPACE: debian, AFTER_SCRIPT: 'ccache 2> /dev/null && exit 1; [ "$$?" = "127" ]'} 93 | # Using default file name for ROSINSTALL_FILENAME, test CCACHE, verify cache was filled 94 | - {ROS_DISTRO: kinetic, UPSTREAM_WORKSPACE: file, CCACHE_DIR: '/github/home/.ccache', AFTER_SCRIPT: 'num=($$(ccache -s | grep "files in cache")) && (( num[-1] > 0 ))'} 95 | - {ROS_DISTRO: indigo, UPSTREAM_WORKSPACE: file, USE_DEB: true, EXPECT_EXIT_CODE: 1} # Expected to fail. See https://github.com/ros-industrial/industrial_ci/pull/74 96 | - {ROS_DISTRO: kinetic, UPSTREAM_WORKSPACE: 'https://raw.githubusercontent.com/ros-industrial/industrial_ci/master/.travis.rosinstall'} 97 | - {ROS_DISTRO: kinetic, ADDITIONAL_DEBS: 'ros-melodic-opencv3', DEBUG_BASH: true, EXPECT_EXIT_CODE: 100} # This should fail (trying from a wrong distro). 98 | - {ROS_DISTRO: kinetic, UPSTREAM_WORKSPACE: file, ROSINSTALL_FILENAME: .ci.rosinstall} # Testing arbitrary file name without ROS_DISTRO suffix. As of 6/3/2016 this fails due to https://github.com/ros-industrial/industrial_core/pull/144#issuecomment-223186764 99 | - {ROS_DISTRO: kinetic, UPSTREAM_WORKSPACE: file, ROSINSTALL_FILENAME: .i.do.not.exist, EXPECT_EXIT_CODE: 1} 100 | - {ROS_DISTRO: noetic, AFTER_SCRIPT: 'grep -q ID=ubuntu /etc/os-release && grep -q VERSION_CODENAME=focal /etc/os-release'} 101 | - {ROS_DISTRO: noetic, BEFORE_INIT: 'grep -q ID=debian /etc/os-release && grep -q VERSION_ID=\"10\" /etc/os-release', EXPECT_EXIT_CODE: 1} 102 | - {ROS_DISTRO: noetic, OS_NAME: debian, OS_CODE_NAME: buster, AFTER_SCRIPT: 'grep -q ID=debian /etc/os-release && grep -q VERSION_ID=\"10\" /etc/os-release'} 103 | - {ROS_DISTRO: noetic, OS_NAME: debian, EXPECT_EXIT_CODE: 1} 104 | - {ROS_DISTRO: noetic, OS_NAME: debian, OS_CODE_NAME: focal, EXPECT_EXIT_CODE: 1} 105 | - {ROS_DISTRO: melodic, ROS_REPO: ros, BUILDER: colcon, AFTER_SCRIPT: 'rosenv && [ "$$CMAKE_PREFIX_PATH" = "/root/target_ws/install/industrial_ci:/opt/ros/melodic" ]'} 106 | - {DOCKER_IMAGE: "ros:humble", AFTER_INIT: "grep -r ros2-testing /etc/apt && ici_exit 1 || ici_exit 2", EXPECT_EXIT_CODE: 2} 107 | - {DOCKER_IMAGE: "ros:humble", ROS_REPO: testing, AFTER_INIT: "grep -r ros2-testing /etc/apt && ici_exit 1 || ici_exit 2", EXPECT_EXIT_CODE: 1} 108 | - {DOCKER_IMAGE: 'ros:noetic', ROS_REPO: ros, NOT_TEST_BUILD: true, DEBUG_BASH: true, VERBOSE_OUTPUT: false, DOCKER_COMMIT: img_temp, POST_PROCESS: 'eval docker image inspect $$DOCKER_COMMIT --format="$$DOCKER_COMMIT:\ \"{{.Size}}\" bytes"'} 109 | - {ROS_DISTRO: noetic, AFTER_SCRIPT: 'rosenv rosrun industrial_ci run_travis', ADDITIONAL_DEBS: "ros-noetic-rosbash"} 110 | - {ROS_DISTRO: foxy, AFTER_SCRIPT: 'rosenv ros2 run industrial_ci run_travis', ADDITIONAL_DEBS: "ros-foxy-ros2run"} 111 | 112 | # Are CXXFLAGS correctly passed? These tests should fail due to -Werror (exit code is for catkin tools: 1 and for colcon: 2) 113 | - {ROS_DISTRO: melodic, CXXFLAGS: "-Werror", EXPECT_EXIT_CODE: 1, TARGET_WORKSPACE: 'industrial_ci/mockups/industrial_ci_testpkg'} 114 | - {ROS_DISTRO: noetic, CXXFLAGS: "-Werror", EXPECT_EXIT_CODE: 1, TARGET_WORKSPACE: 'industrial_ci/mockups/industrial_ci_testpkg'} 115 | - {ROS_DISTRO: melodic, CMAKE_ARGS: -DCMAKE_CXX_FLAGS="-Werror", EXPECT_EXIT_CODE: 1, TARGET_WORKSPACE: 'industrial_ci/mockups/industrial_ci_testpkg'} 116 | - {ROS_DISTRO: noetic, CMAKE_ARGS: -DCMAKE_CXX_FLAGS="-Werror", EXPECT_EXIT_CODE: 1, TARGET_WORKSPACE: 'industrial_ci/mockups/industrial_ci_testpkg'} 117 | - {ROS_DISTRO: noetic, BUILDER: colcon, CMAKE_ARGS: -DCMAKE_CXX_FLAGS="-Werror", EXPECT_EXIT_CODE: 2, TARGET_WORKSPACE: 'industrial_ci/mockups/industrial_ci_testpkg'} 118 | 119 | - {ROS_DISTRO: melodic, ROS_REPO: main} 120 | 121 | - {ROS_DISTRO: noetic, TEST: debians, TARGET_WORKSPACE: ". industrial_ci/mockups/industrial_ci_testpkg"} 122 | 123 | # Format tests 124 | - {ROS_DISTRO: indigo, TARGET_WORKSPACE: 'industrial_ci/mockups/format_tests/cpp/LLVM', CLANG_FORMAT_CHECK: 'LLVM', CLANG_FORMAT_VERSION: 3.8} 125 | - {ROS_DISTRO: kinetic, TARGET_WORKSPACE: 'industrial_ci/mockups/format_tests/cpp/LLVM', CLANG_FORMAT_CHECK: 'LLVM'} 126 | - {ROS_DISTRO: kinetic, TARGET_WORKSPACE: 'industrial_ci/mockups/format_tests/cpp/WebKit', CLANG_FORMAT_CHECK: 'LLVM', EXPECT_EXIT_CODE: 1} 127 | - {ROS_DISTRO: kinetic, TARGET_WORKSPACE: 'industrial_ci/mockups/format_tests/cpp/WebKit', CLANG_FORMAT_CHECK: 'file'} 128 | - {ROS_DISTRO: kinetic, TARGET_WORKSPACE: 'industrial_ci/mockups/format_tests/cpp/LLVM', CLANG_FORMAT_CHECK: 'WebKit', EXPECT_EXIT_CODE: 1} 129 | 130 | # Tidy 131 | - {ROS_DISTRO: noetic, TARGET_WORKSPACE: 'industrial_ci/mockups/test_clang_tidy', CLANG_TIDY: true} 132 | - {ROS_DISTRO: melodic, TARGET_WORKSPACE: 'industrial_ci/mockups/test_clang_tidy', CLANG_TIDY: pedantic, EXPECT_EXIT_CODE: 1} 133 | - {ROS_DISTRO: melodic, TARGET_WORKSPACE: 'industrial_ci/mockups/test_clang_tidy', CLANG_TIDY: pedantic, CLANG_TIDY_ARGS: "-checks=-*,modernize-use-nullptr", EXPECT_EXIT_CODE: 1} 134 | 135 | - {ROS_DISTRO: noetic, PYLINT_ARGS: "--errors-only", PYLINT_EXCLUDE: "sample_talker.py", PYLINT_CHECK: "true"} 136 | runs-on: ubuntu-latest 137 | steps: 138 | - uses: actions/checkout@v4 139 | - uses: './' 140 | with: 141 | config: ${{toJSON(matrix)}} 142 | 143 | outputs: 144 | strategy: 145 | fail-fast: false 146 | matrix: 147 | include: 148 | - {ROS_DISTRO: melodic, TARGET_WORKSPACE: 'industrial_ci/mockups/test_clang_tidy', CLANG_TIDY: pedantic, EXPECT_EXIT_CODE: 1} 149 | 150 | runs-on: ubuntu-latest 151 | steps: 152 | - uses: actions/checkout@v4 153 | - uses: './' 154 | id: ici 155 | with: 156 | config: ${{toJSON(matrix)}} 157 | - name: Check output 158 | run: | 159 | test "${{ steps.ici.outputs.target_test_results}}" = "0" || exit 1 160 | test "${{ steps.ici.outputs.clang_tidy_checks}}" = "1" || exit 1 161 | 162 | abicheck: 163 | strategy: 164 | fail-fast: false 165 | matrix: 166 | include: 167 | - repo: 'ros/actionlib' 168 | ref: '38ce66e2ae2ec9c19cf12ab22d57a8134a9285be' 169 | depth: 0 # All history will be cloned 170 | env: {ROS_DISTRO: kinetic, ROS_REPO: ros, ABICHECK_URL: url, ABICHECK_MERGE: true} # actual URL will not be used in the case 171 | 172 | - repo: 'ros-industrial/ros_canopen' 173 | ref: '0.7.5' 174 | env: {ROS_DISTRO: kinetic, ROS_REPO: ros, ABICHECK_URL: 'github:ros-industrial/ros_canopen#0.7.1', ABICHECK_MERGE: false, EXPECT_EXIT_CODE: 1} 175 | 176 | - repo: 'ros-industrial/ros_canopen' 177 | ref: '0.7.6' 178 | env: {ROS_DISTRO: kinetic, ABICHECK_URL: 'github:ros-industrial/ros_canopen#0.7.5', ABICHECK_MERGE: false} 179 | 180 | runs-on: ubuntu-latest 181 | steps: 182 | - name: Checkout external repository 183 | uses: actions/checkout@v4 184 | with: 185 | repository: ${{matrix.repo}} 186 | ref: ${{matrix.ref}} 187 | fetch-depth: ${{matrix.depth}} 188 | 189 | - uses: actions/checkout@v4 190 | with: 191 | path: .industrial_ci 192 | 193 | - uses: './.industrial_ci/' 194 | env: ${{matrix.env}} 195 | 196 | isolated: 197 | env: 198 | ISOLATION: shell 199 | strategy: 200 | fail-fast: false 201 | matrix: 202 | env: 203 | - {ROS_DISTRO: humble, UBUNTU: 22.04} 204 | - {ROS_DISTRO: humble, UBUNTU: 22.04, TEST: debians} 205 | - {ROS_DISTRO: humble, PRERELEASE: true, UBUNTU: 22.04, TARGET_WORKSPACE: ". github:ros-controls/control_msgs#galactic-devel"} 206 | - {ROS_DISTRO: jazzy, UBUNTU: 24.04} 207 | - {ROS_DISTRO: jazzy, UBUNTU: 24.04, TEST: debians} 208 | - {ROS_DISTRO: jazzy, PRERELEASE: true, UBUNTU: 24.04, TARGET_WORKSPACE: ". github:ros-controls/control_msgs#galactic-devel"} 209 | - {ROS_DISTRO: kilted, UBUNTU: 24.04} 210 | - {ROS_DISTRO: kilted, UBUNTU: 24.04, TEST: debians} 211 | - {ROS_DISTRO: kilted, PRERELEASE: true, UBUNTU: 24.04, TARGET_WORKSPACE: ". github:ros-controls/control_msgs#master"} 212 | runs-on: ubuntu-${{matrix.env.UBUNTU}} 213 | steps: 214 | - uses: actions/checkout@v4 215 | - uses: './' 216 | env: ${{matrix.env}} 217 | 218 | builders: 219 | runs-on: ubuntu-latest 220 | steps: 221 | - uses: actions/checkout@v4 222 | - run: | 223 | for BUILDER in $(ls industrial_ci/src/builders/*.sh); do 224 | echo "##[group]BUILDER=$BUILDER" 225 | .github/action.sh _FOLDING_TYPE=none DOCKER_IMAGE=ros:noetic BUILDER="$BUILDER" TARGET_WORKSPACE=industrial_ci/mockups/industrial_ci_testpkg 226 | echo "##[endgroup]" 227 | done 228 | 229 | test_arm: 230 | runs-on: ubuntu-latest 231 | steps: 232 | - uses: actions/checkout@v4 233 | - uses: docker/setup-qemu-action@v3 234 | - uses: './' 235 | env: 236 | DOCKER_IMAGE: 'arm32v7/ros:melodic-ros-core' 237 | BEFORE_INIT: '[[ $(uname -p) == armv7l ]] && exit 42' 238 | EXPECT_EXIT_CODE: 42 239 | DOCKER_DEFAULT_PLATFORM: 'linux/arm/v7' 240 | 241 | run_travis: 242 | runs-on: ubuntu-latest 243 | steps: 244 | - uses: actions/checkout@v4 245 | - run: | 246 | sudo apt install -y python3-yaml 247 | industrial_ci/scripts/run_travis 248 | industrial_ci/scripts/run_travis 1 249 | -------------------------------------------------------------------------------- /industrial_ci/src/util.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Originally developed in JSK travis package https://github.com/jsk-ros-pkg/jsk_travis 4 | 5 | # Copyright (c) 2016, Isaac I. Y. Saito 6 | # All rights reserved. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | 20 | ## util.sh 21 | ## This is a script where the functions commonly used within the industrial_ci repo are defined. 22 | 23 | ANSI_RED=31 24 | ANSI_GREEN=32 25 | ANSI_YELLOW=33 26 | ANSI_BLUE=34 27 | ANSI_MAGENTA=35 28 | ANSI_BOLD=1 29 | 30 | export _FOLDING_TYPE=${_FOLDING_TYPE:-none} 31 | export TRACE=${TRACE:-false} 32 | export ICI_FOLD_NAME=${ICI_FOLD_NAME:-} 33 | export ICI_START_TIME=${ICI_START_TIME:-} 34 | export ICI_TIME_ID=${ICI_TIME_ID:-} 35 | 36 | __ici_log_fd=1 37 | __ici_err_fd=2 38 | __ici_top_level=0 39 | 40 | function ici_setup { 41 | trap 'ici_trap_exit' EXIT # install industrial_ci exit handler 42 | exec {__ici_log_fd}>&1 43 | exec {__ici_err_fd}>&2 44 | __ici_top_level=$BASH_SUBSHELL 45 | } 46 | 47 | function ici_redirect { 48 | 1>&"$__ici_log_fd" 2>&"$__ici_err_fd" "$@" 49 | } 50 | 51 | function ici_log { 52 | ici_redirect echo "$@" 53 | } 54 | 55 | function ici_color_output { 56 | local c=$1 57 | shift 58 | ici_log -e "\e[${c}m$*\e[0m" 59 | } 60 | 61 | function ici_ansi_cleared_line { 62 | ici_log -en "$*\r\e[0K" 63 | } 64 | 65 | function ici_backtrace { 66 | if [ "$TRACE" = true ]; then 67 | ici_log 68 | ici_color_output ${ANSI_MAGENTA} "TRACE:${BASH_SOURCE[2]#$ICI_SRC_PATH/}:${BASH_LINENO[1]} ${FUNCNAME[1]} $*" 69 | for ((i=3;i<${#BASH_SOURCE[@]};i++)); do 70 | ici_color_output ${ANSI_MAGENTA} " AT:${BASH_SOURCE[$i]#$ICI_SRC_PATH/}:${BASH_LINENO[$((i-1))]} ${FUNCNAME[$((i-1))]}" 71 | done 72 | fi 73 | } 74 | 75 | function ici_trace { 76 | if [ "$TRACE" = true ]; then 77 | ici_log 78 | ici_color_output ${ANSI_MAGENTA} "TRACE:${BASH_SOURCE[2]#$ICI_SRC_PATH/}:${BASH_LINENO[1]} ${FUNCNAME[1]} $*" 79 | fi 80 | } 81 | 82 | function ici_set_u { 83 | [[ "${BASH_VERSINFO[0]}_${BASH_VERSINFO[1]}" < "4_4" ]] || set -u 84 | } 85 | 86 | function ici_with_unset_variables { 87 | local err=0 88 | set +u 89 | "$@" || err=$? 90 | ici_set_u 91 | return "$err" 92 | } 93 | 94 | function _sub_shell() ( 95 | # shellcheck disable=SC2317,SC2329 96 | function rosenv() { 97 | # if current_ws not set, use an invalid path to skip it 98 | for e in $(ici_extend_space "${current_ws:-/dev/null}") $(ici_extend_space "$BASEDIR/${PREFIX}downstream_ws") $(ici_extend_space "$BASEDIR/${PREFIX}target_ws") $(ici_extend_space "$BASEDIR/${PREFIX}base_ws") $(ici_extend_space "$BASEDIR/${PREFIX}upstream_ws") "$UNDERLAY"; do 99 | if [ -f "$e/setup.bash" ]; then 100 | ici_source_setup "$e" 101 | if [ -n "$*" ]; then 102 | (exec "$@") || return 103 | fi 104 | return 0 105 | fi 106 | done 107 | return 1 108 | } 109 | eval "$*" || ici_exit 110 | ) 111 | 112 | function _label_hook() { 113 | ici_log 114 | # shellcheck disable=SC2001 115 | ici_color_output ${ANSI_BOLD} "$(sed -e 's/^/$ /' <<< "$1")" 116 | } 117 | 118 | function ici_hook() { 119 | ici_trace "$@" 120 | local name=${1^^} 121 | name=${name//[^A-Z0-9_]/_} 122 | local name_embed="${name}_EMBED" 123 | 124 | local script=${!name:-} 125 | local script_embed=${!name_embed:-} 126 | 127 | if [ -n "$script" ] || [ -n "$script_embed" ] ; then 128 | ici_time_start "$1" 129 | 130 | if [ -n "$script" ]; then 131 | _label_hook "( $script; )" 132 | _sub_shell "$script" || ici_exit 133 | fi 134 | 135 | if [ -n "$script_embed" ]; then 136 | _label_hook "eval \"$script_embed\"" 137 | eval "$script_embed" || ici_exit 138 | ici_set_u 139 | fi 140 | 141 | ici_time_end 142 | fi 143 | } 144 | 145 | ####################################### 146 | # Starts a timer section in a folding section 147 | # based on https://github.com/travis-ci/travis-build/blob/master/lib/travis/build/bash/travis_time_start.bash 148 | # and https://github.com/travis-ci/travis-build/blob/master/lib/travis/build/bash/travis_fold.bash 149 | # 150 | # Globals: 151 | # DEBUG_BASH (read-only) 152 | # ICI_FOLD_NAME (write-only) 153 | # ICI_TIME_ID (write-only) 154 | # ICI_START_TIME (write-only) 155 | # Arguments: 156 | # color_wrap (default: 32): Color code for the section delimitter text. 157 | # exit_code (default: $?): Exit code for display 158 | # Returns: 159 | # (None) 160 | ####################################### 161 | 162 | function ici_time_start { 163 | ici_hook "before_${1}" || ici_exit 164 | if [ "$DEBUG_BASH" ] && [ "$DEBUG_BASH" == true ]; then set +x; fi 165 | ICI_START_TIME=$(date -u +%s%N) 166 | ICI_TIME_ID="$(printf %08x $((RANDOM * RANDOM)))" 167 | ICI_FOLD_NAME=$1 168 | 169 | ici_log # blank line 170 | 171 | ici_start_fold "$ICI_TIME_ID" "$ICI_FOLD_NAME" "$ICI_START_TIME" 172 | ici_color_output $ANSI_BLUE "$ICI_FOLD_NAME" 173 | if [ "$DEBUG_BASH" ] && [ "$DEBUG_BASH" == true ]; then set -x; fi 174 | } 175 | 176 | ####################################### 177 | # Wraps up the timer section that was started by ici_time_start function 178 | # based on https://github.com/travis-ci/travis-build/blob/master/lib/travis/build/bash/travis_time_finish.bash 179 | # 180 | # Globals: 181 | # DEBUG_BASH (read-only) 182 | # ICI_FOLD_NAME (from ici_time_start, read-write) 183 | # ICI_TIME_ID (from ici_time_start, read-only) 184 | # ICI_START_TIME (from ici_time_start, read-only) 185 | # Arguments: 186 | # color_wrap (default: 32): Color code for the section delimitter text. 187 | # exit_code (default: $?): Exit code for display 188 | # Returns: 189 | # (None) 190 | ####################################### 191 | function ici_time_end { 192 | if [ "$DEBUG_BASH" ] && [ "$DEBUG_BASH" == true ]; then set +x; fi 193 | local color_wrap=${1:-${ANSI_GREEN}} 194 | local exit_code=${2:-$?} 195 | local name=$ICI_FOLD_NAME 196 | 197 | if [ -z "$ICI_START_TIME" ]; then ici_warn "[ici_time_end] var ICI_START_TIME is not set. You need to call ici_time_start in advance. Returning."; return; fi 198 | local end_time; end_time=$(date -u +%s%N) 199 | local elapsed_seconds; elapsed_seconds=$(( (end_time - ICI_START_TIME)/1000000000 )) 200 | 201 | ici_log -en "\e[${color_wrap}m" # just set color, no output 202 | ici_end_fold "$ICI_TIME_ID" "$name" "$ICI_START_TIME" "$end_time" 203 | ici_color_output "$color_wrap" "'$name' returned with code '${exit_code}' after $(( elapsed_seconds / 60 )) min $(( elapsed_seconds % 60 )) sec" 204 | ici_report_result "$ICI_FOLD_NAME" "${exit_code}" 205 | 206 | ICI_FOLD_NAME= 207 | if [ "$DEBUG_BASH" ] && [ "$DEBUG_BASH" == true ]; then set -x; fi 208 | ici_hook "after_${name}" || ici_exit 209 | } 210 | 211 | function ici_step { 212 | local name=$1; shift 213 | ici_time_start "$name" 214 | "$@" || ici_exit 215 | ici_time_end 216 | } 217 | 218 | function ici_teardown { 219 | if [ "$BASH_SUBSHELL" -le "$__ici_top_level" ]; then 220 | local exit_code=$1 221 | trap - EXIT # Reset signal handler since the shell is about to exit. 222 | 223 | local cleanup=() 224 | # shellcheck disable=SC2016 225 | IFS=: command eval 'cleanup=(${_CLEANUP})' 226 | for c in "${cleanup[@]}"; do 227 | ici_warn Cleaning up "${c/#\~/$HOME}" 228 | rm -rf "${c/#\~/$HOME}" 229 | done 230 | 231 | # end fold if needed 232 | if [ -n "$ICI_FOLD_NAME" ]; then 233 | local color_wrap=${ANSI_GREEN} 234 | if [ "$exit_code" -ne "0" ]; then color_wrap=${ANSI_RED}; fi # Red color for errors 235 | ici_time_end "$color_wrap" "$exit_code" 236 | elif [ -n "${ICI_RESULT_NAME:-}" ]; then 237 | ici_report_result "$ICI_RESULT_NAME" "${exit_code}" 238 | fi 239 | 240 | exec {__ici_log_fd}>&- 241 | exec {__ici_err_fd}>&- 242 | fi 243 | } 244 | 245 | function ici_trap_exit { 246 | local exit_code=${1:-$?} 247 | 248 | ici_warn "industrial_ci terminated unexpectedly with exit code '$exit_code'" 249 | TRACE=true ici_backtrace "$@" 250 | exit_code=143 251 | ici_teardown "$exit_code" 252 | exit "$exit_code" 253 | } 254 | 255 | ####################################### 256 | # exit function with handling for EXPECT_EXIT_CODE, ends the current fold if necessary 257 | # 258 | # Globals: 259 | # EXPECT_EXIT_CODE (read-only) 260 | # ICI_FOLD_NAME (from ici_time_start, read-only) 261 | # Arguments: 262 | # exit_code (default: $?) 263 | # Returns: 264 | # (None) 265 | ####################################### 266 | function ici_exit { 267 | local exit_code=${1:-$?} 268 | ici_backtrace "$@" 269 | 270 | ici_teardown "$exit_code" 271 | 272 | if [ "$exit_code" == "$EXPECT_EXIT_CODE" ] ; then 273 | exit_code=0 274 | elif [ "$exit_code" == "0" ]; then # 0 was not expected 275 | exit_code=1 276 | fi 277 | 278 | exit "$exit_code" 279 | } 280 | 281 | function ici_warn { 282 | ici_color_output ${ANSI_YELLOW} "$*" 283 | } 284 | 285 | function ici_mark_deprecated { 286 | local e=$1 287 | shift 288 | if [ "${!e:-}" ]; then 289 | ici_warn "'$e' is deprecated. $*" 290 | fi 291 | } 292 | 293 | ####################################### 294 | # Print an error message and calls "exit" 295 | # 296 | # * Wraps the section that is started by ici_time_start function with the echo color red (${ANSI_RED}). 297 | # * exit_code is taken from second argument or from the previous comman. 298 | # * If the final exit_code is 0, this function will exit 1 instead to enforce a test failure 299 | # 300 | # Globals: 301 | # (None) 302 | # Arguments: 303 | # message (optional) 304 | # exit_code (default: $?) 305 | # Returns: 306 | # (None) 307 | ####################################### 308 | function ici_error { 309 | local exit_code=${2:-$?} # 310 | if [ -n "$1" ]; then 311 | __ici_log_fd=$__ici_err_fd ici_color_output ${ANSI_RED} "$1" 312 | fi 313 | if [ "$exit_code" == "0" ]; then # 0 is not error 314 | exit_code=1 315 | fi 316 | ici_exit "$exit_code" 317 | } 318 | 319 | function ici_enforce_deprecated { 320 | local e=$1 321 | shift 322 | if [ "${!e:-}" ]; then 323 | ici_error "'$e' is not used anymore. $*" 324 | fi 325 | } 326 | 327 | function ici_rename_deprecated() { 328 | local old=$1 329 | shift 330 | local new=$1 331 | shift 332 | if [ "${!old:-}" ]; then 333 | local value=${!old} 334 | ici_warn "'$old' is deprecated. Use '$new=$value' instead" 335 | export "$new"="$value" 336 | fi 337 | } 338 | 339 | function ici_migrate_hook() { 340 | local oldname=${1^^} 341 | oldname=${oldname//[^A-Z0-9_]/_} 342 | local newname=${2^^} 343 | newname=${newname//[^A-Z0-9_]/_} 344 | 345 | mapfile -t envs < <(env | grep -oE "(BEFORE_|AFTER_)+$oldname(_EMBED)?") 346 | 347 | for oldhook in "${envs[@]}"; do 348 | local newhook=${oldhook/$oldname/$newname} 349 | ici_warn "hook '$oldhook' was renamed to '$newhook'." 350 | eval "export $newhook=\$$oldhook" 351 | done 352 | } 353 | 354 | function ici_removed_hook() { 355 | local oldname=${1^^} 356 | shift 357 | oldname=${oldname//[^A-Z0-9_]/_} 358 | 359 | mapfile -t envs < <(env | grep -oE "(BEFORE_|AFTER_)+$oldname(_EMBED)?") 360 | 361 | for oldhook in "${envs[@]}"; do 362 | ici_enforce_deprecated "$oldhook" "$@" 363 | done 364 | } 365 | 366 | function ici_retry { 367 | ici_trace "$@" 368 | local tries=$1; shift 369 | local ret=0 370 | 371 | for ((i=1;i<=tries;i++)); do 372 | "$@" && return 0 373 | ret=$? 374 | sleep 1; 375 | done 376 | 377 | ici_color_output ${ANSI_RED} "'$*' failed $tries times" 378 | return "$ret" 379 | } 380 | 381 | function ici_get_log_cmd { 382 | local post="" 383 | while true; do 384 | case "$1" in 385 | ici_asroot) 386 | echo -n "sudo " 387 | ;; 388 | ici_exec_in_workspace) 389 | echo -n "( source $2/setup.bash && " 390 | if [ "$3" != '.' ]; then 391 | echo -n "cd $3 && " 392 | fi 393 | shift 2 394 | post="$post; )" 395 | ;; 396 | ici_filter) 397 | post=" | grep -E '$2' " 398 | shift 1 399 | ;; 400 | ici_quiet) 401 | post=" > /dev/null " 402 | ;; 403 | ici_cmd|ici_guard|ici_label) 404 | ;; 405 | *) 406 | echo "$*$post" 407 | return 408 | esac 409 | shift 410 | done 411 | } 412 | 413 | function ici_quiet { 414 | local out; out=$(mktemp) 415 | local err=0 416 | "$@" &> "$out" || err=$? 417 | if [ "$err" -ne 0 ]; then 418 | ici_redirect cat "$out" 419 | rm -rf "$out" 420 | fi 421 | rm -rf "$out" 422 | return "$err" 423 | } 424 | 425 | function ici_filter { 426 | local filter=$1; shift 427 | local out; out=$(mktemp) 428 | "$@" | grep -E "$filter" | ici_redirect cat || true 429 | local err=${PIPESTATUS[0]} 430 | if [ "$err" -ne 0 ]; then 431 | ici_redirect cat "$out" 432 | fi 433 | rm -rf "$out" 434 | return "$err" 435 | } 436 | 437 | 438 | function _ici_guard { 439 | local err=0 440 | "$@" || err=$? 441 | if [ "$err" -ne 0 ]; then 442 | ici_error "'$(ici_get_log_cmd "$@")' returned with $err" "$err" 443 | fi 444 | } 445 | 446 | function ici_guard { 447 | ici_trace "$@" 448 | _ici_guard "$@" 449 | } 450 | 451 | function ici_label { 452 | local cmd; cmd=$(ici_get_log_cmd "$@") 453 | ici_log 454 | ici_color_output ${ANSI_BOLD} "$ $cmd" 455 | "$@" 456 | } 457 | 458 | function ici_cmd { 459 | _ici_guard ici_label "$@" 460 | } 461 | 462 | function ici_asroot { 463 | if [ "$EUID" -ne 0 ] && command -v sudo > /dev/null; then 464 | sudo "$@" 465 | else 466 | "$@" 467 | fi 468 | } 469 | 470 | function ici_exec_for_command { 471 | ici_trace "$@" 472 | local command=$1; shift 473 | if ! command -v "$command" > /dev/null; then 474 | "$@" 475 | fi 476 | } 477 | 478 | function ici_split_array { 479 | # shellcheck disable=SC2034 480 | IFS=" " read -r -a "$1" <<< "$*" 481 | } 482 | 483 | function ici_parse_env_array { 484 | # shellcheck disable=SC2034 485 | eval "$1=(${!2:-})" 486 | } 487 | 488 | function ici_parse_jobs { 489 | local -n _ici_parse_jobs_res=$1 490 | # shellcheck disable=SC2034 491 | _ici_parse_jobs_res=${!2:-} 492 | 493 | case "$_ici_parse_jobs_res" in 494 | "") 495 | _ici_parse_jobs_res="$3";; 496 | "true") 497 | _ici_parse_jobs_res="0";; 498 | "false") 499 | _ici_parse_jobs_res="1";; 500 | *) 501 | if ! [[ "$_ici_parse_jobs_res" =~ ^[0-9]+$ ]]; then 502 | ici_error "cannot parse $2=$_ici_parse_jobs_res as a number" 503 | fi 504 | ;; 505 | esac 506 | } 507 | 508 | function ici_find_nonhidden { 509 | ici_trace "$@" 510 | local path=$1; shift 511 | local args=() 512 | if [ $# -gt 0 ]; then 513 | args=(-a \( "$@" \)) 514 | fi 515 | find "$path" \( \! \( -path "${path}*/.*" -prune \) \) "${args[@]}" 516 | } 517 | 518 | function ici_resolve_component { 519 | local label=$1 520 | local group=$2 521 | for file in "${TARGET_REPO_PATH}/${!label}" "${ICI_SRC_PATH}/$group/${!label}.sh"; do 522 | if [ -f "$file" ]; then 523 | echo "$file" 524 | return 525 | fi 526 | done 527 | ici_error "$label '${!label}' not found" 528 | } 529 | 530 | function ici_source_component { 531 | local script 532 | script=$(ici_resolve_component "$@") 533 | ici_guard source "$script" 534 | } 535 | 536 | function ici_check_builder { 537 | ici_trace "$@" 538 | [ -z "$BUILDER" ] || ici_resolve_component BUILDER builders > /dev/null 539 | } 540 | 541 | function ici_source_builder { 542 | ici_source_component BUILDER builders 543 | } 544 | 545 | function ici_join_array { 546 | local sep=$1 547 | shift 548 | local res="" 549 | for elem in "$@"; do 550 | if [ -n "$elem" ]; then 551 | res+="$sep$elem" 552 | fi 553 | done 554 | echo "${res#"$sep"}" 555 | } 556 | 557 | function ici_cleanup_later { 558 | ici_trace "$@" 559 | _CLEANUP=$(ici_join_array : "$_CLEANUP" "$@") 560 | } 561 | 562 | function ici_make_temp_dir { 563 | ici_trace "$@" 564 | local -n ici_make_temp_dir_res=$1; 565 | ici_make_temp_dir_res=$(mktemp -d) 566 | ici_log "ici_make_temp_dir: $1 -> $ici_make_temp_dir_res" 567 | ici_cleanup_later "$ici_make_temp_dir_res" 568 | } 569 | 570 | ici_source_component _FOLDING_TYPE folding 571 | --------------------------------------------------------------------------------