This is an automated email from the ASF dual-hosted git repository.
jamesnetherton pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
The following commit(s) were added to refs/heads/main by this push:
new ac20afcc76 Add GitHub workflow to perform dependency convergence checks
ac20afcc76 is described below
commit ac20afcc763759019f8e47a92fa984d5e8251025
Author: James Netherton <[email protected]>
AuthorDate: Tue May 6 09:22:52 2025 +0100
Add GitHub workflow to perform dependency convergence checks
Fixes #5196
---
.github/workflows/check-dependency-convergence.yml | 177 +++++++++++++++++++++
.github/workflows/ci-build.yaml | 1 +
.github/workflows/pr-validate.yml | 1 +
tooling/scripts/create-superapp.groovy | 97 +++++++++++
4 files changed, 276 insertions(+)
diff --git a/.github/workflows/check-dependency-convergence.yml
b/.github/workflows/check-dependency-convergence.yml
new file mode 100644
index 0000000000..f6aa985ac3
--- /dev/null
+++ b/.github/workflows/check-dependency-convergence.yml
@@ -0,0 +1,177 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+name: Check Dependency Convergence
+
+on:
+ schedule:
+ # Run every sunday at 12PM
+ - cron: '0 12 * * 0'
+ workflow_dispatch:
+
+concurrency:
+ group: ${{ github.ref }}-${{ github.workflow }}
+ cancel-in-progress: true
+
+env:
+ LANG: en_US.UTF-8
+ MAVEN_OPTS: -Xmx3000m
+ CQ_MAVEN_ARGS: -V -ntp -e -Daether.connector.http.connectionMaxTtl=120
+ ISSUE_ID: 7348
+
+jobs:
+ check-dependency-convergence:
+ if: github.repository == 'apache/camel-quarkus'
+ runs-on: ubuntu-latest
+ permissions:
+ issues: write
+ steps:
+ - name: Set up JDK 17
+ uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 #
v4.7.1
+ with:
+ distribution: 'temurin'
+ java-version: '17'
+ - name: Checkout
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #
v4.2.2
+ - name: Set Build Info
+ run: |
+ [ ! -d ~/build-data ] && mkdir -p ~/build-data
+ echo "${{ github.run_id }}-${{ github.run_number }}-$(uuidgen)" >
~/build-data/build-id.txt
+ git rev-parse HEAD > ~/build-data/main-sha.txt
+ - name: Build Camel Quarkus
+ run: ./mvnw ${CQ_MAVEN_ARGS} clean install -Dquickly -T1C
+ - name: Install Groovy
+ run:
+ sudo apt install groovy --no-install-recommends -y
+ - name: Create Superapp
+ run: |
+ groovy tooling/scripts/create-superapp.groovy
+ - name: Run checks
+ run: |
+ # Copy maven wrapper
+ cp -r .mvn ${{ runner.temp }}/camel-quarkus-superapp/
+ cp ./mvnw ${{ runner.temp }}/camel-quarkus-superapp/
+
+ # Run dependency convergence checks
+ cd ${{ runner.temp }}/camel-quarkus-superapp/
+ ./mvnw ${CQ_MAVEN_ARGS} validate -Denforcer.fail=false | tee -a
enforcer.log
+ - name: Analyze Results
+ run: |
+ INPUT_FILE="${{ runner.temp }}/camel-quarkus-superapp/enforcer.log"
+ OUTPUT_FILE="${{ runner.temp
}}/camel-quarkus-superapp/enforcer-filtered.log"
+
+ # Clean up enforcer output
+ sed -i '1,/Failed while enforcing releasability./d' ${INPUT_FILE}
+
+ # List of Maven GAVs to ignore from the dependency convergence check
results. Keep sorted alphabetically
+ IGNORED_GAVS=(
+ # Mismatch between camel-quarkus-aws-xray &
camel-quarkus-aws2-kinesis
+ "com.amazonaws:aws-java-sdk-core"
+ # Mismatch between camel-quarkus-aws-xray &
camel-quarkus-aws2-kinesis
+ "com.amazonaws:jmespath-java"
+ # Mismatch between camel-quarkus-grpc & camel-quarkus-twilio
+ "com.auth0:java-jwt"
+ # Mismatch between camel-quarkus-cassandraql & camel-quarkus-web3j
+ "com.github.jnr:jnr-posix"
+ # Mismatch between camel-quarkus-google-bigquery,
camel-quarkus-google-functions, camel-quarkus-google-pubsub &
camel-quarkus-google-storage
+ "com.google.api-client:google-api-client"
+ # Mismatch between camel-quarkus-google-bigquery,
camel-quarkus-google-functions, camel-quarkus-google-pubsub &
camel-quarkus-google-storage
+ "com.google.api:api-common"
+ # Mismatch between camel-quarkus-google-bigquery,
camel-quarkus-google-functions, camel-quarkus-google-pubsub &
camel-quarkus-google-storage
+ "com.google.api:gax"
+ # Mismatch between camel-quarkus-google-bigquery,
camel-quarkus-google-functions, camel-quarkus-google-pubsub &
camel-quarkus-google-storage
+ "com.google.api:gax-grpc"
+ # Mismatch between camel-quarkus-google-bigquery,
camel-quarkus-google-functions, camel-quarkus-google-pubsub &
camel-quarkus-google-storage
+ "com.google.api.grpc:proto-google-iam-v1"
+ # Mismatch between camel-quarkus-couchdb &
camel-quarkus-ibm-secrets-manager
+ "com.ibm.cloud:sdk-core"
+ # Mismatch between camel-quarkus-cassandraql & camel-quarkus-dfdl
+ "com.typesafe:config"
+ # Mismatch between camel-quarkus-aws-datasonnet, camel-quarkus-djl
& camel-quarkus-aws2-kinesis
+ "io.github.classgraph:classgraph"
+ # Mismatch between camel-quarkus-csv, camel-quarkus-djl &
camel-quarkus-tika
+ "org.apache.commons:commons-csv"
+ # Mismatch between camel-quarkus-ldif, camel-quarkus-milvus,
camel-quarkus-netty & camel-quarkus-spring-redis
+ "org.apache.commons:commons-pool2"
+ # Mismatch between camel-quarkus-jsch, camel-quarkus-ldif &
camel-quarkus-quickfix
+ "org.apache.mina:mina-core"
+ # Mismatch between camel-quarkus-as2,
camel-quarkus-avro-deployment & camel-quarkus-cxf-soap-deployment
+ "org.apache.velocity:velocity-engine-core"
+ # Mismatch between camel-quarkus-jcr & camel-quarkus-tika
+ "org.apache.tika:tika-core"
+ # Mismatch between camel-quarkus-rest-openapi-deployment &
camel-quarkus-smallrye-reactive-messaging-deployment
+ "org.commonmark:commonmark"
+ # Mismatch between camel-quarkus-activemq & camel-quarkus-stomp
+ "org.fusesource.hawtbuf:hawtbuf"
+ # Mismatch between camel-quarkus-aws2-kinesis &
camel-quarkus-pubnub
+ "org.jetbrains.kotlinx:kotlinx-datetime-jvm"
+ # Mismatch between camel-quarkus-aws2-jgroups &
camel-quarkus-jgroups-raft
+ "org.jgroups:jgroups"
+ # Mismatch between camel-quarkus-box, camel-quarkus-oaipmh &
camel-quarkus-shiro
+ "org.jsoup:jsoup"
+ # Mismatch between camel-quarkus-jcr & camel-quarkus-lucene
+ "org.apache.lucene:lucene-core"
+ # Mismatch between camel-quarkus-flink, camel-quarkus-junit5,
camel-quarkus-nitrite & camel-quarkus-redis
+ "org.objenesis:objenesis"
+ )
+
+ BLOCK=""
+ IN_BLOCK=false
+ KEEP_BLOCK=true
+
+ # Filter out errors for ignored GAVs
+ while IFS= read -r LINE || [[ -n "${LINE}" ]]; do
+ if [[ "${LINE}" =~ ^Dependency\ convergence\ error\ for\
([^:]+:[^:]+): ]]; then
+ if ${IN_BLOCK} && ${KEEP_BLOCK}; then
+ echo "${BLOCK}" >> ${OUTPUT_FILE}
+ fi
+
+ BLOCK="${LINE}"
+ IN_BLOCK=true
+ KEEP_BLOCK=true
+ GAV="${BASH_REMATCH[1]}"
+
+ for IGNORED in "${IGNORED_GAVS[@]}"; do
+ if [[ "${GAV}" == "${IGNORED}" ]]; then
+ KEEP_BLOCK=false
+ break
+ fi
+ done
+ elif ${IN_BLOCK}; then
+ BLOCK+=$'\n'"${LINE}"
+ else
+ echo "${LINE}" >> ${OUTPUT_FILE}
+ fi
+ done < ${INPUT_FILE}
+
+ if ${IN_BLOCK} && ${KEEP_BLOCK}; then
+ echo "${BLOCK}" >> ${OUTPUT_FILE}
+ fi
+
+ # If after excluding ignored GAVs there are still convergence check
errors, fail the build
+ if grep "Dependency convergence error" ${OUTPUT_FILE} > /dev/null;
then
+ echo "There are dependency convergence errors!"
+ echo
+ cat ${OUTPUT_FILE}
+ echo
+ echo "Either fix the problem dependencies or add GAVs to the
IGNORED_GAVS list in check-dependency-convergence.yml"
+ exit 1
+ fi
+ - name: Report Build Failure
+ if: failure() || cancelled()
+ run: |
+ ./mvnw ${CQ_MAVEN_ARGS} verify -N -Pbuild-notification -Dstatus=${{
job.status }} -DissueId=${{ env.ISSUE_ID }} -Dtoken=${{ secrets.GITHUB_TOKEN }}
-DbuildId=$(cat ~/build-data/build-id.txt) -Drepo=${GITHUB_REPOSITORY}
-Dbranch=$(git rev-parse --abbrev-ref HEAD) -Dbranch-commit=$(cat
~/build-data/main-sha.txt)
diff --git a/.github/workflows/ci-build.yaml b/.github/workflows/ci-build.yaml
index 03e8569b2a..299b9f8b3b 100644
--- a/.github/workflows/ci-build.yaml
+++ b/.github/workflows/ci-build.yaml
@@ -39,6 +39,7 @@ on:
- '.github/workflows/assign-issue-milestone.yaml'
- '.github/workflows/assign-wontfix-issue-milestone.yaml'
- '.github/workflows/camel-master-cron.yaml'
+ - '.github/workflows/check-dependency-convergence.yml'
- '.github/workflows/generate-sbom-main.yml'
- '.github/workflows/label-issue.yaml'
- '.github/workflows/pr-validate.yml'
diff --git a/.github/workflows/pr-validate.yml
b/.github/workflows/pr-validate.yml
index 803de90937..80a2c0830b 100644
--- a/.github/workflows/pr-validate.yml
+++ b/.github/workflows/pr-validate.yml
@@ -38,6 +38,7 @@ on:
- '.github/workflows/assign-issue-milestone.yaml'
- '.github/workflows/assign-wontfix-issue-milestone.yaml'
- '.github/workflows/camel-master-cron.yaml'
+ - '.github/workflows/check-dependency-convergence.yml'
- '.github/workflows/generate-sbom-main.yml'
- '.github/workflows/label-issue.yaml'
- '.github/workflows/pr-validate.yml'
diff --git a/tooling/scripts/create-superapp.groovy
b/tooling/scripts/create-superapp.groovy
new file mode 100644
index 0000000000..c92f68761b
--- /dev/null
+++ b/tooling/scripts/create-superapp.groovy
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import groovy.xml.*
+
+def rootPom = new XmlParser().parse(new File('pom.xml'))
+def camelQuarkusVersion = rootPom.version.text()
+def quarkusVersion = rootPom.properties.'quarkus.version'?.text()
+def mavenEnforcerPluginVersion =
rootPom.properties.'maven-enforcer-plugin.version'?.text()
+
+// Get org.apache.camel.quarkus dependencies from camel-quarkus-bom
+def cqBomPath =
"${System.properties['user.home']}/.m2/repository/org/apache/camel/quarkus/camel-quarkus-bom/${camelQuarkusVersion}/camel-quarkus-bom-${camelQuarkusVersion}.pom"
+def bom = new XmlParser().parse(new File(cqBomPath))
+def cqBomDependencies =
bom.dependencyManagement.dependencies?.dependency?.findAll {
+ it.groupId.text().startsWith('org.apache.camel.quarkus') &&
!it.artifactId.text().contains("-support") &&
it.artifactId.text().endsWith('-deployment')
+}
+
+// Create a 'super' POM with all camel-quarkus-* dependencies
+def writer = new StringWriter()
+def xml = new MarkupBuilder(writer)
+
+xml.project(xmlns: "http://maven.apache.org/POM/4.0.0",
+ "xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
+ "xsi:schemaLocation": "http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd") {
+ modelVersion('4.0.0')
+ groupId('org.apache.camel.quarkus')
+ artifactId('camel-quarkus-superapp')
+ version(camelQuarkusVersion)
+ packaging('pom')
+ build {
+ plugins {
+ plugin {
+ groupId('org.apache.maven.plugins')
+ artifactId('maven-enforcer-plugin')
+ version(mavenEnforcerPluginVersion)
+ executions {
+ execution {
+ goals {
+ goal('enforce')
+ }
+ configuration {
+ rules {
+ dependencyConvergence()
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ dependencyManagement {
+ dependencies {
+ dependency{
+ groupId('io.quarkus')
+ artifactId('quarkus-bom')
+ version(quarkusVersion)
+ type('pom')
+ scope('import')
+ }
+ dependency{
+ groupId('org.apache.camel.quarkus')
+ artifactId('camel-quarkus-bom')
+ version(camelQuarkusVersion)
+ type('pom')
+ scope('import')
+ }
+ }
+ }
+ dependencies {
+ cqBomDependencies.each { dep ->
+ dependency {
+ groupId(dep.groupId.text())
+ artifactId(dep.artifactId.text().replace("-deployment", ""))
+ }
+ }
+ }
+}
+
+def tmp = System.getenv('RUNNER_TEMP')
+def superAppDir = new File("${tmp}/camel-quarkus-superapp")
+superAppDir.mkdirs()
+
+new File("${superAppDir}/pom.xml").text = writer.toString()