This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 255463d16ae6 Revert "chore(ci): Fix parent POM dependency change
detection (#22022)"
255463d16ae6 is described below
commit 255463d16ae65f24881a96fd04557460276bb6e1
Author: Guillaume Nodet <[email protected]>
AuthorDate: Thu Mar 26 16:45:09 2026 +0100
Revert "chore(ci): Fix parent POM dependency change detection (#22022)"
Reverts the detect-dependencies CI action back to its original
implementation. The reworked version was causing issues in CI.
A proper fix will be done in #22247.
---
.github/actions/detect-dependencies/action.yaml | 64 +---
.github/actions/detect-dependencies/detect-test.sh | 393 +++------------------
.github/workflows/pr-build-main.yml | 5 +-
3 files changed, 52 insertions(+), 410 deletions(-)
diff --git a/.github/actions/detect-dependencies/action.yaml
b/.github/actions/detect-dependencies/action.yaml
index e6334fc4d6b2..3db5cf5bcc70 100644
--- a/.github/actions/detect-dependencies/action.yaml
+++ b/.github/actions/detect-dependencies/action.yaml
@@ -21,17 +21,10 @@ inputs:
github-token:
description: 'The github token to access to the API'
required: false
- pr-id:
- description: 'Id of the pull request'
- required: true
- github-repo:
- description: 'The GitHub repository name (example, apache/camel)'
+ base-ref:
+ description: 'The base branch to compare against (defaults to
github.base_ref)'
required: false
- default: 'apache/camel'
- skip-mvnd-install:
- description: 'Skip mvnd installation (use if already installed)'
- required: false
- default: 'false'
+ default: ''
runs:
using: "composite"
steps:
@@ -42,54 +35,5 @@ runs:
- name: maven test
env:
GITHUB_TOKEN: ${{ inputs.github-token }}
- MVND_DIR: ${{ steps.install-mvnd.outputs.mvnd-dir }}
- PR_ID: ${{ inputs.pr-id }}
- GITHUB_REPO: ${{ inputs.github-repo }}
shell: bash
- run: ${{ github.action_path }}/detect-test.sh "$MVND_DIR/mvnd" "$PR_ID"
"$GITHUB_REPO"
- - name: Post dependency change comment
- if: always()
- uses: actions/github-script@v8
- with:
- github-token: ${{ inputs.github-token }}
- script: |
- const fs = require('fs');
- const commentFile = 'detect-dependencies-comment.md';
- if (!fs.existsSync(commentFile)) return;
- const body = fs.readFileSync(commentFile, 'utf8').trim();
- if (!body) return;
-
- const prNumber = ${{ inputs.pr-id || 0 }};
- if (!prNumber) {
- core.warning('Could not determine PR number, skipping dependency
comment');
- return;
- }
-
- const marker = '<!-- ci-parent-pom-deps -->';
-
- try {
- const { data: comments } = await github.rest.issues.listComments({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: prNumber,
- });
- const existing = comments.find(c => c.body &&
c.body.includes(marker));
-
- if (existing) {
- await github.rest.issues.updateComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- comment_id: existing.id,
- body: body,
- });
- } else {
- await github.rest.issues.createComment({
- owner: context.repo.owner,
- repo: context.repo.repo,
- issue_number: prNumber,
- body: body,
- });
- }
- } catch (error) {
- core.warning(`Failed to post dependency change comment:
${error.message}`);
- }
+ run: ${{ github.action_path }}/detect-test.sh ${{ inputs.base-ref ||
github.base_ref }} ${{ steps.install-mvnd.outputs.mvnd-dir }}/mvnd
diff --git a/.github/actions/detect-dependencies/detect-test.sh
b/.github/actions/detect-dependencies/detect-test.sh
index 2f55e1c2f918..dcdb3a9e218f 100755
--- a/.github/actions/detect-dependencies/detect-test.sh
+++ b/.github/actions/detect-dependencies/detect-test.sh
@@ -15,381 +15,82 @@
# limitations under the License.
#
-# Detects property changes in parent/pom.xml, maps them to the managed
-# artifacts that use those properties, then uses Maveniverse Toolbox to
-# find which modules depend on those artifacts (including transitive
-# dependencies) and runs their tests.
-#
-# Uses the GitHub API to fetch the PR diff (works with shallow clones).
-#
-# Approach:
-# 1. Fetch PR diff via GitHub API, extract parent/pom.xml changes
-# 2. Find changed property names from the diff
-# 3. Parse parent/pom.xml to map property -> groupId:artifactId
-# (detecting BOM imports vs regular dependencies)
-# 4. Use toolbox:tree-find to find all modules depending on those
-# artifacts (direct + transitive)
-# 5. Run tests for affected modules
-
set -euo pipefail
-MAX_MODULES=50
-TOOLBOX_PLUGIN="eu.maveniverse.maven.plugins:toolbox"
-
-# Fetch the PR diff from the GitHub API and extract only the parent/pom.xml
-# portion. Returns the unified diff for parent/pom.xml, or empty if not
changed.
-fetch_parent_pom_diff() {
- local pr_id="$1"
- local repository="$2"
-
- local diff_output
- diff_output=$(curl -s -w "\n%{http_code}" \
- -H "Authorization: Bearer ${GITHUB_TOKEN}" \
- -H "Accept: application/vnd.github.v3.diff" \
- "https://api.github.com/repos/${repository}/pulls/${pr_id}")
-
- local http_code
- http_code=$(echo "$diff_output" | tail -n 1)
- local diff_body
- diff_body=$(echo "$diff_output" | sed '$d')
-
- if [[ "$http_code" -lt 200 || "$http_code" -ge 300 || -z "$diff_body" ]];
then
- echo "WARNING: Failed to fetch PR diff (HTTP $http_code)" >&2
- return
- fi
-
- # Extract only the parent/pom.xml diff section
- echo "$diff_body" | awk '
- /^diff --git/ && found { exit }
- /^diff --git a\/parent\/pom.xml/ { found=1 }
- found { print }
- '
-}
-
-# Detect which properties changed in the parent/pom.xml diff.
-# Returns one property name per line.
detect_changed_properties() {
- local diff_content="$1"
+ local base_branch="$1"
- echo "$diff_content" | \
- grep -E '^[+-][[:space:]]*<[^>]+>[^<]*</[^>]+>' | \
- grep -vE '^\+\+\+|^---' | \
- sed -E 's/^[+-][[:space:]]*<([^>]+)>.*/\1/' | \
+ git diff "${base_branch}" -- parent/pom.xml | \
+ grep -E '^[+-]\s*<[^>]+>[^<]*</[^>]+>' | \
+ grep -vE '^\+\+\+|---' | \
+ grep -E 'version|dependency|artifact' | \
+ sed -E 's/^[+-]\s*<([^>]+)>.*/\1/' | \
sort -u || true
}
-# Given a property name, find which groupId:artifactId pairs in
-# parent/pom.xml use it as their <version>.
-# Also detects if the artifact is a BOM import (<type>pom</type> +
-# <scope>import</scope>), in which case it outputs "bom:groupId"
-# so the caller can search by groupId wildcard.
-# Returns one entry per line: either "groupId:artifactId" or "bom:groupId".
-find_gav_for_property() {
- local property="$1"
- local parent_pom="parent/pom.xml"
-
- local matches
- matches=$(grep -n "<version>\${${property}}</version>" "$parent_pom"
2>/dev/null || true)
-
- if [ -z "$matches" ]; then
- return
- fi
-
- echo "$matches" | while IFS=: read -r line_num _; do
- local block
- block=$(sed -n "1,${line_num}p" "$parent_pom")
- local artifactId
- artifactId=$(echo "$block" | grep '<artifactId>' | tail -1 | sed
's/.*<artifactId>\([^<]*\)<\/artifactId>.*/\1/')
- local groupId
- groupId=$(echo "$block" | grep '<groupId>' | tail -1 | sed
's/.*<groupId>\([^<]*\)<\/groupId>.*/\1/')
-
- # Check if this is a BOM import by looking at lines after the version
- local after_version
- after_version=$(sed -n "$((line_num+1)),$((line_num+3))p" "$parent_pom")
- if echo "$after_version" | grep -q '<type>pom</type>' && echo
"$after_version" | grep -q '<scope>import</scope>'; then
- echo "bom:${groupId}"
- else
- echo "${groupId}:${artifactId}"
+find_affected_modules() {
+ local property_name="$1"
+ local mavenBinary=${2}
+ local affected=()
+
+ while IFS= read -r pom; do
+ # skip any target that may have been built previously
+ if [[ "$pom" != */target/* ]]; then
+ # only consider certain modules, nothing else
+ if [[ "$pom" == */catalog/* ]] || \
+ [[ "$pom" == */components/* ]] || \
+ [[ "$pom" == */core/* ]] || \
+ ([[ "$pom" == */dsl/* ]] && [[ "$pom" != */dsl/camel-jbang* ]]); then
+ if grep -q "\${${property_name}}" "$pom"; then
+ affected+=("$pom")
+ fi
+ fi
fi
- done | sort -u
-}
-
-# Use Maveniverse Toolbox tree-find to discover all modules that depend
-# on a given artifact (including transitive dependencies).
-# Returns one module artifactId per line.
-find_modules_with_toolbox() {
- local mavenBinary="$1"
- local matcher_spec="$2"
- local search_pattern="$3"
+ done < <(find . -name "pom.xml")
- local output
- output=$($mavenBinary -B ${TOOLBOX_PLUGIN}:tree-find \
- -DartifactMatcherSpec="${matcher_spec}" 2>&1 || true)
+ affected_transformed=""
- if echo "$output" | grep -q 'BUILD FAILURE'; then
- echo " WARNING: toolbox tree-find failed, skipping" >&2
- return
- fi
+ for pom in "${affected[@]}"; do
+ if [[ -f "$pom" ]]; then
+ artifactId=$($mavenBinary -f "$pom" help:evaluate
-Dexpression=project.artifactId -q --raw-streams -DforceStdout)
+ if [ ! -z "$artifactId" ]; then
+ affected_transformed+=":$artifactId,"
+ fi
+ fi
+ done
- # Parse output: track current module from "Paths found in project" lines,
- # then when a dependency match is found, output that module's artifactId.
- # Note: mvnd strips [module] prefixes when output is captured to a
- # variable, so we track the current module from "Paths found" headers.
- echo "$output" | awk -v pattern="$search_pattern" '
- /Paths found in project/ {
- split($0, a, "project ")
- split(a[2], b, ":")
- current = b[2]
- }
- index($0, pattern) && /->/ {
- print current
- }
- ' | sort -u
+ echo "$affected_transformed"
}
main() {
echo "Using MVND_OPTS=$MVND_OPTS"
- local mavenBinary=${1}
- local prId=${2}
- local repository=${3}
- local log="detect-dependencies.log"
- local
exclusionList="!:camel-allcomponents,!:dummy-component,!:camel-catalog,!:camel-catalog-console,!:camel-catalog-lucene,!:camel-catalog-maven,!:camel-catalog-suggest,!:camel-route-parser,!:camel-csimple-maven-plugin,!:camel-report-maven-plugin,!:camel-endpointdsl,!:camel-componentdsl,!:camel-endpointdsl-support,!:camel-yaml-dsl,!:camel-kamelet-main,!:camel-yaml-dsl-deserializers,!:camel-yaml-dsl-maven-plugin,!:camel-jbang-core,!:camel-jbang-main,!:camel-jbang-plugin-generate,!:came
[...]
+ local base_branch=${1}
+ local mavenBinary=${2}
+ local
exclusionList="!:camel-allcomponents,!:dummy-component,!:camel-catalog,!:camel-catalog-console,!:camel-catalog-lucene,!:camel-catalog-maven,!:camel-catalog-suggest,!:camel-route-parser,!:camel-csimple-maven-plugin,!:camel-report-maven-plugin,!:camel-endpointdsl,!:camel-componentdsl,!:camel-endpointdsl-support,!:camel-yaml-dsl,!:camel-kamelet-main,!:camel-yaml-dsl-deserializers,!:camel-yaml-dsl-maven-plugin,!:camel-jbang-core,!:camel-jbang-main,!:camel-jbang-plugin-generate,!:came
[...]
- # Fetch diff via GitHub API (works with shallow clones)
- echo "Fetching PR #${prId} diff from GitHub API..."
- local parent_diff
- parent_diff=$(fetch_parent_pom_diff "$prId" "$repository")
+ git fetch origin $base_branch:$base_branch
- if [ -z "$parent_diff" ]; then
- echo "parent/pom.xml not changed, nothing to do"
- exit 0
- fi
-
- local changed_props
- changed_props=$(detect_changed_properties "$parent_diff")
+ changed_props=$(detect_changed_properties "$base_branch")
if [ -z "$changed_props" ]; then
- echo "No property changes detected in parent/pom.xml"
+ echo "โ
No property changes detected."
exit 0
fi
- echo "Changed properties in parent/pom.xml:"
- echo "$changed_props"
- echo ""
+ modules_affected=""
- # Map properties -> GAV coordinates for toolbox lookup
- # For properties not used in parent's dependencyManagement, fall back
- # to grepping for ${property} in module pom.xml files directly
- local all_gavs=""
- local fallback_props=""
while read -r prop; do
- [ -z "$prop" ] && continue
-
- local gavs
- gavs=$(find_gav_for_property "$prop")
- if [ -z "$gavs" ]; then
- echo " Property '$prop': not in dependencyManagement, will search
modules directly"
- fallback_props="${fallback_props:+${fallback_props}
-}${prop}"
- continue
- fi
-
- echo " Property '$prop' manages:"
- while read -r gav; do
- [ -z "$gav" ] && continue
- echo " - $gav"
- all_gavs="${all_gavs:+${all_gavs}
-}${gav}"
- done <<< "$gavs"
+ modules=$(find_affected_modules "$prop" $mavenBinary)
+ modules_affected+="$modules"
done <<< "$changed_props"
- if [ -z "$all_gavs" ] && [ -z "$fallback_props" ]; then
- echo ""
- echo "No managed artifacts found for changed properties"
+ if [ -z "$modules_affected" ]; then
+ echo "โ
No components affected by property changes detected."
exit 0
fi
- local all_module_ids=""
- local seen_modules=""
-
- # Step 1: Use Toolbox tree-find for properties with managed artifacts
- if [ -n "$all_gavs" ]; then
- echo ""
- echo "Searching for affected modules using Maveniverse Toolbox..."
-
- local unique_gavs
- unique_gavs=$(echo "$all_gavs" | sort -u)
-
- while read -r gav; do
- [ -z "$gav" ] && continue
-
- local matcher_spec search_pattern
- if [[ "$gav" == bom:* ]]; then
- # BOM import: search by groupId wildcard
- local groupId="${gav#bom:}"
- matcher_spec="artifact(${groupId}:*)"
- search_pattern="${groupId}:"
- echo " Searching for modules using ${groupId}:* (BOM)..."
- else
- matcher_spec="artifact(${gav})"
- search_pattern="${gav}"
- echo " Searching for modules using ${gav}..."
- fi
-
- local modules
- modules=$(find_modules_with_toolbox "$mavenBinary" "$matcher_spec"
"$search_pattern")
- if [ -n "$modules" ]; then
- while read -r mod; do
- [ -z "$mod" ] && continue
- if ! echo "$seen_modules" | grep -qx "$mod"; then
- seen_modules="${seen_modules:+${seen_modules}
-}${mod}"
- all_module_ids="${all_module_ids:+${all_module_ids},}:${mod}"
- fi
- done <<< "$modules"
- fi
- done <<< "$unique_gavs"
- fi
-
- # Step 2: Fallback for properties used directly in module pom.xml files
- # (not through parent's dependencyManagement)
- if [ -n "$fallback_props" ]; then
- echo ""
- echo "Searching for modules referencing properties directly..."
-
- while read -r prop; do
- [ -z "$prop" ] && continue
-
- local matches
- matches=$(grep -rl "\${${prop}}" --include="pom.xml" . 2>/dev/null | \
- grep -v "^\./parent/pom.xml" | \
- grep -v "/target/" | \
- grep -v "\.claude/worktrees" || true)
-
- if [ -n "$matches" ]; then
- echo " Property '\${${prop}}' referenced by:"
- while read -r pom_file; do
- [ -z "$pom_file" ] && continue
- # Extract artifactId from the module's pom.xml
- local mod_artifact
- mod_artifact=$(sed -n '/<parent>/,/<\/parent>/!{
s/.*<artifactId>\([^<]*\)<\/artifactId>.*/\1/p }' "$pom_file" | head -1)
- if [ -n "$mod_artifact" ] && ! echo "$seen_modules" | grep -qx
"$mod_artifact"; then
- echo " - $mod_artifact"
- seen_modules="${seen_modules:+${seen_modules}
-}${mod_artifact}"
-
all_module_ids="${all_module_ids:+${all_module_ids},}:${mod_artifact}"
- fi
- done <<< "$matches"
- fi
- done <<< "$fallback_props"
- fi
-
- if [ -z "$all_module_ids" ]; then
- echo ""
- echo "No modules depend on the changed artifacts"
- exit 0
- fi
-
- # Count modules
- local module_count
- module_count=$(echo "$all_module_ids" | tr ',' '\n' | wc -l | tr -d ' ')
-
- echo ""
- echo "Found ${module_count} modules affected by parent/pom.xml property
changes:"
- echo "$all_module_ids" | tr ',' '\n' | while read -r m; do
- echo " - $m"
- done
- echo ""
-
- if [ "${module_count}" -gt "${MAX_MODULES}" ]; then
- echo "Too many affected modules (${module_count} > ${MAX_MODULES}),
skipping targeted tests"
-
- write_comment "$changed_props" "$all_module_ids" "$module_count" "skip"
- exit 0
- fi
-
- # Filter out modules that are in the exclusion list
- local filtered_ids=""
- local IFS_backup="$IFS"
- IFS=','
- for mod_id in $all_module_ids; do
- if ! echo ",$exclusionList," | grep -q ",!${mod_id},"; then
- filtered_ids="${filtered_ids:+${filtered_ids},}${mod_id}"
- else
- echo " Skipping excluded module: $mod_id"
- fi
- done
- IFS="$IFS_backup"
-
- if [ -z "$filtered_ids" ]; then
- echo "All affected modules are in the exclusion list, skipping targeted
tests"
- write_comment "$changed_props" "$all_module_ids" "$module_count" "skip"
- exit 0
- fi
-
- echo "Running targeted tests for affected modules..."
- # Use install instead of test, otherwise test-infra modules fail due to
jandex maven plugin
- $mavenBinary -l $log $MVND_OPTS install -pl
"${filtered_ids},${exclusionList}" -amd
- local ret=$?
-
- if [ ${ret} -eq 0 ]; then
- write_comment "$changed_props" "$all_module_ids" "$module_count" "pass"
- else
- write_comment "$changed_props" "$all_module_ids" "$module_count" "fail"
- fi
-
- # Write step summary
- if [ -n "${GITHUB_STEP_SUMMARY:-}" ]; then
- echo "### Parent POM dependency change tests" >> "$GITHUB_STEP_SUMMARY"
- echo "" >> "$GITHUB_STEP_SUMMARY"
- echo "Changed properties: $(echo "$changed_props" | tr '\n' ', ' | sed
's/,$//')" >> "$GITHUB_STEP_SUMMARY"
- echo "" >> "$GITHUB_STEP_SUMMARY"
- echo "$all_module_ids" | tr ',' '\n' | while read -r m; do
- echo "- \`$m\`" >> "$GITHUB_STEP_SUMMARY"
- done
-
- if [ ${ret} -ne 0 ]; then
- echo "" >> "$GITHUB_STEP_SUMMARY"
- echo "Processing surefire and failsafe reports to create the summary" >>
"$GITHUB_STEP_SUMMARY"
- echo -e "| Failed Test | Duration | Failure Type |\n| --- | --- | --- |"
>> "$GITHUB_STEP_SUMMARY"
- find . -path '*target/*-reports*' -iname '*.txt' -exec
.github/actions/incremental-build/parse_errors.sh {} \;
- fi
- fi
-
- exit $ret
-}
-
-write_comment() {
- local changed_props="$1"
- local modules="$2"
- local module_count="$3"
- local status="$4"
- local comment_file="detect-dependencies-comment.md"
-
- echo "<!-- ci-parent-pom-deps -->" > "$comment_file"
-
- case "$status" in
- pass)
- echo ":white_check_mark: **Parent POM dependency changes: targeted tests
passed**" >> "$comment_file"
- ;;
- fail)
- echo ":x: **Parent POM dependency changes: targeted tests failed**" >>
"$comment_file"
- ;;
- skip)
- echo ":information_source: **Parent POM dependency changes detected**
but too many modules affected (${module_count}) to run targeted tests." >>
"$comment_file"
- ;;
- esac
-
- echo "" >> "$comment_file"
- echo "Changed properties: $(echo "$changed_props" | tr '\n' ', ' | sed
's/,$//')" >> "$comment_file"
- echo "" >> "$comment_file"
- echo "<details><summary>Affected modules (${module_count})</summary>" >>
"$comment_file"
- echo "" >> "$comment_file"
- echo "$modules" | tr ',' '\n' | while read -r m; do
- echo "- \`$m\`" >> "$comment_file"
- done
- echo "" >> "$comment_file"
- echo "</details>" >> "$comment_file"
+ echo "๐งช Testing the following modules $modules_affected and its dependents"
+ $mavenBinary $MVND_OPTS test -pl "$modules_affected$exclusionList" -amd
}
main "$@"
diff --git a/.github/workflows/pr-build-main.yml
b/.github/workflows/pr-build-main.yml
index fe32bbacbf7a..539a1250555c 100644
--- a/.github/workflows/pr-build-main.yml
+++ b/.github/workflows/pr-build-main.yml
@@ -143,10 +143,7 @@ jobs:
core.warning(`Failed to post CI test summary comment:
${error.message}`);
}
- name: mvn test parent pom dependencies changed
- if: always() && !matrix.experimental
uses: ./.github/actions/detect-dependencies
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- pr-id: ${{ github.event.number || inputs.pr_number }}
- github-repo: ${{ github.repository }}
- skip-mvnd-install: 'true'
+ base-ref: ${{ github.base_ref || 'main' }}