Overview of the GitHub Actions CI/CD ecosystem for Apache Camel.
PR opened/updated
│
├──► pr-id.yml ──► pr-commenter.yml (welcome message)
│
├──► pr-build-main.yml (Build and test)
│ │
│ ├── regen.sh (full build, no tests)
│ ├── incremental-build (test affected modules)
│ │ ├── File-path analysis
│ │ ├── POM dependency analysis
│ │ └── Extra modules (/component-test)
│ │
│ └──► pr-test-commenter.yml (post unified comment)
│
└──► sonar-build.yml ──► sonar-scan.yml (SonarCloud analysis)
[currently disabled — INFRA-27808]
PR comment: /component-test kafka http
│
└──► pr-manual-component-test.yml
│
└── dispatches "Build and test" with extra_modules
pr-build-main.yml — Build and testpull_request (main branch), workflow_dispatchregen.sh (mvn install -DskipTests -Pregen)pr_number, pr_ref, extra_modules, skip_full_buildpr-test-commenter.yml — Post CI test commentworkflow_run on “Build and test” completionworkflow_run to run in base repo context, allowing comment posting on fork PRs (where GITHUB_TOKEN is read-only)pr-manual-component-test.yml — /component-test handlerissue_comment with /component-test prefixextra_modules and skip_full_build=true-Dquickly) of the requested modules and their dependencies instead of the full regen.sh buildpr-id.yml + pr-commenter.yml — Welcome messagepull_request (all branches)pr-id.yml runs in PR context (uploads PR number), pr-commenter.yml runs via workflow_run with write permissionsmain-build.yml — Main branch buildpush to main, camel-4.14.x, camel-4.18.xsonar-build.yml + sonar-scan.yml — SonarCloud PR analysispull_request (main branch) → workflow_run on SonarBuild completionsonar-build.yml runs in PR context (builds with JaCoCo coverage on core modules, uploads compiled classes artifact), sonar-scan.yml runs via workflow_run with secrets access to run the Sonar scanner and post resultscamel-api, camel-core, etc.) and coverage aggregator. Component coverage planned for future integration with incremental-build.sh module detectionpr-labeler.yml — Auto-labels PRs based on changed filespr-doc-validation.yml — Validates documentation changespr-cleanup-branches.yml — Cleans up merged PR branchesalternative-os-build-main.yml — Tests on non-Linux OSescheck-container-versions.yml — Checks test container version updatesgenerate-sbom-main.yml — Generates SBOM for releasessecurity-scan.yml — Security vulnerability scanningincremental-buildThe core test runner. Determines which modules to test using:
parent/pom.xml changes, detects property changes and finds modules that explicitly reference the affected properties via ${property} in their pom.xml files/component-testBoth detection methods run in parallel. Their results are merged (union), deduplicated, and tested. If Scalpel fails (build error, runtime error), the script falls back to grep-only with no regression.
The script also:
@DisabledIfSystemProperty(named = "ci.env.name"))manual-it-mapping.txt) and advises contributors to run them manuallyinstall-mvndInstalls the Maven Daemon (mvnd) for faster builds.
install-packagesInstalls system packages required for the build.
| Label | Effect |
|---|---|
skip-tests | Skip all tests |
test-dependents | Force testing dependent modules even if threshold exceeded |
The CI sets -Dci.env.name=github.com via MVND_OPTS (in install-mvnd). Tests can use @DisabledIfSystemProperty(named = "ci.env.name") to skip flaky tests in CI. The test comment warns about these skipped tests.
The grep approach searches for ${property-name} references in module pom.xml files. It has known limitations:
<version> — Modules inheriting versions via <dependencyManagement> without declaring <version>${property}</version> are missed.parent/pom.xml via <pluginManagement> are invisible to child modules.<dependencyManagement> edits without property substitution are not caught.Maveniverse Scalpel is a Maven core extension that compares effective POM models between the base branch and the PR. It resolves all 5 grep limitations by:
project.getBuildPlugins() comparisonScalpel runs in report mode (-Dscalpel.mode=report), writing a JSON report to target/scalpel-report.json without modifying the Maven reactor. The report includes affected modules with reasons (SOURCE_CHANGE, POM_CHANGE, TRANSITIVE_DEPENDENCY, MANAGED_PLUGIN).
Both methods run in parallel. Results are merged (union) before testing. This lets us:
Scalpel is configured permanently in .mvn/extensions.xml (version 0.1.0). On developer machines it is a no-op — without CI environment variables (GITHUB_BASE_REF), no base branch is detected and Scalpel returns immediately. The mvn validate with report mode adds ~60-90 seconds in CI.
Note: the script overrides fullBuildTriggers to empty (-Dscalpel.fullBuildTriggers=) because Scalpel's default (.mvn/**) would trigger a full build whenever .mvn/extensions.xml itself changes (e.g., Dependabot bumping Scalpel).
Some modules are excluded from CI's -amd expansion (the EXCLUSION_LIST) because they are generated code, meta-modules, or expensive integration test suites. When a contributor changes one of these modules, CI cannot automatically test all downstream effects.
The file manual-it-mapping.txt (co-located with the incremental build script) maps source modules to their associated integration test suites. When a changed module has a mapping entry, CI posts an advisory in the PR comment:
You modified
dsl/camel-jbang/camel-jbang-core. The related integration tests indsl/camel-jbang/camel-jbang-itare excluded from CI. Consider running them manually:mvn verify -f dsl/camel-jbang/camel-jbang-it -Djbang-it-test
To add new mappings, edit manual-it-mapping.txt using the format:
source-artifact-id:it-module-path:command
All non-experimental JDK matrix entries (17, 21) upload the CI comment artifact with overwrite: true. This ensures a comment is posted even if one JDK build fails. Since the comment content is identical across JDKs (same modules are tested regardless of JDK version), last writer wins.
PR comments use HTML markers for upsert (create-or-update) behavior:
<!-- ci-tested-modules --> — Unified test summary comment