ros2_medkit_updated #413
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| pull_request: | |
| branches: [main] | |
| push: | |
| branches: [main] | |
| repository_dispatch: | |
| types: [ros2_medkit_updated] | |
| permissions: | |
| contents: read | |
| jobs: | |
| lint: | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Check for trailing whitespace | |
| run: | | |
| ! git grep -I --line-number --perl-regexp '\s+$' -- \ | |
| '*.md' '*.py' '*.yaml' '*.yml' || \ | |
| (echo "Found trailing whitespace in the files above" && exit 1) | |
| - name: Check shell scripts with shellcheck | |
| run: | | |
| sudo apt-get update && sudo apt-get install -y shellcheck | |
| find . \( -name "*.sh" -o -name "*.bash" \) -type f | xargs shellcheck | |
| - name: Validate YAML files | |
| run: | | |
| sudo apt-get update && sudo apt-get install -y yamllint | |
| YAMLLINT_CONFIG="{extends: relaxed, rules: {line-length: {max: 120}}}" | |
| find . \( -name "*.yaml" -o -name "*.yml" \) -type f | xargs yamllint -d "$YAMLLINT_CONFIG" | |
| build-and-test-sensor: | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Show triggering source | |
| if: github.event_name == 'repository_dispatch' | |
| run: | | |
| SHA="${{ github.event.client_payload.sha }}" | |
| RUN_URL="${{ github.event.client_payload.run_url }}" | |
| echo "## Triggered by ros2_medkit" >> "$GITHUB_STEP_SUMMARY" | |
| echo "- Commit: \`${SHA:-unknown}\`" >> "$GITHUB_STEP_SUMMARY" | |
| if [ -n "$RUN_URL" ]; then | |
| echo "- Run: [View triggering run]($RUN_URL)" >> "$GITHUB_STEP_SUMMARY" | |
| else | |
| echo "- Run: (URL not provided)" >> "$GITHUB_STEP_SUMMARY" | |
| fi | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Build and start sensor_diagnostics demo | |
| working-directory: demos/sensor_diagnostics | |
| run: docker compose --profile ci up -d --build sensor-demo-ci | |
| - name: Run smoke tests | |
| run: ./tests/smoke_test.sh | |
| - name: Show container logs on failure | |
| if: failure() | |
| working-directory: demos/sensor_diagnostics | |
| run: docker compose --profile ci logs sensor-demo-ci --tail=200 | |
| - name: Teardown | |
| if: always() | |
| working-directory: demos/sensor_diagnostics | |
| run: docker compose --profile ci down | |
| build-and-test-turtlebot: | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Build and start turtlebot3 demo | |
| working-directory: demos/turtlebot3_integration | |
| run: docker compose --profile ci up -d --build turtlebot3-demo-ci | |
| - name: Run smoke tests | |
| run: ./tests/smoke_test_turtlebot3.sh | |
| - name: Show container logs on failure | |
| if: failure() | |
| working-directory: demos/turtlebot3_integration | |
| run: docker compose --profile ci logs turtlebot3-demo-ci --tail=200 | |
| - name: Teardown | |
| if: always() | |
| working-directory: demos/turtlebot3_integration | |
| run: docker compose --profile ci down | |
| build-and-test-moveit: | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Build and start moveit demo | |
| working-directory: demos/moveit_pick_place | |
| run: docker compose --profile ci up -d --build moveit-demo-ci | |
| - name: Run smoke tests | |
| run: ./tests/smoke_test_moveit.sh | |
| - name: Show container logs on failure | |
| if: failure() | |
| working-directory: demos/moveit_pick_place | |
| run: docker compose --profile ci logs moveit-demo-ci --tail=200 | |
| - name: Teardown | |
| if: always() | |
| working-directory: demos/moveit_pick_place | |
| run: docker compose --profile ci down | |
| build-and-test-multi-ecu: | |
| needs: lint | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Show triggering source | |
| if: github.event_name == 'repository_dispatch' | |
| run: | | |
| SHA="${{ github.event.client_payload.sha }}" | |
| RUN_URL="${{ github.event.client_payload.run_url }}" | |
| echo "## Triggered by ros2_medkit" >> "$GITHUB_STEP_SUMMARY" | |
| echo "- Commit: \`${SHA:-unknown}\`" >> "$GITHUB_STEP_SUMMARY" | |
| if [ -n "$RUN_URL" ]; then | |
| echo "- Run: [View triggering run]($RUN_URL)" >> "$GITHUB_STEP_SUMMARY" | |
| else | |
| echo "- Run: (URL not provided)" >> "$GITHUB_STEP_SUMMARY" | |
| fi | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Build and start multi-ECU demo | |
| working-directory: demos/multi_ecu_aggregation | |
| run: docker compose --profile ci up -d --build perception-ecu-ci planning-ecu-ci actuation-ecu-ci | |
| - name: Run smoke tests | |
| run: ./tests/smoke_test_multi_ecu.sh | |
| - name: Show perception ECU logs on failure | |
| if: failure() | |
| working-directory: demos/multi_ecu_aggregation | |
| run: docker compose --profile ci logs perception-ecu-ci --tail=200 | |
| - name: Show planning ECU logs on failure | |
| if: failure() | |
| working-directory: demos/multi_ecu_aggregation | |
| run: docker compose --profile ci logs planning-ecu-ci --tail=200 | |
| - name: Show actuation ECU logs on failure | |
| if: failure() | |
| working-directory: demos/multi_ecu_aggregation | |
| run: docker compose --profile ci logs actuation-ecu-ci --tail=200 | |
| - name: Teardown | |
| if: always() | |
| working-directory: demos/multi_ecu_aggregation | |
| run: docker compose --profile ci down | |
| build-and-test-ota: | |
| needs: lint | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Show triggering source | |
| if: github.event_name == 'repository_dispatch' | |
| run: | | |
| SHA="${{ github.event.client_payload.sha }}" | |
| RUN_URL="${{ github.event.client_payload.run_url }}" | |
| echo "## Triggered by ros2_medkit" >> "$GITHUB_STEP_SUMMARY" | |
| echo "- Commit: \`${SHA:-unknown}\`" >> "$GITHUB_STEP_SUMMARY" | |
| if [ -n "$RUN_URL" ]; then | |
| echo "- Run: [View triggering run]($RUN_URL)" >> "$GITHUB_STEP_SUMMARY" | |
| else | |
| echo "- Run: (URL not provided)" >> "$GITHUB_STEP_SUMMARY" | |
| fi | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Build and start OTA demo | |
| working-directory: demos/ota_nav2_sensor_fix | |
| run: docker compose up -d --build | |
| - name: Run smoke tests | |
| run: ./tests/smoke_test_ota.sh | |
| - name: Diagnostics on failure | |
| if: failure() | |
| run: ./tests/dump_ota_diagnostics.sh ota_diagnostics.log | |
| - name: Upload diagnostics | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ota-diagnostics-smoke | |
| path: ota_diagnostics.log | |
| - name: Teardown | |
| if: always() | |
| working-directory: demos/ota_nav2_sensor_fix | |
| run: docker compose down | |
| # Actually runs the OTA demo's own test suites (they never run in the demo | |
| # up/smoke jobs). The C++ gtest is built and executed inside the plugin test | |
| # stage of Dockerfile.gateway (a failing test fails the docker build); the two | |
| # pytest suites run natively. | |
| plugin-tests: | |
| needs: lint | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Run ota_update_plugin C++ gtest (in image build) | |
| working-directory: demos/ota_nav2_sensor_fix | |
| run: docker build --target ota-plugin-test -f Dockerfile.gateway . | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.12' | |
| - name: Install Python test dependencies | |
| run: pip install pytest fastapi 'uvicorn[standard]' httpx | |
| - name: Run ota_update_server pytest suite | |
| working-directory: demos/ota_nav2_sensor_fix/ota_update_server | |
| run: pytest tests | |
| - name: Run pack_artifact pytest suite | |
| working-directory: demos/ota_nav2_sensor_fix/scripts | |
| run: pytest test_pack_artifact.py | |
| # Separate job from build-and-test-ota: this one drives the full | |
| # latch/publish/apply/clear narrative through the operator scripts. The | |
| # entrypoint auto-applies broken_lidar_3_0_0 at boot; send-goal.sh then | |
| # drives the robot into the phantom sector so Nav2 cannot make progress | |
| # and navigate_to_pose aborts, which the log + action-status bridges | |
| # surface as ACTION_NAVIGATE_TO_POSE_ABORTED on bt-navigator (latched, | |
| # with a freeze-frame + MCAP capture). publish-fix.sh registers the | |
| # forward hotfix fixed_lidar_3_0_1 (not in the boot catalog), then | |
| # apply-fix.sh swaps scan_sensor_node to it, but the fault stays | |
| # latched (no self-heal) until clear-fault.sh explicitly clears it, and | |
| # only then does a fresh send-goal.sh resume clean. Catches regressions | |
| # in that loop (phantom not stalling Nav2, the bridges not promoting the | |
| # failure, fault_manager latching/capture, the fault clearing itself on | |
| # apply). Slower than the API-only smoke job because it has | |
| # to wait for nav2 lifecycle to settle and for /cmd_vel to actually | |
| # fire, so it's split out and can fail in isolation without blocking | |
| # the quick OTA-endpoint check. | |
| ota-demo-narrative: | |
| needs: lint | |
| runs-on: ubuntu-24.04 | |
| steps: | |
| - name: Show triggering source | |
| if: github.event_name == 'repository_dispatch' | |
| run: | | |
| SHA="${{ github.event.client_payload.sha }}" | |
| RUN_URL="${{ github.event.client_payload.run_url }}" | |
| echo "## Triggered by ros2_medkit" >> "$GITHUB_STEP_SUMMARY" | |
| echo "- Commit: \`${SHA:-unknown}\`" >> "$GITHUB_STEP_SUMMARY" | |
| if [ -n "$RUN_URL" ]; then | |
| echo "- Run: [View triggering run]($RUN_URL)" >> "$GITHUB_STEP_SUMMARY" | |
| fi | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Build and start OTA demo | |
| working-directory: demos/ota_nav2_sensor_fix | |
| # docker compose up --build runs the multi-stage build for | |
| # ota_update_server which produces the catalog + tarballs | |
| # internally - no separate "build artifacts on host" step | |
| # needed (and the host wouldn't have ros2_medkit_msgs anyway). | |
| run: docker compose up -d --build | |
| - name: Run demo narrative smoke | |
| run: ./tests/smoke_test_demo_narrative.sh | |
| - name: Diagnostics on failure | |
| if: failure() | |
| run: ./tests/dump_ota_diagnostics.sh ota_diagnostics.log | |
| - name: Upload diagnostics | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ota-diagnostics-narrative | |
| path: ota_diagnostics.log | |
| - name: Teardown | |
| if: always() | |
| working-directory: demos/ota_nav2_sensor_fix | |
| run: docker compose down |