From 7cf57286a59e18d2401c88ebe0974158dc3f75fa Mon Sep 17 00:00:00 2001 From: Claude Code Agent Date: Tue, 14 Jul 2026 16:17:03 -0400 Subject: [PATCH 1/2] Add workspace-standard infrastructure Onboarding: pre-commit config, CI workflow (colcon build + headless gtest suite with 4 source-sibling clones), root AGENTS.md (ADR-0017), and agent guide update to reflect the new CI/pre-commit gates. Closes #165 --- .agents/README.md | 5 +- .github/workflows/ci.yml | 101 +++++++++++++++++++++++++++++++++++++++ .pre-commit-config.yaml | 43 +++++++++++++++++ AGENTS.md | 57 ++++++++++++++++++++++ 4 files changed, 204 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .pre-commit-config.yaml create mode 100644 AGENTS.md diff --git a/.agents/README.md b/.agents/README.md index 5dadc5a..5767648 100644 --- a/.agents/README.md +++ b/.agents/README.md @@ -8,8 +8,9 @@ desktop GUI for planning and monitoring autonomous marine-vehicle missions. Standard worktree/PR workflow (this is a GitHub-origin repo). The default branch is **`jazzy`**, not `main`. -There is **no CI and no pre-commit config** in this repo. The build + the gtest -suite are the only automated gates — run them locally before pushing. +CI (`.github/workflows/ci.yml`, colcon build + gtest suite) and pre-commit +(`.pre-commit-config.yaml`) are both configured — run the tests locally and +let pre-commit hooks run before pushing. > When developed inside the `ros2_agent_workspace` (the usual case), the > workspace's `.agent/scripts/` (field-mode detection, worktree helpers, etc.) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..5ccf959 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,101 @@ +# CI for camp. +# Based on the workspace template (ros2_agent_workspace .agent/templates/ci_workflow.yml). + +name: CI + +on: + push: + branches: [jazzy] + pull_request: + branches: [jazzy] + +jobs: + build-and-test: + runs-on: ubuntu-24.04 + permissions: + contents: read + container: + image: ros:jazzy-ros-core + + steps: + - name: Update apt + run: apt-get update + + - name: Install ros dev tools + run: DEBIAN_FRONTEND=noninteractive apt-get -y install ros-dev-tools + + - name: Checkout + uses: actions/checkout@v6 + + - name: Init rosdep + run: | + if [ ! -f /etc/ros/rosdep/sources.list.d/20-default.list ]; then + rosdep init + fi + + - name: Update rosdep + run: rosdep update + + - name: Create workspace + run: mkdir -p ../ws/src && ln -s "$GITHUB_WORKSPACE" ../ws/src/camp + + # Source-sibling dependencies not in rosdep. camp needs marine_autonomy, + # marine_interfaces, and marine_tiled_raster_store (unh_marine_autonomy); + # marine_colormap and marine_colormap_widgets (marine_colormap); + # marine_nav_interfaces and marine_nav_tasks — plus their sibling + # marine_nav_utilities — (unh_marine_navigation); and marine_ais_msgs + # (marine_ais). Everything else resolves via rosdep. + - name: Clone unh_marine_autonomy (source-sibling dependency, not in rosdep) + run: > + git clone --depth 1 -b jazzy + https://github.com/rolker/unh_marine_autonomy.git + ../ws/src/unh_marine_autonomy + + - name: Clone marine_colormap (source-sibling dependency, not in rosdep) + run: > + git clone --depth 1 -b jazzy + https://github.com/rolker/marine_colormap.git + ../ws/src/marine_colormap + + - name: Clone unh_marine_navigation (source-sibling dependency, not in rosdep) + run: > + git clone --depth 1 -b jazzy + https://github.com/rolker/unh_marine_navigation.git + ../ws/src/unh_marine_navigation + + - name: Clone marine_ais (source-sibling dependency, not in rosdep) + run: > + git clone --depth 1 -b jazzy + https://github.com/rolker/marine_ais.git + ../ws/src/marine_ais + + - name: Install ROS dependencies + working-directory: ../ws + run: > + DEBIAN_FRONTEND=noninteractive + rosdep install --from-paths src --ignore-src -r -y + + - name: Build + working-directory: ../ws + run: > + bash -c 'source /opt/ros/jazzy/setup.bash && + colcon build --packages-up-to camp + --cmake-args -DBUILD_TESTING=ON' + + - name: Test + working-directory: ../ws + # The gtest suite forces QT_QPA_PLATFORM=offscreen internally, so it + # runs headless in this container. + run: > + bash -c 'source /opt/ros/jazzy/setup.bash && + source install/setup.bash && + colcon test --packages-select camp + --event-handlers console_direct+ + --return-code-on-test-failure' + + - name: Test results + working-directory: ../ws + run: > + bash -c 'source /opt/ros/jazzy/setup.bash && + colcon test-result --verbose' + if: always() diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..9229987 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,43 @@ +# Pre-commit configuration for camp. +# Based on the workspace template (ros2_agent_workspace +# .agent/templates/pre-commit-config.yaml); see ADR-0004/0005 there for the +# enforcement hierarchy rationale. +# +# Install: pip install pre-commit && pre-commit install +# Run manually: pre-commit run --all-files + +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + args: ['--unsafe'] # allow ROS YAML tags + - id: check-xml + - id: check-merge-conflict + - id: check-executables-have-shebangs + - id: mixed-line-ending + - id: check-added-large-files + args: ['--maxkb=500'] + + - repo: https://github.com/cheshirekow/cmake-format-precommit + rev: v0.6.13 + hooks: + - id: cmake-lint + args: ['--disabled-codes', 'C0103,C0113,C0301'] + # C0103: invalid-name (ROS packages use unconventional names) + # C0113: missing-command (ament macros not recognized) + # C0301: line-too-long + + - repo: https://github.com/adrienverge/yamllint + rev: v1.35.1 + hooks: + - id: yamllint + args: ['-d', '{extends: default, rules: {line-length: {max: 120}, document-start: disable, truthy: disable}}'] + + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: no-commit-to-branch + args: ['--branch', 'jazzy'] diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..ac5028e --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,57 @@ +# AGENTS.md — camp + +Instructions for AI agents working in this repository — including **GitHub +Copilot code review**, which reads this file when reviewing PRs. Coding +agents: the deep guide (packages, layout, pitfalls) is +[`.agents/README.md`](.agents/README.md); read it before making changes. + +## Workspace Rules + +This repo is developed inside a [ROS 2 Agent Workspace](https://github.com/rolker/ros2_agent_workspace). +The workspace root `AGENTS.md` carries the full shared rules (worktree +isolation, issue-first policy, commit conventions, AI signatures). This file +**references** those rules and adds repo-specific context only — it must +never restate or fork them. + +## Quality Standard + + + +This is software for autonomous robot boats operating on open water. +Robustness is not optional. + +- Fix bugs completely: add the test, handle the edge case, check the + lifecycle transition. +- Concerns about error handling, silent failures, stale data, or missing + validation are not nits — flag them unless the failure mode genuinely + cannot occur. "Config is under our control" and "pathological input" are + not blanket dismissals; field configs change under pressure. +- A change includes its consequences: tests, documentation, and dependent + references update in the same PR. + +## Reviewing PRs + +- If the PR carries a work plan (`.agent/work-plans/issue-/plan.md` or a + plan in the PR body), the plan is kept **in sync with the implementation + as it evolves** — an implementation that matches the current plan text is + not "plan drift", even if the plan changed after the PR opened. +- Verify claims against source: parameters, topics, services, and message + types in docs must match the code. + +## Review Context — camp + +- CAMP is the operator-station GUI (Qt5 + rclcpp) for planning and + monitoring autonomous marine-vehicle missions. It is the operator's + window on a live boat: silently stale displays or dropped mission + commands are safety problems, not cosmetic ones. +- One package, three targets: the deployed `CCOMAutonomousMissionPlanner` + executable (`src/camp/`) plus the `camp_map` / `camp_map_ros` shared + libraries (`src/camp_map/`). The old `camp2` executable is retired. +- Long-running GUI process — resource lifecycle is a known risk area. + Watch cleanup paths for GDAL datasets, OpenGL objects, timers, and + background threads; destructors and disconnect paths deserve review. +- Tests are gtest and force `QT_QPA_PLATFORM=offscreen` themselves; + new GUI-touching tests must stay headless-safe. Default branch: `jazzy`. From 356eb1add1c0cdfb4c7d699ec778373f44fc1668 Mon Sep 17 00:00:00 2001 From: Claude Code Agent Date: Tue, 14 Jul 2026 16:20:02 -0400 Subject: [PATCH 2/2] docs: fix remaining stale no-CI claim in agent guide --- .agents/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.agents/README.md b/.agents/README.md index 5767648..2a88101 100644 --- a/.agents/README.md +++ b/.agents/README.md @@ -161,7 +161,8 @@ coverage of the Map model's insert/remove/reorder paths). Likewise ADR-0005 reset GGGS store persistence: the old `GggsStores/roots` key is ignored and cleared once on startup (not migrated) — stores re-added through the Stores tab persist as flat `GggsTileLayers/dirs`. -- **No CI / no pre-commit** — local build + gtest are the gate. +- **CI + pre-commit are configured** — GitHub Actions runs the colcon build + + gtest suite on PRs; pre-commit hooks guard formatting/config hygiene. ## Instructions for Use