This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch detect-dependencies-fix
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 4f25c099dfea43f31d98ac93401502a271baf5bc
Author: Guillaume Nodet <[email protected]>
AuthorDate: Mon Mar 16 09:39:19 2026 +0100

    chore(ci): Fix parent POM dependency change detection
    
    The detect-dependencies action was not finding affected modules because
    it searched for ${property-name} references in module pom.xml files.
    This never matches because modules inherit managed versions from the
    parent without referencing the property directly.
    
    New approach:
    1. Detect changed properties in parent/pom.xml diff
    2. Map each property to the artifact(s) it versions in dependencyManagement
    3. Find modules that depend on those artifacts by searching for artifactId
    4. Run tests for affected modules
    
    Also adds:
    - PR comment posting with test results summary
    - Step summary output
    - Proper skip-mvnd-install input in action.yaml
    - Run only on non-experimental matrix (skip JDK 25)
    - Remove overly restrictive version|dependency|artifact filter
    
    Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
 .github/actions/detect-dependencies/action.yaml    |  50 +++++
 .github/actions/detect-dependencies/detect-test.sh | 230 +++++++++++++++++----
 .github/workflows/pr-build-main.yml                |   2 +
 3 files changed, 240 insertions(+), 42 deletions(-)

diff --git a/.github/actions/detect-dependencies/action.yaml 
b/.github/actions/detect-dependencies/action.yaml
index 3db5cf5bcc70..92745a7c3514 100644
--- a/.github/actions/detect-dependencies/action.yaml
+++ b/.github/actions/detect-dependencies/action.yaml
@@ -25,6 +25,10 @@ inputs:
     description: 'The base branch to compare against (defaults to 
github.base_ref)'
     required: false
     default: ''
+  skip-mvnd-install:
+    description: 'Skip mvnd installation (use if already installed)'
+    required: false
+    default: 'false'
 runs:
   using: "composite"
   steps:
@@ -37,3 +41,49 @@ runs:
         GITHUB_TOKEN: ${{ inputs.github-token }}
       shell: bash
       run: ${{ github.action_path }}/detect-test.sh ${{ inputs.base-ref || 
github.base_ref }} ${{ steps.install-mvnd.outputs.mvnd-dir }}/mvnd
+    - 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 = context.issue.number;
+          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}`);
+          }
diff --git a/.github/actions/detect-dependencies/detect-test.sh 
b/.github/actions/detect-dependencies/detect-test.sh
index dcdb3a9e218f..b7b4806d6251 100755
--- a/.github/actions/detect-dependencies/detect-test.sh
+++ b/.github/actions/detect-dependencies/detect-test.sh
@@ -15,82 +15,228 @@
 # limitations under the License.
 #
 
+# Detects property changes in parent/pom.xml, maps them to the managed
+# artifacts that use those properties, then finds which modules depend
+# on those artifacts and runs their tests.
+#
+# Previous approach searched for ${property-name} in module pom.xml files,
+# but that never matches because modules inherit managed versions from the
+# parent without referencing the property directly.
+#
+# New approach:
+#   1. Diff parent/pom.xml to find changed property names
+#   2. Parse parent/pom.xml to map property -> artifactId(s)
+#   3. Search module pom.xml files for those artifactIds
+#   4. Run tests for affected modules
+
 set -euo pipefail
 
+MAX_MODULES=50
+
+# Detect which properties changed in parent/pom.xml compared to the base 
branch.
+# Returns one property name per line.
 detect_changed_properties() {
   local base_branch="$1"
 
   git diff "${base_branch}" -- parent/pom.xml | \
     grep -E '^[+-]\s*<[^>]+>[^<]*</[^>]+>' | \
-    grep -vE '^\+\+\+|---' | \
-    grep -E 'version|dependency|artifact' | \
+    grep -vE '^\+\+\+|^---' | \
     sed -E 's/^[+-]\s*<([^>]+)>.*/\1/' | \
     sort -u || true
 }
 
-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 < <(find . -name "pom.xml")
-
-  affected_transformed=""
-
-  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
+# Given a property name, find which artifactIds in parent/pom.xml use it
+# as their <version>. Looks for patterns like:
+#   <artifactId>some-artifact</artifactId>
+#   <version>${property-name}</version>
+# Returns one artifactId per line.
+find_artifacts_for_property() {
+  local property="$1"
+  local parent_pom="parent/pom.xml"
+
+  # Find line numbers where <version>${property}</version> appears
+  grep -n "<version>\${${property}}</version>" "$parent_pom" 2>/dev/null | \
+    while IFS=: read -r line_num _; do
+      # Search backwards from that line for the nearest <artifactId>
+      sed -n "1,${line_num}p" "$parent_pom" | \
+        grep '<artifactId>' | tail -1 | \
+        sed 's/.*<artifactId>\([^<]*\)<\/artifactId>.*/\1/'
+    done | sort -u
+}
 
-  echo "$affected_transformed"
+# Given an artifactId, find which module pom.xml files reference it
+# (as a dependency, not just in exclusions or comments).
+# Returns module directories, one per line.
+find_modules_using_artifact() {
+  local artifact="$1"
+  local modules=()
+
+  # Search for <artifactId>artifact</artifactId> in pom.xml files
+  # Exclude parent/pom.xml, target dirs, and worktrees
+  grep -rl "<artifactId>${artifact}</artifactId>" --include="pom.xml" . 
2>/dev/null | \
+    grep -v "^\./parent/pom.xml" | \
+    grep -v "/target/" | \
+    grep -v "\.claude/worktrees" | \
+    while read -r pom_file; do
+      # Verify it's actually a dependency reference (not just an exclusion)
+      # by checking that <artifactId>artifact</artifactId> appears inside a
+      # <dependency> block (not only inside an <exclusion> block).
+      # Simple heuristic: if the artifact appears, the module is likely 
affected.
+      # Exclusion-only references are rare enough that false positives are 
acceptable.
+      dirname "$pom_file" | sed 's|^\./||'
+    done | sort -u
 }
 
 main() {
   echo "Using MVND_OPTS=$MVND_OPTS"
   local base_branch=${1}
   local mavenBinary=${2}
+  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
 [...]
 
-  git fetch origin $base_branch:$base_branch
+  git fetch origin "$base_branch":"$base_branch" 2>/dev/null || true
 
+  # Check if parent/pom.xml was actually changed
+  if ! git diff --name-only "${base_branch}" -- parent/pom.xml | grep -q .; 
then
+    echo "parent/pom.xml not changed, nothing to do"
+    exit 0
+  fi
+
+  local changed_props
   changed_props=$(detect_changed_properties "$base_branch")
 
   if [ -z "$changed_props" ]; then
-    echo "โœ… No property changes detected."
+    echo "No property changes detected in parent/pom.xml"
     exit 0
   fi
 
-  modules_affected=""
+  echo "Changed properties in parent/pom.xml:"
+  echo "$changed_props"
+  echo ""
+
+  # Map properties -> artifacts -> modules
+  local all_artifacts=""
+  local all_modules=""
+  local seen_modules=""
 
   while read -r prop; do
-    modules=$(find_affected_modules "$prop" $mavenBinary)
-    modules_affected+="$modules"
+    [ -z "$prop" ] && continue
+
+    local artifacts
+    artifacts=$(find_artifacts_for_property "$prop")
+    if [ -z "$artifacts" ]; then
+      echo "  Property '$prop': no managed artifacts found"
+      continue
+    fi
+
+    echo "  Property '$prop' manages:"
+    while read -r artifact; do
+      [ -z "$artifact" ] && continue
+      echo "    - $artifact"
+      all_artifacts="${all_artifacts:+${all_artifacts},}${artifact}"
+
+      local modules
+      modules=$(find_modules_using_artifact "$artifact")
+      if [ -n "$modules" ]; then
+        while read -r mod; do
+          [ -z "$mod" ] && continue
+          # Deduplicate
+          if ! echo "$seen_modules" | grep -qx "$mod"; then
+            seen_modules="${seen_modules:+${seen_modules}
+}${mod}"
+            all_modules="${all_modules:+${all_modules},}${mod}"
+          fi
+        done <<< "$modules"
+      fi
+    done <<< "$artifacts"
   done <<< "$changed_props"
 
-  if [ -z "$modules_affected" ]; then
-    echo "โœ… No components affected by property changes detected."
+  if [ -z "$all_modules" ]; then
+    echo ""
+    echo "No modules reference the changed artifacts"
+    exit 0
+  fi
+
+  # Count modules
+  local module_count
+  module_count=$(echo "$all_modules" | tr ',' '\n' | wc -l | tr -d ' ')
+
+  echo ""
+  echo "Found ${module_count} modules affected by parent/pom.xml property 
changes:"
+  echo "$all_modules" | 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_modules" "$module_count" "skip"
     exit 0
   fi
 
-  echo "๐Ÿงช Testing the following modules $modules_affected and its dependents"
-  $mavenBinary $MVND_OPTS test -pl "$modules_affected$exclusionList" -amd
+  echo "Running targeted tests for affected modules..."
+  $mavenBinary -l $log $MVND_OPTS test -pl "$all_modules" -am -pl 
"$exclusionList"
+  local ret=$?
+
+  if [ ${ret} -eq 0 ]; then
+    write_comment "$changed_props" "$all_modules" "$module_count" "pass"
+  else
+    write_comment "$changed_props" "$all_modules" "$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_modules" | 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>Tested 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"
 }
 
 main "$@"
diff --git a/.github/workflows/pr-build-main.yml 
b/.github/workflows/pr-build-main.yml
index 8d46b8376673..cedc8fceb5f6 100644
--- a/.github/workflows/pr-build-main.yml
+++ b/.github/workflows/pr-build-main.yml
@@ -143,7 +143,9 @@ 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 }}
           base-ref: ${{ github.base_ref || 'main' }}
+          skip-mvnd-install: 'true'

Reply via email to