From d8313ff42f6866b761476dfc050bde348c5322d4 Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Tue, 14 Jul 2026 11:24:32 +0000 Subject: [PATCH 01/11] Use a separate PR workflow with gates --- .../workflows/rolling-abi-compatibility.yml | 14 -- .github/workflows/rolling-binary-build.yml | 3 +- .github/workflows/rolling-check-docs.yml | 14 -- ...ling-compatibility-humble-binary-build.yml | 3 +- ...lling-compatibility-jazzy-binary-build.yml | 3 +- ...ling-compatibility-kilted-binary-build.yml | 3 +- ...ing-compatibility-lyrical-binary-build.yml | 3 +- .github/workflows/rolling-coverage-build.yml | 3 +- .github/workflows/rolling-debian-build.yml | 3 +- .github/workflows/rolling-pr-gated-ci.yml | 229 ++++++++++++++++++ .github/workflows/rolling-pre-commit.yml | 3 - .../workflows/rolling-rhel-binary-build.yml | 3 +- .../rolling-semi-binary-build-win.yml | 3 +- .../workflows/rolling-semi-binary-build.yml | 3 +- .../rolling-semi-binary-downstream-build.yml | 14 -- 15 files changed, 239 insertions(+), 65 deletions(-) create mode 100644 .github/workflows/rolling-pr-gated-ci.yml diff --git a/.github/workflows/rolling-abi-compatibility.yml b/.github/workflows/rolling-abi-compatibility.yml index d71893a679..c3a2da4a0a 100644 --- a/.github/workflows/rolling-abi-compatibility.yml +++ b/.github/workflows/rolling-abi-compatibility.yml @@ -1,20 +1,6 @@ name: Rolling - ABI Compatibility Check on: workflow_dispatch: - pull_request: - branches: - - master - paths: - - '**.hpp' - - '**.h' - - '**.cpp' - - '**.py' - - '**.yaml' - - '.github/workflows/rolling-abi-compatibility.yml' - - '**/package.xml' - - '**/CMakeLists.txt' - - 'ros2_control-not-released.rolling.repos' - - 'ros2_control-not-released.lyrical.repos' concurrency: # cancel previous runs of the same workflow, except for pushes on given branches diff --git a/.github/workflows/rolling-binary-build.yml b/.github/workflows/rolling-binary-build.yml index bdf0fd7e34..548751afe2 100644 --- a/.github/workflows/rolling-binary-build.yml +++ b/.github/workflows/rolling-binary-build.yml @@ -4,7 +4,7 @@ name: Rolling Binary Build on: workflow_dispatch: - pull_request: &event + push: branches: - master paths: @@ -18,7 +18,6 @@ on: - '**/CMakeLists.txt' - 'ros2_control-not-released.rolling.repos' - 'ros2_control-not-released.lyrical.repos' - push: *event schedule: # Run every morning to detect flakiness and broken dependencies - cron: '03 1 * * MON-FRI' diff --git a/.github/workflows/rolling-check-docs.yml b/.github/workflows/rolling-check-docs.yml index bac1a6dd86..c9ec0097dd 100644 --- a/.github/workflows/rolling-check-docs.yml +++ b/.github/workflows/rolling-check-docs.yml @@ -2,20 +2,6 @@ name: Rolling Check Docs on: workflow_dispatch: - pull_request: - branches: - - master - paths: - - '**.rst' - - '**.md' - - '**.jpg' - - '**.jpeg' - - '**.png' - - '**.svg' - - '**.yml' - - '**.yaml' - - '!.github/**' # exclude yaml files in .github directory - - '.github/workflows/rolling-check-docs.yml' concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/rolling-compatibility-humble-binary-build.yml b/.github/workflows/rolling-compatibility-humble-binary-build.yml index a5bec4e952..a19dde5afa 100644 --- a/.github/workflows/rolling-compatibility-humble-binary-build.yml +++ b/.github/workflows/rolling-compatibility-humble-binary-build.yml @@ -4,7 +4,7 @@ name: Check Rolling Compatibility on Humble on: workflow_dispatch: - pull_request: &event + push: branches: - master paths: @@ -17,7 +17,6 @@ on: - '**/package.xml' - '**/CMakeLists.txt' - 'ros2_control.rolling.repos' - push: *event concurrency: # cancel previous runs of the same workflow, except for pushes on given branches diff --git a/.github/workflows/rolling-compatibility-jazzy-binary-build.yml b/.github/workflows/rolling-compatibility-jazzy-binary-build.yml index 01d8ba423f..40c30ac32d 100644 --- a/.github/workflows/rolling-compatibility-jazzy-binary-build.yml +++ b/.github/workflows/rolling-compatibility-jazzy-binary-build.yml @@ -4,7 +4,7 @@ name: Check Rolling Compatibility on Jazzy on: workflow_dispatch: - pull_request: &event + push: branches: - master paths: @@ -17,7 +17,6 @@ on: - '**/package.xml' - '**/CMakeLists.txt' - 'ros2_control.rolling.repos' - push: *event concurrency: # cancel previous runs of the same workflow, except for pushes on given branches diff --git a/.github/workflows/rolling-compatibility-kilted-binary-build.yml b/.github/workflows/rolling-compatibility-kilted-binary-build.yml index 45097e424e..14e9be0c7f 100644 --- a/.github/workflows/rolling-compatibility-kilted-binary-build.yml +++ b/.github/workflows/rolling-compatibility-kilted-binary-build.yml @@ -4,7 +4,7 @@ name: Check Rolling Compatibility on Kilted on: workflow_dispatch: - pull_request: &event + push: branches: - master paths: @@ -17,7 +17,6 @@ on: - '**/package.xml' - '**/CMakeLists.txt' - 'ros2_control.rolling.repos' - push: *event concurrency: # cancel previous runs of the same workflow, except for pushes on given branches diff --git a/.github/workflows/rolling-compatibility-lyrical-binary-build.yml b/.github/workflows/rolling-compatibility-lyrical-binary-build.yml index 8f849cf1ba..0acd413431 100644 --- a/.github/workflows/rolling-compatibility-lyrical-binary-build.yml +++ b/.github/workflows/rolling-compatibility-lyrical-binary-build.yml @@ -4,7 +4,7 @@ name: Check Rolling Compatibility on Lyrical on: workflow_dispatch: - pull_request: &event + push: branches: - master paths: @@ -17,7 +17,6 @@ on: - '**/package.xml' - '**/CMakeLists.txt' - 'ros2_control.rolling.repos' - push: *event concurrency: # cancel previous runs of the same workflow, except for pushes on given branches diff --git a/.github/workflows/rolling-coverage-build.yml b/.github/workflows/rolling-coverage-build.yml index bef06d3622..4ecbf49047 100644 --- a/.github/workflows/rolling-coverage-build.yml +++ b/.github/workflows/rolling-coverage-build.yml @@ -1,7 +1,7 @@ name: Coverage Build - Rolling on: workflow_dispatch: - pull_request: &event + push: branches: - master paths: @@ -15,7 +15,6 @@ on: - '**/CMakeLists.txt' - 'ros2_control.rolling.repos' - 'codecov.yml' - push: *event concurrency: # cancel previous runs of the same workflow, except for pushes on given branches diff --git a/.github/workflows/rolling-debian-build.yml b/.github/workflows/rolling-debian-build.yml index d02ad72ffb..35bed4f96e 100644 --- a/.github/workflows/rolling-debian-build.yml +++ b/.github/workflows/rolling-debian-build.yml @@ -1,7 +1,7 @@ name: Rolling - Debian Semi-Binary Build on: workflow_dispatch: - pull_request: &event + push: branches: - master paths: @@ -15,7 +15,6 @@ on: - '**/CMakeLists.txt' - 'ros2_control.rolling.repos' - 'ros2_control.lyrical.repos' - push: *event concurrency: # cancel previous runs of the same workflow, except for pushes on given branches diff --git a/.github/workflows/rolling-pr-gated-ci.yml b/.github/workflows/rolling-pr-gated-ci.yml new file mode 100644 index 0000000000..c3d114e6b0 --- /dev/null +++ b/.github/workflows/rolling-pr-gated-ci.yml @@ -0,0 +1,229 @@ +name: Rolling PR Gated CI + +on: + workflow_dispatch: + pull_request: + branches: + - master + paths: + - '**.hpp' + - '**.h' + - '**.cpp' + - '**.py' + - '**.yaml' + - '**.yml' + - '**.rst' + - '**.md' + - '**.jpg' + - '**.jpeg' + - '**.png' + - '**.svg' + - '.github/workflows/rolling-pr-gated-ci.yml' + - '**/package.xml' + - '**/CMakeLists.txt' + - 'ros2_control.rolling.repos' + - 'ros2_control.lyrical.repos' + - 'ros2_control-not-released.rolling.repos' + - 'ros2_control-not-released.lyrical.repos' + - 'ros_controls.rolling.repos' + - 'ros_controls.lyrical.repos' + - 'codecov.yml' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + pre-commit: + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-pre-commit.yml@master + strategy: + fail-fast: false + matrix: + ROS_DISTRO: [lyrical, rolling] + with: + ros_distro: ${{ matrix.ROS_DISTRO }} + + detect-docs-changes: + runs-on: ubuntu-latest + outputs: + docs_changed: ${{ steps.docs_changed.outputs.docs_changed }} + steps: + - id: filter + if: ${{ github.event_name == 'pull_request' }} + uses: dorny/paths-filter@v3 + with: + filters: | + docs: + - '**.rst' + - '**.md' + - '**.jpg' + - '**.jpeg' + - '**.png' + - '**.svg' + - '**.yml' + - '**.yaml' + - '!.github/**' + - '.github/workflows/rolling-pr-gated-ci.yml' + - id: docs_changed + run: | + if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then + echo "docs_changed=true" >> "$GITHUB_OUTPUT" + else + echo "docs_changed=${{ steps.filter.outputs.docs }}" >> "$GITHUB_OUTPUT" + fi + + check-docs: + name: Check Docs + needs: [detect-docs-changes] + if: ${{ needs.detect-docs-changes.outputs.docs_changed == 'true' }} + uses: ros-controls/control.ros.org/.github/workflows/reusable-sphinx-check-single-version.yml@rolling + with: + ROS2_CONTROL_PR: ${{ github.ref }} + + check-docs-noop: + needs: [detect-docs-changes] + if: ${{ needs.detect-docs-changes.outputs.docs_changed != 'true' }} + runs-on: ubuntu-latest + steps: + - run: echo "No docs changes detected. Skipping docs build." + + docs-gate: + needs: [check-docs, check-docs-noop] + if: ${{ always() }} + runs-on: ubuntu-latest + steps: + - name: Validate docs gate + run: | + if [[ "${{ needs.check-docs.result }}" == "success" || "${{ needs.check-docs-noop.result }}" == "success" ]]; then + echo "Docs gate passed." + exit 0 + fi + echo "Docs gate failed." + exit 1 + + semi-binary: + needs: [pre-commit, docs-gate] + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master + strategy: + fail-fast: false + matrix: + ROS_DISTRO: [lyrical, rolling] + with: + ros_distro: ${{ matrix.ROS_DISTRO }} + ros_repo: testing + upstream_workspace: ros2_control.${{ matrix.ROS_DISTRO }}.repos + ref_for_scheduled_build: master + + semi-binary-clang: + needs: [pre-commit, docs-gate] + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master + strategy: + fail-fast: false + matrix: + ROS_DISTRO: [rolling] + with: + ros_distro: ${{ matrix.ROS_DISTRO }} + ros_repo: testing + upstream_workspace: ros2_control.${{ matrix.ROS_DISTRO }}.repos + ref_for_scheduled_build: master + additional_debs: clang + c_compiler: clang + cxx_compiler: clang++ + not_test_build: true + + build-downstream: + needs: [pre-commit, docs-gate] + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master + strategy: + fail-fast: false + matrix: + ROS_DISTRO: [lyrical, rolling] + with: + ros_distro: ${{ matrix.ROS_DISTRO }} + ros_repo: testing + ref_for_scheduled_build: master + upstream_workspace: ros2_control.${{ matrix.ROS_DISTRO }}.repos + not_test_build: true + downstream_workspace: ros_controls.${{ matrix.ROS_DISTRO }}.repos + not_test_downstream: false + + binary: + needs: [pre-commit, docs-gate] + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master + strategy: + fail-fast: false + matrix: + ROS_DISTRO: [lyrical, rolling] + ROS_REPO: [main, testing] + exclude: + - ROS_DISTRO: rolling + ROS_REPO: main + with: + ros_distro: ${{ matrix.ROS_DISTRO }} + ros_repo: ${{ matrix.ROS_REPO }} + upstream_workspace: ros2_control-not-released.${{ matrix.ROS_DISTRO }}.repos + ref_for_scheduled_build: master + + coverage_rolling: + needs: [pre-commit, docs-gate] + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-build-coverage.yml@master + secrets: inherit + with: + ros_distro: rolling + + compatibility-build: + needs: [pre-commit, docs-gate] + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master + strategy: + fail-fast: false + matrix: + ROS_DISTRO: [humble, jazzy, kilted, lyrical] + with: + ros_distro: ${{ matrix.ROS_DISTRO }} + ros_repo: testing + upstream_workspace: ros2_control.rolling.repos + ref_for_scheduled_build: master + + abi_check: + needs: [pre-commit, docs-gate] + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-abi-check.yml@master + strategy: + fail-fast: false + matrix: + ROS_DISTRO: [lyrical, rolling] + with: + ros_distro: ${{ matrix.ROS_DISTRO }} + + debian_semi_binary_build: + needs: [pre-commit, docs-gate] + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-debian-build.yml@master + strategy: + fail-fast: false + matrix: + ROS_DISTRO: [lyrical, rolling] + with: + ros_distro: ${{ matrix.ROS_DISTRO }} + upstream_workspace: ros2_control.${{ matrix.ROS_DISTRO }}.repos + ref_for_scheduled_build: master + skip_packages: rqt_controller_manager + + rhel_semi_binary_build: + needs: [pre-commit, docs-gate] + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-rhel-binary-build.yml@master + strategy: + fail-fast: false + matrix: + ROS_DISTRO: [lyrical, rolling] + with: + ros_distro: ${{ matrix.ROS_DISTRO }} + upstream_workspace: ros2_control.${{ matrix.ROS_DISTRO }}.repos + ref_for_scheduled_build: master + skip_packages: rqt_controller_manager + + binary-windows: + needs: [pre-commit, docs-gate] + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-ros-tooling-win-build.yml@master + with: + ros_distro: rolling + pixi_dependencies: typeguard jinja2 boost compilers cpp-expected + upstream_workspace: ros2_control.rolling.repos diff --git a/.github/workflows/rolling-pre-commit.yml b/.github/workflows/rolling-pre-commit.yml index 7b3fb229bd..3a2593040c 100644 --- a/.github/workflows/rolling-pre-commit.yml +++ b/.github/workflows/rolling-pre-commit.yml @@ -2,9 +2,6 @@ name: Pre-Commit - Rolling on: workflow_dispatch: - pull_request: - branches: - - master push: branches: - master diff --git a/.github/workflows/rolling-rhel-binary-build.yml b/.github/workflows/rolling-rhel-binary-build.yml index c16da77161..cfabde17a3 100644 --- a/.github/workflows/rolling-rhel-binary-build.yml +++ b/.github/workflows/rolling-rhel-binary-build.yml @@ -1,7 +1,7 @@ name: Rolling - RHEL Semi-Binary Build on: workflow_dispatch: - pull_request: &event + push: branches: - master paths: @@ -15,7 +15,6 @@ on: - '**/CMakeLists.txt' - 'ros2_control.rolling.repos' - 'ros2_control.lyrical.repos' - push: *event concurrency: # cancel previous runs of the same workflow, except for pushes on given branches group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/rolling-semi-binary-build-win.yml b/.github/workflows/rolling-semi-binary-build-win.yml index e196ca3b47..25555dca2c 100644 --- a/.github/workflows/rolling-semi-binary-build-win.yml +++ b/.github/workflows/rolling-semi-binary-build-win.yml @@ -4,7 +4,7 @@ name: Rolling Windows Semi-Binary Build on: workflow_dispatch: - pull_request: &event + push: branches: - master paths: @@ -17,7 +17,6 @@ on: - 'ros2_control.rolling.repos' - '**/package.xml' - '**/CMakeLists.txt' - push: *event concurrency: # cancel previous runs of the same workflow, except for pushes on given branches diff --git a/.github/workflows/rolling-semi-binary-build.yml b/.github/workflows/rolling-semi-binary-build.yml index 42cd8664c0..3e0d1e0946 100644 --- a/.github/workflows/rolling-semi-binary-build.yml +++ b/.github/workflows/rolling-semi-binary-build.yml @@ -4,7 +4,7 @@ name: Rolling Semi-Binary Build on: workflow_dispatch: - pull_request: &event + push: branches: - master paths: @@ -18,7 +18,6 @@ on: - '**/CMakeLists.txt' - 'ros2_control.rolling.repos' - 'ros2_control.lyrical.repos' - push: *event schedule: # Run every morning to detect flakiness and broken dependencies - cron: '03 1 * * MON-FRI' diff --git a/.github/workflows/rolling-semi-binary-downstream-build.yml b/.github/workflows/rolling-semi-binary-downstream-build.yml index e011356196..9edf461489 100644 --- a/.github/workflows/rolling-semi-binary-downstream-build.yml +++ b/.github/workflows/rolling-semi-binary-downstream-build.yml @@ -4,20 +4,6 @@ name: Rolling Downstream Build on: workflow_dispatch: - pull_request: - branches: - - master - paths: - - '**.hpp' - - '**.h' - - '**.cpp' - - '**.py' - - '**.yaml' - - '.github/workflows/rolling-semi-binary-downstream-build.yml' - - '**/package.xml' - - '**/CMakeLists.txt' - - 'ros_controls.rolling.repos' - - 'ros_controls.lyrical.repos' concurrency: group: ${{ github.workflow }}-${{ github.ref }} From b5ffa4f1493b742e789836a2461501607381a8df Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Tue, 14 Jul 2026 11:38:00 +0000 Subject: [PATCH 02/11] Fix gate of matrix strategy --- .github/workflows/rolling-pr-gated-ci.yml | 47 +++++++++++++++-------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/.github/workflows/rolling-pr-gated-ci.yml b/.github/workflows/rolling-pr-gated-ci.yml index c3d114e6b0..79514d06a8 100644 --- a/.github/workflows/rolling-pr-gated-ci.yml +++ b/.github/workflows/rolling-pr-gated-ci.yml @@ -34,14 +34,29 @@ concurrency: cancel-in-progress: true jobs: - pre-commit: + pre-commit-rolling: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-pre-commit.yml@master - strategy: - fail-fast: false - matrix: - ROS_DISTRO: [lyrical, rolling] with: - ros_distro: ${{ matrix.ROS_DISTRO }} + ros_distro: rolling + + pre-commit-lyrical: + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-pre-commit.yml@master + with: + ros_distro: lyrical + + pre-commit-gate: + needs: [pre-commit-rolling, pre-commit-lyrical] + if: ${{ always() }} + runs-on: ubuntu-latest + steps: + - name: Validate pre-commit gate + run: | + if [[ "${{ needs.pre-commit-rolling.result }}" == "success" && "${{ needs.pre-commit-lyrical.result }}" == "success" ]]; then + echo "Pre-commit gate passed." + exit 0 + fi + echo "Pre-commit gate failed." + exit 1 detect-docs-changes: runs-on: ubuntu-latest @@ -102,7 +117,7 @@ jobs: exit 1 semi-binary: - needs: [pre-commit, docs-gate] + needs: [pre-commit-gate, docs-gate] uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -115,7 +130,7 @@ jobs: ref_for_scheduled_build: master semi-binary-clang: - needs: [pre-commit, docs-gate] + needs: [pre-commit-gate, docs-gate] uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -132,7 +147,7 @@ jobs: not_test_build: true build-downstream: - needs: [pre-commit, docs-gate] + needs: [pre-commit-gate, docs-gate] uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -148,7 +163,7 @@ jobs: not_test_downstream: false binary: - needs: [pre-commit, docs-gate] + needs: [pre-commit-gate, docs-gate] uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -165,14 +180,14 @@ jobs: ref_for_scheduled_build: master coverage_rolling: - needs: [pre-commit, docs-gate] + needs: [pre-commit-gate, docs-gate] uses: ros-controls/ros2_control_ci/.github/workflows/reusable-build-coverage.yml@master secrets: inherit with: ros_distro: rolling compatibility-build: - needs: [pre-commit, docs-gate] + needs: [pre-commit-gate, docs-gate] uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -185,7 +200,7 @@ jobs: ref_for_scheduled_build: master abi_check: - needs: [pre-commit, docs-gate] + needs: [pre-commit-gate, docs-gate] uses: ros-controls/ros2_control_ci/.github/workflows/reusable-abi-check.yml@master strategy: fail-fast: false @@ -195,7 +210,7 @@ jobs: ros_distro: ${{ matrix.ROS_DISTRO }} debian_semi_binary_build: - needs: [pre-commit, docs-gate] + needs: [pre-commit-gate, docs-gate] uses: ros-controls/ros2_control_ci/.github/workflows/reusable-debian-build.yml@master strategy: fail-fast: false @@ -208,7 +223,7 @@ jobs: skip_packages: rqt_controller_manager rhel_semi_binary_build: - needs: [pre-commit, docs-gate] + needs: [pre-commit-gate, docs-gate] uses: ros-controls/ros2_control_ci/.github/workflows/reusable-rhel-binary-build.yml@master strategy: fail-fast: false @@ -221,7 +236,7 @@ jobs: skip_packages: rqt_controller_manager binary-windows: - needs: [pre-commit, docs-gate] + needs: [pre-commit-gate, docs-gate] uses: ros-controls/ros2_control_ci/.github/workflows/reusable-ros-tooling-win-build.yml@master with: ros_distro: rolling From dc8915f952872b3dbaf7ef97df74076a5119cfcc Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Tue, 14 Jul 2026 11:50:21 +0000 Subject: [PATCH 03/11] Use a single quality gate --- .github/workflows/rolling-pr-gated-ci.yml | 57 ++++++++++++----------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/.github/workflows/rolling-pr-gated-ci.yml b/.github/workflows/rolling-pr-gated-ci.yml index 79514d06a8..af75d46796 100644 --- a/.github/workflows/rolling-pr-gated-ci.yml +++ b/.github/workflows/rolling-pr-gated-ci.yml @@ -44,20 +44,6 @@ jobs: with: ros_distro: lyrical - pre-commit-gate: - needs: [pre-commit-rolling, pre-commit-lyrical] - if: ${{ always() }} - runs-on: ubuntu-latest - steps: - - name: Validate pre-commit gate - run: | - if [[ "${{ needs.pre-commit-rolling.result }}" == "success" && "${{ needs.pre-commit-lyrical.result }}" == "success" ]]; then - echo "Pre-commit gate passed." - exit 0 - fi - echo "Pre-commit gate failed." - exit 1 - detect-docs-changes: runs-on: ubuntu-latest outputs: @@ -102,22 +88,28 @@ jobs: steps: - run: echo "No docs changes detected. Skipping docs build." - docs-gate: - needs: [check-docs, check-docs-noop] + quality-gate: + needs: [pre-commit-rolling, pre-commit-lyrical, check-docs, check-docs-noop] if: ${{ always() }} runs-on: ubuntu-latest steps: - - name: Validate docs gate + - name: Validate quality gate run: | + if [[ "${{ needs.pre-commit-rolling.result }}" != "success" || "${{ needs.pre-commit-lyrical.result }}" != "success" ]]; then + echo "Pre-commit gate failed." + exit 1 + fi + if [[ "${{ needs.check-docs.result }}" == "success" || "${{ needs.check-docs-noop.result }}" == "success" ]]; then - echo "Docs gate passed." + echo "Quality gate passed." exit 0 fi echo "Docs gate failed." exit 1 semi-binary: - needs: [pre-commit-gate, docs-gate] + needs: [quality-gate] + if: ${{ needs.quality-gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -130,7 +122,8 @@ jobs: ref_for_scheduled_build: master semi-binary-clang: - needs: [pre-commit-gate, docs-gate] + needs: [quality-gate] + if: ${{ needs.quality-gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -147,7 +140,8 @@ jobs: not_test_build: true build-downstream: - needs: [pre-commit-gate, docs-gate] + needs: [quality-gate] + if: ${{ needs.quality-gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -163,7 +157,8 @@ jobs: not_test_downstream: false binary: - needs: [pre-commit-gate, docs-gate] + needs: [quality-gate] + if: ${{ needs.quality-gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -180,14 +175,16 @@ jobs: ref_for_scheduled_build: master coverage_rolling: - needs: [pre-commit-gate, docs-gate] + needs: [quality-gate] + if: ${{ needs.quality-gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-build-coverage.yml@master secrets: inherit with: ros_distro: rolling compatibility-build: - needs: [pre-commit-gate, docs-gate] + needs: [quality-gate] + if: ${{ needs.quality-gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -200,7 +197,8 @@ jobs: ref_for_scheduled_build: master abi_check: - needs: [pre-commit-gate, docs-gate] + needs: [quality-gate] + if: ${{ needs.quality-gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-abi-check.yml@master strategy: fail-fast: false @@ -210,7 +208,8 @@ jobs: ros_distro: ${{ matrix.ROS_DISTRO }} debian_semi_binary_build: - needs: [pre-commit-gate, docs-gate] + needs: [quality-gate] + if: ${{ needs.quality-gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-debian-build.yml@master strategy: fail-fast: false @@ -223,7 +222,8 @@ jobs: skip_packages: rqt_controller_manager rhel_semi_binary_build: - needs: [pre-commit-gate, docs-gate] + needs: [quality-gate] + if: ${{ needs.quality-gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-rhel-binary-build.yml@master strategy: fail-fast: false @@ -236,7 +236,8 @@ jobs: skip_packages: rqt_controller_manager binary-windows: - needs: [pre-commit-gate, docs-gate] + needs: [quality-gate] + if: ${{ needs.quality-gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-ros-tooling-win-build.yml@master with: ros_distro: rolling From db267844a93493cca40877957607299f1c7e61af Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Tue, 14 Jul 2026 11:59:59 +0000 Subject: [PATCH 04/11] Fix expression parsing --- .github/workflows/rolling-pr-gated-ci.yml | 66 +++++++++++------------ 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/.github/workflows/rolling-pr-gated-ci.yml b/.github/workflows/rolling-pr-gated-ci.yml index af75d46796..c1a8f63509 100644 --- a/.github/workflows/rolling-pr-gated-ci.yml +++ b/.github/workflows/rolling-pr-gated-ci.yml @@ -34,17 +34,17 @@ concurrency: cancel-in-progress: true jobs: - pre-commit-rolling: + pre_commit_rolling: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-pre-commit.yml@master with: ros_distro: rolling - pre-commit-lyrical: + pre_commit_lyrical: uses: ros-controls/ros2_control_ci/.github/workflows/reusable-pre-commit.yml@master with: ros_distro: lyrical - detect-docs-changes: + detect_docs_changes: runs-on: ubuntu-latest outputs: docs_changed: ${{ steps.docs_changed.outputs.docs_changed }} @@ -73,34 +73,34 @@ jobs: echo "docs_changed=${{ steps.filter.outputs.docs }}" >> "$GITHUB_OUTPUT" fi - check-docs: + check_docs: name: Check Docs - needs: [detect-docs-changes] - if: ${{ needs.detect-docs-changes.outputs.docs_changed == 'true' }} + needs: [detect_docs_changes] + if: ${{ needs.detect_docs_changes.outputs.docs_changed == 'true' }} uses: ros-controls/control.ros.org/.github/workflows/reusable-sphinx-check-single-version.yml@rolling with: ROS2_CONTROL_PR: ${{ github.ref }} - check-docs-noop: - needs: [detect-docs-changes] - if: ${{ needs.detect-docs-changes.outputs.docs_changed != 'true' }} + check_docs_noop: + needs: [detect_docs_changes] + if: ${{ needs.detect_docs_changes.outputs.docs_changed != 'true' }} runs-on: ubuntu-latest steps: - run: echo "No docs changes detected. Skipping docs build." - quality-gate: - needs: [pre-commit-rolling, pre-commit-lyrical, check-docs, check-docs-noop] + quality_gate: + needs: [pre_commit_rolling, pre_commit_lyrical, check_docs, check_docs_noop] if: ${{ always() }} runs-on: ubuntu-latest steps: - name: Validate quality gate run: | - if [[ "${{ needs.pre-commit-rolling.result }}" != "success" || "${{ needs.pre-commit-lyrical.result }}" != "success" ]]; then + if [[ "${{ needs.pre_commit_rolling.result }}" != "success" || "${{ needs.pre_commit_lyrical.result }}" != "success" ]]; then echo "Pre-commit gate failed." exit 1 fi - if [[ "${{ needs.check-docs.result }}" == "success" || "${{ needs.check-docs-noop.result }}" == "success" ]]; then + if [[ "${{ needs.check_docs.result }}" == "success" || "${{ needs.check_docs_noop.result }}" == "success" ]]; then echo "Quality gate passed." exit 0 fi @@ -108,8 +108,8 @@ jobs: exit 1 semi-binary: - needs: [quality-gate] - if: ${{ needs.quality-gate.result == 'success' }} + needs: [quality_gate] + if: ${{ needs.quality_gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -122,8 +122,8 @@ jobs: ref_for_scheduled_build: master semi-binary-clang: - needs: [quality-gate] - if: ${{ needs.quality-gate.result == 'success' }} + needs: [quality_gate] + if: ${{ needs.quality_gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -140,8 +140,8 @@ jobs: not_test_build: true build-downstream: - needs: [quality-gate] - if: ${{ needs.quality-gate.result == 'success' }} + needs: [quality_gate] + if: ${{ needs.quality_gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -157,8 +157,8 @@ jobs: not_test_downstream: false binary: - needs: [quality-gate] - if: ${{ needs.quality-gate.result == 'success' }} + needs: [quality_gate] + if: ${{ needs.quality_gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -175,16 +175,16 @@ jobs: ref_for_scheduled_build: master coverage_rolling: - needs: [quality-gate] - if: ${{ needs.quality-gate.result == 'success' }} + needs: [quality_gate] + if: ${{ needs.quality_gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-build-coverage.yml@master secrets: inherit with: ros_distro: rolling compatibility-build: - needs: [quality-gate] - if: ${{ needs.quality-gate.result == 'success' }} + needs: [quality_gate] + if: ${{ needs.quality_gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -197,8 +197,8 @@ jobs: ref_for_scheduled_build: master abi_check: - needs: [quality-gate] - if: ${{ needs.quality-gate.result == 'success' }} + needs: [quality_gate] + if: ${{ needs.quality_gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-abi-check.yml@master strategy: fail-fast: false @@ -208,8 +208,8 @@ jobs: ros_distro: ${{ matrix.ROS_DISTRO }} debian_semi_binary_build: - needs: [quality-gate] - if: ${{ needs.quality-gate.result == 'success' }} + needs: [quality_gate] + if: ${{ needs.quality_gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-debian-build.yml@master strategy: fail-fast: false @@ -222,8 +222,8 @@ jobs: skip_packages: rqt_controller_manager rhel_semi_binary_build: - needs: [quality-gate] - if: ${{ needs.quality-gate.result == 'success' }} + needs: [quality_gate] + if: ${{ needs.quality_gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-rhel-binary-build.yml@master strategy: fail-fast: false @@ -236,8 +236,8 @@ jobs: skip_packages: rqt_controller_manager binary-windows: - needs: [quality-gate] - if: ${{ needs.quality-gate.result == 'success' }} + needs: [quality_gate] + if: ${{ needs.quality_gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-ros-tooling-win-build.yml@master with: ros_distro: rolling From ec44f9b0f8eb4f916d68e46fdc1929af3fd3a896 Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Tue, 14 Jul 2026 12:25:18 +0000 Subject: [PATCH 05/11] Try another fix --- .github/workflows/rolling-pr-gated-ci.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/rolling-pr-gated-ci.yml b/.github/workflows/rolling-pr-gated-ci.yml index c1a8f63509..d056045a59 100644 --- a/.github/workflows/rolling-pr-gated-ci.yml +++ b/.github/workflows/rolling-pr-gated-ci.yml @@ -109,7 +109,7 @@ jobs: semi-binary: needs: [quality_gate] - if: ${{ needs.quality_gate.result == 'success' }} + if: ${{ always() && needs.quality_gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -123,7 +123,7 @@ jobs: semi-binary-clang: needs: [quality_gate] - if: ${{ needs.quality_gate.result == 'success' }} + if: ${{ always() && needs.quality_gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -141,7 +141,7 @@ jobs: build-downstream: needs: [quality_gate] - if: ${{ needs.quality_gate.result == 'success' }} + if: ${{ always() && needs.quality_gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -158,7 +158,7 @@ jobs: binary: needs: [quality_gate] - if: ${{ needs.quality_gate.result == 'success' }} + if: ${{ always() && needs.quality_gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -176,7 +176,7 @@ jobs: coverage_rolling: needs: [quality_gate] - if: ${{ needs.quality_gate.result == 'success' }} + if: ${{ always() && needs.quality_gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-build-coverage.yml@master secrets: inherit with: @@ -184,7 +184,7 @@ jobs: compatibility-build: needs: [quality_gate] - if: ${{ needs.quality_gate.result == 'success' }} + if: ${{ always() && needs.quality_gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -198,7 +198,7 @@ jobs: abi_check: needs: [quality_gate] - if: ${{ needs.quality_gate.result == 'success' }} + if: ${{ always() && needs.quality_gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-abi-check.yml@master strategy: fail-fast: false @@ -209,7 +209,7 @@ jobs: debian_semi_binary_build: needs: [quality_gate] - if: ${{ needs.quality_gate.result == 'success' }} + if: ${{ always() && needs.quality_gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-debian-build.yml@master strategy: fail-fast: false @@ -223,7 +223,7 @@ jobs: rhel_semi_binary_build: needs: [quality_gate] - if: ${{ needs.quality_gate.result == 'success' }} + if: ${{ always() && needs.quality_gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-rhel-binary-build.yml@master strategy: fail-fast: false @@ -237,7 +237,7 @@ jobs: binary-windows: needs: [quality_gate] - if: ${{ needs.quality_gate.result == 'success' }} + if: ${{ always() && needs.quality_gate.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-ros-tooling-win-build.yml@master with: ros_distro: rolling From bebbacbcae31b27fcb0bd5a734e93647adb987ce Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Wed, 22 Jul 2026 05:24:54 +0000 Subject: [PATCH 06/11] Move the docs check to its own file again --- .github/workflows/rolling-check-docs.yml | 14 +++++ .github/workflows/rolling-pr-gated-ci.yml | 62 ++--------------------- 2 files changed, 17 insertions(+), 59 deletions(-) diff --git a/.github/workflows/rolling-check-docs.yml b/.github/workflows/rolling-check-docs.yml index c9ec0097dd..bac1a6dd86 100644 --- a/.github/workflows/rolling-check-docs.yml +++ b/.github/workflows/rolling-check-docs.yml @@ -2,6 +2,20 @@ name: Rolling Check Docs on: workflow_dispatch: + pull_request: + branches: + - master + paths: + - '**.rst' + - '**.md' + - '**.jpg' + - '**.jpeg' + - '**.png' + - '**.svg' + - '**.yml' + - '**.yaml' + - '!.github/**' # exclude yaml files in .github directory + - '.github/workflows/rolling-check-docs.yml' concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/rolling-pr-gated-ci.yml b/.github/workflows/rolling-pr-gated-ci.yml index d056045a59..1267821d42 100644 --- a/.github/workflows/rolling-pr-gated-ci.yml +++ b/.github/workflows/rolling-pr-gated-ci.yml @@ -11,13 +11,6 @@ on: - '**.cpp' - '**.py' - '**.yaml' - - '**.yml' - - '**.rst' - - '**.md' - - '**.jpg' - - '**.jpeg' - - '**.png' - - '**.svg' - '.github/workflows/rolling-pr-gated-ci.yml' - '**/package.xml' - '**/CMakeLists.txt' @@ -44,52 +37,8 @@ jobs: with: ros_distro: lyrical - detect_docs_changes: - runs-on: ubuntu-latest - outputs: - docs_changed: ${{ steps.docs_changed.outputs.docs_changed }} - steps: - - id: filter - if: ${{ github.event_name == 'pull_request' }} - uses: dorny/paths-filter@v3 - with: - filters: | - docs: - - '**.rst' - - '**.md' - - '**.jpg' - - '**.jpeg' - - '**.png' - - '**.svg' - - '**.yml' - - '**.yaml' - - '!.github/**' - - '.github/workflows/rolling-pr-gated-ci.yml' - - id: docs_changed - run: | - if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then - echo "docs_changed=true" >> "$GITHUB_OUTPUT" - else - echo "docs_changed=${{ steps.filter.outputs.docs }}" >> "$GITHUB_OUTPUT" - fi - - check_docs: - name: Check Docs - needs: [detect_docs_changes] - if: ${{ needs.detect_docs_changes.outputs.docs_changed == 'true' }} - uses: ros-controls/control.ros.org/.github/workflows/reusable-sphinx-check-single-version.yml@rolling - with: - ROS2_CONTROL_PR: ${{ github.ref }} - - check_docs_noop: - needs: [detect_docs_changes] - if: ${{ needs.detect_docs_changes.outputs.docs_changed != 'true' }} - runs-on: ubuntu-latest - steps: - - run: echo "No docs changes detected. Skipping docs build." - quality_gate: - needs: [pre_commit_rolling, pre_commit_lyrical, check_docs, check_docs_noop] + needs: [pre_commit_rolling, pre_commit_lyrical] if: ${{ always() }} runs-on: ubuntu-latest steps: @@ -99,13 +48,8 @@ jobs: echo "Pre-commit gate failed." exit 1 fi - - if [[ "${{ needs.check_docs.result }}" == "success" || "${{ needs.check_docs_noop.result }}" == "success" ]]; then - echo "Quality gate passed." - exit 0 - fi - echo "Docs gate failed." - exit 1 + echo "Quality gate passed." + exit 0 semi-binary: needs: [quality_gate] From 3d01982074d09ab1f5c67b7fa85951a844dfd260 Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Wed, 22 Jul 2026 05:41:32 +0000 Subject: [PATCH 07/11] Gate the downstream jobs --- .github/workflows/rolling-pr-gated-ci.yml | 63 +++++++++++++++++------ 1 file changed, 46 insertions(+), 17 deletions(-) diff --git a/.github/workflows/rolling-pr-gated-ci.yml b/.github/workflows/rolling-pr-gated-ci.yml index 1267821d42..beaa20e28b 100644 --- a/.github/workflows/rolling-pr-gated-ci.yml +++ b/.github/workflows/rolling-pr-gated-ci.yml @@ -83,23 +83,6 @@ jobs: cxx_compiler: clang++ not_test_build: true - build-downstream: - needs: [quality_gate] - if: ${{ always() && needs.quality_gate.result == 'success' }} - uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master - strategy: - fail-fast: false - matrix: - ROS_DISTRO: [lyrical, rolling] - with: - ros_distro: ${{ matrix.ROS_DISTRO }} - ros_repo: testing - ref_for_scheduled_build: master - upstream_workspace: ros2_control.${{ matrix.ROS_DISTRO }}.repos - not_test_build: true - downstream_workspace: ros_controls.${{ matrix.ROS_DISTRO }}.repos - not_test_downstream: false - binary: needs: [quality_gate] if: ${{ always() && needs.quality_gate.result == 'success' }} @@ -151,6 +134,35 @@ jobs: with: ros_distro: ${{ matrix.ROS_DISTRO }} + ubuntu_gate: + needs: [semi-binary, semi-binary-clang, binary, coverage_rolling, compatibility-build] + if: ${{ always() }} + runs-on: ubuntu-latest + steps: + - name: Validate Ubuntu gate + run: | + if [[ "${{ needs.semi-binary.result }}" != "success" ]]; then + echo "semi-binary failed" + exit 1 + fi + if [[ "${{ needs.semi-binary-clang.result }}" != "success" ]]; then + echo "semi-binary-clang failed" + exit 1 + fi + if [[ "${{ needs.binary.result }}" != "success" ]]; then + echo "binary failed" + exit 1 + fi + if [[ "${{ needs.coverage_rolling.result }}" != "success" ]]; then + echo "coverage_rolling failed" + exit 1 + fi + if [[ "${{ needs.compatibility-build.result }}" != "success" ]]; then + echo "compatibility-build failed" + exit 1 + fi + echo "Ubuntu gate passed." + debian_semi_binary_build: needs: [quality_gate] if: ${{ always() && needs.quality_gate.result == 'success' }} @@ -187,3 +199,20 @@ jobs: ros_distro: rolling pixi_dependencies: typeguard jinja2 boost compilers cpp-expected upstream_workspace: ros2_control.rolling.repos + + build-downstream: + needs: [ubuntu_gate] + if: ${{ always() && needs.ubuntu_gate.result == 'success' }} + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master + strategy: + fail-fast: false + matrix: + ROS_DISTRO: [lyrical, rolling] + with: + ros_distro: ${{ matrix.ROS_DISTRO }} + ros_repo: testing + ref_for_scheduled_build: master + upstream_workspace: ros2_control.${{ matrix.ROS_DISTRO }}.repos + not_test_build: true + downstream_workspace: ros_controls.${{ matrix.ROS_DISTRO }}.repos + not_test_downstream: false From 22c4b8ee91ef3c0ad14f3f0cb3c28d62ecaa4bf5 Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Wed, 22 Jul 2026 05:55:11 +0000 Subject: [PATCH 08/11] Simplify layout --- .github/workflows/rolling-pr-gated-ci.yml | 33 ++--------------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/.github/workflows/rolling-pr-gated-ci.yml b/.github/workflows/rolling-pr-gated-ci.yml index beaa20e28b..9ae149b953 100644 --- a/.github/workflows/rolling-pr-gated-ci.yml +++ b/.github/workflows/rolling-pr-gated-ci.yml @@ -134,35 +134,6 @@ jobs: with: ros_distro: ${{ matrix.ROS_DISTRO }} - ubuntu_gate: - needs: [semi-binary, semi-binary-clang, binary, coverage_rolling, compatibility-build] - if: ${{ always() }} - runs-on: ubuntu-latest - steps: - - name: Validate Ubuntu gate - run: | - if [[ "${{ needs.semi-binary.result }}" != "success" ]]; then - echo "semi-binary failed" - exit 1 - fi - if [[ "${{ needs.semi-binary-clang.result }}" != "success" ]]; then - echo "semi-binary-clang failed" - exit 1 - fi - if [[ "${{ needs.binary.result }}" != "success" ]]; then - echo "binary failed" - exit 1 - fi - if [[ "${{ needs.coverage_rolling.result }}" != "success" ]]; then - echo "coverage_rolling failed" - exit 1 - fi - if [[ "${{ needs.compatibility-build.result }}" != "success" ]]; then - echo "compatibility-build failed" - exit 1 - fi - echo "Ubuntu gate passed." - debian_semi_binary_build: needs: [quality_gate] if: ${{ always() && needs.quality_gate.result == 'success' }} @@ -201,8 +172,8 @@ jobs: upstream_workspace: ros2_control.rolling.repos build-downstream: - needs: [ubuntu_gate] - if: ${{ always() && needs.ubuntu_gate.result == 'success' }} + needs: [semi-binary, semi-binary-clang, binary, coverage_rolling, compatibility-build] + if: ${{ always() && needs['semi-binary'].result == 'success' && needs['semi-binary-clang'].result == 'success' && needs.binary.result == 'success' && needs.coverage_rolling.result == 'success' && needs['compatibility-build'].result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false From 91e8987062ea12fefe255167fb9b74e245ee93f2 Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Wed, 22 Jul 2026 06:17:32 +0000 Subject: [PATCH 09/11] Simplify gating --- .github/workflows/rolling-pr-gated-ci.yml | 50 ++++++++--------------- 1 file changed, 18 insertions(+), 32 deletions(-) diff --git a/.github/workflows/rolling-pr-gated-ci.yml b/.github/workflows/rolling-pr-gated-ci.yml index 9ae149b953..aa1e95b10b 100644 --- a/.github/workflows/rolling-pr-gated-ci.yml +++ b/.github/workflows/rolling-pr-gated-ci.yml @@ -37,23 +37,9 @@ jobs: with: ros_distro: lyrical - quality_gate: - needs: [pre_commit_rolling, pre_commit_lyrical] - if: ${{ always() }} - runs-on: ubuntu-latest - steps: - - name: Validate quality gate - run: | - if [[ "${{ needs.pre_commit_rolling.result }}" != "success" || "${{ needs.pre_commit_lyrical.result }}" != "success" ]]; then - echo "Pre-commit gate failed." - exit 1 - fi - echo "Quality gate passed." - exit 0 - semi-binary: - needs: [quality_gate] - if: ${{ always() && needs.quality_gate.result == 'success' }} + needs: [pre_commit_rolling, pre_commit_lyrical] + if: ${{ always() && needs.pre_commit_rolling.result == 'success' && needs.pre_commit_lyrical.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -66,8 +52,8 @@ jobs: ref_for_scheduled_build: master semi-binary-clang: - needs: [quality_gate] - if: ${{ always() && needs.quality_gate.result == 'success' }} + needs: [pre_commit_rolling, pre_commit_lyrical] + if: ${{ always() && needs.pre_commit_rolling.result == 'success' && needs.pre_commit_lyrical.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -84,8 +70,8 @@ jobs: not_test_build: true binary: - needs: [quality_gate] - if: ${{ always() && needs.quality_gate.result == 'success' }} + needs: [pre_commit_rolling, pre_commit_lyrical] + if: ${{ always() && needs.pre_commit_rolling.result == 'success' && needs.pre_commit_lyrical.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -102,16 +88,16 @@ jobs: ref_for_scheduled_build: master coverage_rolling: - needs: [quality_gate] - if: ${{ always() && needs.quality_gate.result == 'success' }} + needs: [pre_commit_rolling, pre_commit_lyrical] + if: ${{ always() && needs.pre_commit_rolling.result == 'success' && needs.pre_commit_lyrical.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-build-coverage.yml@master secrets: inherit with: ros_distro: rolling compatibility-build: - needs: [quality_gate] - if: ${{ always() && needs.quality_gate.result == 'success' }} + needs: [pre_commit_rolling, pre_commit_lyrical] + if: ${{ always() && needs.pre_commit_rolling.result == 'success' && needs.pre_commit_lyrical.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false @@ -124,8 +110,8 @@ jobs: ref_for_scheduled_build: master abi_check: - needs: [quality_gate] - if: ${{ always() && needs.quality_gate.result == 'success' }} + needs: [pre_commit_rolling, pre_commit_lyrical] + if: ${{ always() && needs.pre_commit_rolling.result == 'success' && needs.pre_commit_lyrical.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-abi-check.yml@master strategy: fail-fast: false @@ -135,8 +121,8 @@ jobs: ros_distro: ${{ matrix.ROS_DISTRO }} debian_semi_binary_build: - needs: [quality_gate] - if: ${{ always() && needs.quality_gate.result == 'success' }} + needs: [pre_commit_rolling, pre_commit_lyrical] + if: ${{ always() && needs.pre_commit_rolling.result == 'success' && needs.pre_commit_lyrical.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-debian-build.yml@master strategy: fail-fast: false @@ -149,8 +135,8 @@ jobs: skip_packages: rqt_controller_manager rhel_semi_binary_build: - needs: [quality_gate] - if: ${{ always() && needs.quality_gate.result == 'success' }} + needs: [pre_commit_rolling, pre_commit_lyrical] + if: ${{ always() && needs.pre_commit_rolling.result == 'success' && needs.pre_commit_lyrical.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-rhel-binary-build.yml@master strategy: fail-fast: false @@ -163,8 +149,8 @@ jobs: skip_packages: rqt_controller_manager binary-windows: - needs: [quality_gate] - if: ${{ always() && needs.quality_gate.result == 'success' }} + needs: [pre_commit_rolling, pre_commit_lyrical] + if: ${{ always() && needs.pre_commit_rolling.result == 'success' && needs.pre_commit_lyrical.result == 'success' }} uses: ros-controls/ros2_control_ci/.github/workflows/reusable-ros-tooling-win-build.yml@master with: ros_distro: rolling From c77a881b836f3d8e70662331f260a6940dccfc89 Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Wed, 22 Jul 2026 07:53:29 +0000 Subject: [PATCH 10/11] Only skip downstream jobs if build already fails --- .github/workflows/rolling-pr-gated-ci.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/rolling-pr-gated-ci.yml b/.github/workflows/rolling-pr-gated-ci.yml index aa1e95b10b..f529b9c55b 100644 --- a/.github/workflows/rolling-pr-gated-ci.yml +++ b/.github/workflows/rolling-pr-gated-ci.yml @@ -40,7 +40,7 @@ jobs: semi-binary: needs: [pre_commit_rolling, pre_commit_lyrical] if: ${{ always() && needs.pre_commit_rolling.result == 'success' && needs.pre_commit_lyrical.result == 'success' }} - uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@ici-output strategy: fail-fast: false matrix: @@ -54,7 +54,7 @@ jobs: semi-binary-clang: needs: [pre_commit_rolling, pre_commit_lyrical] if: ${{ always() && needs.pre_commit_rolling.result == 'success' && needs.pre_commit_lyrical.result == 'success' }} - uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@ici-output strategy: fail-fast: false matrix: @@ -72,7 +72,7 @@ jobs: binary: needs: [pre_commit_rolling, pre_commit_lyrical] if: ${{ always() && needs.pre_commit_rolling.result == 'success' && needs.pre_commit_lyrical.result == 'success' }} - uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@ici-output strategy: fail-fast: false matrix: @@ -98,7 +98,7 @@ jobs: compatibility-build: needs: [pre_commit_rolling, pre_commit_lyrical] if: ${{ always() && needs.pre_commit_rolling.result == 'success' && needs.pre_commit_lyrical.result == 'success' }} - uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@ici-output strategy: fail-fast: false matrix: @@ -159,8 +159,8 @@ jobs: build-downstream: needs: [semi-binary, semi-binary-clang, binary, coverage_rolling, compatibility-build] - if: ${{ always() && needs['semi-binary'].result == 'success' && needs['semi-binary-clang'].result == 'success' && needs.binary.result == 'success' && needs.coverage_rolling.result == 'success' && needs['compatibility-build'].result == 'success' }} - uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master + if: ${{ always() && needs['semi-binary'].outputs.build_target_workspace_succeeded == 'true' && needs['semi-binary-clang'].outputs.build_target_workspace_succeeded == 'true' && needs.binary.outputs.build_target_workspace_succeeded == 'true' && needs.coverage_rolling.result == 'success' && needs['compatibility-build'].outputs.build_target_workspace_succeeded == 'true' }} + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@ici-output strategy: fail-fast: false matrix: From 5194e1f7abd54be6f9a2603d276492b0f7240a23 Mon Sep 17 00:00:00 2001 From: Christoph Froehlich Date: Wed, 22 Jul 2026 10:40:20 +0000 Subject: [PATCH 11/11] Use master branch of ci repo again --- .github/workflows/rolling-pr-gated-ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/rolling-pr-gated-ci.yml b/.github/workflows/rolling-pr-gated-ci.yml index f529b9c55b..dd2d5a7838 100644 --- a/.github/workflows/rolling-pr-gated-ci.yml +++ b/.github/workflows/rolling-pr-gated-ci.yml @@ -40,7 +40,7 @@ jobs: semi-binary: needs: [pre_commit_rolling, pre_commit_lyrical] if: ${{ always() && needs.pre_commit_rolling.result == 'success' && needs.pre_commit_lyrical.result == 'success' }} - uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@ici-output + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false matrix: @@ -54,7 +54,7 @@ jobs: semi-binary-clang: needs: [pre_commit_rolling, pre_commit_lyrical] if: ${{ always() && needs.pre_commit_rolling.result == 'success' && needs.pre_commit_lyrical.result == 'success' }} - uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@ici-output + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false matrix: @@ -72,7 +72,7 @@ jobs: binary: needs: [pre_commit_rolling, pre_commit_lyrical] if: ${{ always() && needs.pre_commit_rolling.result == 'success' && needs.pre_commit_lyrical.result == 'success' }} - uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@ici-output + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false matrix: @@ -98,7 +98,7 @@ jobs: compatibility-build: needs: [pre_commit_rolling, pre_commit_lyrical] if: ${{ always() && needs.pre_commit_rolling.result == 'success' && needs.pre_commit_lyrical.result == 'success' }} - uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@ici-output + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false matrix: @@ -160,7 +160,7 @@ jobs: build-downstream: needs: [semi-binary, semi-binary-clang, binary, coverage_rolling, compatibility-build] if: ${{ always() && needs['semi-binary'].outputs.build_target_workspace_succeeded == 'true' && needs['semi-binary-clang'].outputs.build_target_workspace_succeeded == 'true' && needs.binary.outputs.build_target_workspace_succeeded == 'true' && needs.coverage_rolling.result == 'success' && needs['compatibility-build'].outputs.build_target_workspace_succeeded == 'true' }} - uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@ici-output + uses: ros-controls/ros2_control_ci/.github/workflows/reusable-industrial-ci-with-cache.yml@master strategy: fail-fast: false matrix: