diff --git a/.github/scripts/enable-spotbugs-for-changed-modules.sh b/.github/scripts/enable-spotbugs-for-changed-modules.sh new file mode 100644 index 0000000000..92ee6b85a1 --- /dev/null +++ b/.github/scripts/enable-spotbugs-for-changed-modules.sh @@ -0,0 +1,59 @@ +#!/bin/bash +set -e + +# This script enables SpotBugs only for modules that have changed files + +BASE_SHA="$1" + +if [ -z "$BASE_SHA" ]; then + echo "Usage: $0 " + echo "Enabling SpotBugs for ALL modules (no base SHA provided)" + exit 0 +fi + +# Get list of changed files +CHANGED_FILES=$(git diff --name-only "$BASE_SHA" HEAD) + +# Extract unique module directories (top-level dirs with pom.xml or META-INF/MANIFEST.MF) +CHANGED_MODULES=$(echo "$CHANGED_FILES" | grep -E '^[^/]+/' | cut -d'/' -f1 | sort -u) + +echo "Detecting changed modules..." +MODULE_COUNT=0 + +for dir in $CHANGED_MODULES; do + # Check if this is a module directory + if [ -f "$dir/pom.xml" ]; then + echo " - $dir" + + # Add spotbugs.skip=false property to this module's pom.xml + # Check if pom.xml already has a section + if grep -q "" "$dir/pom.xml"; then + # Insert after opening tag + sed -i '//a\ + false' "$dir/pom.xml" + else + # Insert new section after or + sed -i '/eclipse-plugin<\/packaging>/a\ + \ + false\ + ' "$dir/pom.xml" + fi + + MODULE_COUNT=$((MODULE_COUNT + 1)) + + elif [ -f "$dir/META-INF/MANIFEST.MF" ]; then + echo " - $dir (MANIFEST only, checking for pom.xml)" + # Some modules might only have MANIFEST.MF, check if pom exists + if [ ! -f "$dir/pom.xml" ]; then + echo " Warning: $dir has no pom.xml, skipping SpotBugs" + fi + fi +done + +if [ $MODULE_COUNT -eq 0 ]; then + echo "No modules with pom.xml files were changed" + echo "SpotBugs will be skipped for all modules" +else + echo "" + echo "Enabled SpotBugs for $MODULE_COUNT module(s)" +fi diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index afb7b98dd0..f1dc3ae8ad 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -1,52 +1,180 @@ -name: verify -on: - push: - branches: [master] - pull_request: -jobs: - pmd: - runs-on: ubuntu-22.04 - steps: - - uses: actions/checkout@v5 - - uses: actions/setup-java@v5 - with: - distribution: 'temurin' - java-version: '21' - - name: PMD - uses: pmd/pmd-github-action@v2.0.0 - id: pmd - with: - version: '7.17.0' - rulesets: 'ddk-configuration/pmd/ruleset.xml' - analyzeModifiedFilesOnly: false - - name: Fail build if there are violations - if: steps.pmd.outputs.violations != 0 - run: exit 1 - maven-verify: - runs-on: ubuntu-22.04 - steps: - - name: Set up Maven - uses: stCarolas/setup-maven@v5 - with: - maven-version: 3.9.11 - - uses: actions/checkout@v5 - - name: Set up JDK 21 - uses: actions/setup-java@v5 - with: - distribution: 'temurin' - java-version: '21' - - name: Set up Workspace Enviroment Variable - run: echo "WORKSPACE=${{ github.workspace }}" >> $GITHUB_ENV - - name: Cache Maven dependencies - uses: actions/cache@v4 - with: - path: /home/runner/.m2/repository - key: ${{ runner.os }}-maven-0-${{ hashFiles('**/pom.xml') }} - - name: Build with Maven within a virtual X Server Environment - run: xvfb-run mvn clean verify checkstyle:check pmd:pmd pmd:check pmd:cpd-check spotbugs:check -f ./ddk-parent/pom.xml --batch-mode --fail-at-end - - name: Archive Tycho Surefire Plugin - if: ${{ failure() }} - uses: actions/upload-artifact@v4 - with: - name: tycho-surefire-plugin - path: ${{ env.GITHUB_WORKSPACE }}/com.avaloq.tools.ddk.xtext.test/target/work/data/.metadata/.log +name: verify +on: + push: + branches: [master] + pull_request: + +jobs: + # Job 1: PMD (runs independently and in parallel) + pmd: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v5 + - uses: actions/setup-java@v5 + with: + distribution: 'temurin' + java-version: '21' + - name: PMD + uses: pmd/pmd-github-action@v2.0.0 + id: pmd + with: + version: '7.17.0' + rulesets: 'ddk-configuration/pmd/ruleset.xml' + analyzeModifiedFilesOnly: false + - name: Fail build if there are violations + if: steps.pmd.outputs.violations != 0 + run: exit 1 + + # Job 2: Code Quality Checks (runs in parallel with PMD) + code-quality: + runs-on: ubuntu-24.04 + steps: + - name: Set up Maven + uses: stCarolas/setup-maven@v5 + with: + maven-version: 3.9.11 + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - name: Set up JDK 21 + uses: actions/setup-java@v5 + with: + distribution: 'temurin' + java-version: '21' + - name: Set up Workspace Environment Variable + run: echo "WORKSPACE=${{ github.workspace }}" >> $GITHUB_ENV + - name: Cache Maven dependencies + uses: actions/cache@v4 + with: + path: /home/runner/.m2/repository + key: ${{ runner.os }}-maven-0-${{ hashFiles('**/pom.xml') }} + - name: Run checkstyle, pmd, and cpd + # Run pmd:pmd and pmd:cpd first to generate reports for all modules, then run pmd:check and pmd:cpd-check + # This ensures all violations are collected and reported before the build fails + run: mvn -T 1.5C checkstyle:check pmd:pmd pmd:cpd pmd:check pmd:cpd-check -f ./ddk-parent/pom.xml --batch-mode --fail-at-end + + # Job 3: Compile and install (produces artifacts for verify and spotbugs) + compile: + runs-on: ubuntu-24.04 + steps: + - name: Set up Maven + uses: stCarolas/setup-maven@v5 + with: + maven-version: 3.9.11 + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - name: Set up JDK 21 + uses: actions/setup-java@v5 + with: + distribution: 'temurin' + java-version: '21' + - name: Set up Workspace Environment Variable + run: echo "WORKSPACE=${{ github.workspace }}" >> $GITHUB_ENV + - name: Cache Maven dependencies + uses: actions/cache@v4 + with: + path: /home/runner/.m2/repository + key: ${{ runner.os }}-maven-0-${{ hashFiles('**/pom.xml') }} + - name: Compile and install all modules + run: mvn -T 1.5C clean install -f ./ddk-parent/pom.xml --batch-mode -DskipTests + - name: Upload installed module JARs + uses: actions/upload-artifact@v4 + with: + name: installed-jars + path: /home/runner/.m2/repository/com/avaloq/tools/ddk/ + retention-days: 1 + - name: Upload compiled target directories + uses: actions/upload-artifact@v4 + with: + name: target-dirs + path: | + **/target/classes + **/target/test-classes + **/target/*.jar + retention-days: 1 + + # Job 4: Maven verify (runs tests) + maven-verify: + runs-on: ubuntu-24.04 + needs: compile + steps: + - name: Set up Maven + uses: stCarolas/setup-maven@v5 + with: + maven-version: 3.9.11 + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - name: Set up JDK 21 + uses: actions/setup-java@v5 + with: + distribution: 'temurin' + java-version: '21' + - name: Set up Workspace Environment Variable + run: echo "WORKSPACE=${{ github.workspace }}" >> $GITHUB_ENV + - name: Cache Maven dependencies + uses: actions/cache@v4 + with: + path: /home/runner/.m2/repository + key: ${{ runner.os }}-maven-0-${{ hashFiles('**/pom.xml') }} + - name: Download installed module JARs + uses: actions/download-artifact@v4 + with: + name: installed-jars + path: /home/runner/.m2/repository/com/avaloq/tools/ddk/ + - name: Download compiled target directories + uses: actions/download-artifact@v4 + with: + name: target-dirs + path: . + - name: Run tests with Maven within a virtual X Server Environment + run: xvfb-run mvn -T 1.5C verify -f ./ddk-parent/pom.xml --batch-mode --fail-at-end + + # Job 5: SpotBugs + spotbugs: + runs-on: ubuntu-24.04 + needs: compile + steps: + - name: Set up Maven + uses: stCarolas/setup-maven@v5 + with: + maven-version: 3.9.11 + - uses: actions/checkout@v5 + with: + fetch-depth: 0 + - name: Set up JDK 21 + uses: actions/setup-java@v5 + with: + distribution: 'temurin' + java-version: '21' + - name: Set up Workspace Environment Variable + run: echo "WORKSPACE=${{ github.workspace }}" >> $GITHUB_ENV + - name: Cache Maven dependencies + uses: actions/cache@v4 + with: + path: /home/runner/.m2/repository + key: ${{ runner.os }}-maven-0-${{ hashFiles('**/pom.xml') }} + - name: Download installed module JARs + uses: actions/download-artifact@v4 + with: + name: installed-jars + path: /home/runner/.m2/repository/com/avaloq/tools/ddk/ + - name: Download compiled target directories + uses: actions/download-artifact@v4 + with: + name: target-dirs + path: . + - name: Enable SpotBugs for changed modules (PR only) + if: github.event_name == 'pull_request' + run: | + chmod +x .github/scripts/enable-spotbugs-for-changed-modules.sh + .github/scripts/enable-spotbugs-for-changed-modules.sh "${{ github.event.pull_request.base.sha }}" + - name: Enable SpotBugs for all modules (push to master) + if: github.event_name == 'push' + run: | + echo "Running SpotBugs on all modules (push to master)" + # Set spotbugs.skip=false in parent POM + sed -i 's/true<\/spotbugs.skip>/false<\/spotbugs.skip>/' ddk-parent/pom.xml + - name: Run SpotBugs + run: mvn -T 1.5C spotbugs:check -f ./ddk-parent/pom.xml --batch-mode --fail-at-end diff --git a/com.avaloq.tools.ddk.xtext.generator/src/com/avaloq/tools/ddk/xtext/generator/util/ModelValidator.java b/com.avaloq.tools.ddk.xtext.generator/src/com/avaloq/tools/ddk/xtext/generator/util/ModelValidator.java index f4f68292ea..6b4c3d552f 100644 --- a/com.avaloq.tools.ddk.xtext.generator/src/com/avaloq/tools/ddk/xtext/generator/util/ModelValidator.java +++ b/com.avaloq.tools.ddk.xtext.generator/src/com/avaloq/tools/ddk/xtext/generator/util/ModelValidator.java @@ -65,6 +65,7 @@ public List validate(final Resource resource, final Logger logger) { * @param logger * the logger */ + @SuppressWarnings("PMD.UnnecessaryVarargsArrayCreation") private void logIssue(final Resource resource, final Issue issue, final Logger logger) { final String message = NLS.bind(MESSAGE_TEMPLATE, new Object[] {resource.getURI().lastSegment(), issue.getLineNumber(), issue.getMessage()}); final Severity severity = issue.getSeverity(); diff --git a/ddk-parent/pom.xml b/ddk-parent/pom.xml index ecb5b27a4f..a28bffef74 100644 --- a/ddk-parent/pom.xml +++ b/ddk-parent/pom.xml @@ -36,6 +36,7 @@ ${workspace}/ddk-configuration/checkstyle/avaloq-test.xml ${workspace}/ddk-configuration/findbugs/exclusion-filter.xml 2048 + true ${runtime.javaOptions} @@ -308,6 +309,9 @@ ${pmd.ruleset} + + ${basedir}/src + ${basedir}/src-gen ${basedir}/src-model @@ -351,12 +355,12 @@ + ${spotbugs.skip} true ${spotbugs.maxHeap} 15 Low ${spotbugs.excludeFilterFile} - 1024