diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 57901c7aa1..14e6f86b5e 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -93,10 +93,10 @@ jobs: chmod +x third-party/thrift/install-thrift.sh DESTDIR=${{ github.workspace }}/dist/thrift-${{ env.THRIFT_VERSION }} third-party/thrift/install-thrift.sh - - name: Build SW360 + - name: Build SW360 with Tests and Coverage run: | export PATH=$PATH:${{ github.workspace }}/dist/thrift-${{ env.THRIFT_VERSION }}/usr/local/bin - mvn clean install \ + mvn clean verify \ --no-transfer-progress \ -P deploy -Dhelp-docs=true \ -Dbase.deploy.dir=. \ @@ -109,6 +109,123 @@ jobs: -fae \ -Dmaven.plugin.validation=VERBOSE + - name: Generate Coverage Reports + run: | + mvn jacoco:report-aggregate + + - name: Parse Coverage Percentage + id: coverage + run: | + if [ -f "./target/site/jacoco-aggregate/jacoco.xml" ]; then + # Extract coverage percentage from XML + COVERAGE=$(grep -o 'line-rate="[^"]*"' ./target/site/jacoco-aggregate/jacoco.xml | head -1 | cut -d'"' -f2) + if [ ! -z "$COVERAGE" ]; then + COVERAGE_PCT=$(echo "$COVERAGE * 100" | bc -l | cut -c1-5) + echo "coverage=$COVERAGE_PCT" >> $GITHUB_OUTPUT + echo "✅ Coverage percentage extracted: ${COVERAGE_PCT}%" + else + echo "coverage=0" >> $GITHUB_OUTPUT + echo "⚠️ Could not extract coverage percentage" + fi + else + echo "coverage=0" >> $GITHUB_OUTPUT + echo "❌ Coverage report not found" + exit 1 + fi + + - name: Display Test and Coverage Summary + run: | + echo "=== TEST EXECUTION SUMMARY ===" + echo "✅ Unit Tests (UTs) executed from:" + echo " • backend/ (all modules)" + echo " • libraries/ (datahandler, importers, exporters, etc.)" + echo " • clients/ (client, http-support)" + echo " • keycloak/ (event-listeners, user-storage-provider)" + echo "" + echo "✅ Integration Tests (ITs) executed from:" + echo " • rest/resource-server/ (all integration tests)" + echo "" + echo "=== COVERAGE SUMMARY ===" + echo "📊 Overall Code Coverage: ${{ steps.coverage.outputs.coverage }}%" + echo "📁 Coverage reports available in:" + echo " • Combined: ./target/site/jacoco-aggregate/" + echo " • Individual: */target/site/jacoco/" + + - name: Upload Coverage Artifacts + uses: actions/upload-artifact@v4 + with: + name: coverage-reports + path: | + target/site/jacoco-aggregate/ + */target/site/jacoco/ + retention-days: 30 + + - name: Comment Coverage in PR + uses: romeovs/lcov-reporter-action@v0.3.1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + lcov-file: ./target/site/jacoco-aggregate/jacoco.xml + filter-changed-files: false + delete-old-comments: false + continue-on-error: true + + - name: Create Coverage Summary Comment + if: github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const coverage = '${{ steps.coverage.outputs.coverage }}'; + const comment = `## 📊 SW360 Test Coverage Report + + ### ✅ Test Execution Summary + **Unit Tests (UTs) executed from:** + - \`backend/\` (all modules) + - \`libraries/\` (datahandler, importers, exporters, etc.) + - \`clients/\` (client, http-support) + - \`keycloak/\` (event-listeners, user-storage-provider) + + **Integration Tests (ITs) executed from:** + - \`rest/resource-server/\` (all integration tests) + + ### 📈 Coverage Results + **Overall Code Coverage: ${coverage}%** + + ### 📁 Coverage Reports Available + - **Combined Report**: \`target/site/jacoco-aggregate/\` + - **Individual Reports**: \`*/target/site/jacoco/\` + - **Download**: Available in Actions → Artifacts → coverage-reports + + --- + *Generated automatically by SW360 CI/CD pipeline*`; + + // Delete previous coverage comments + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number + }); + + const coverageComments = comments.filter(comment => + comment.body.includes('SW360 Test Coverage Report') + ); + + for (const comment of coverageComments) { + await github.rest.issues.deleteComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: comment.id + }); + } + + // Add new coverage comment + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: comment + }); + - name: Run PrivateProjectAccessTest run: | mvn install -pl :build-configuration -am -Dbase.deploy.dir=. diff --git a/pom.xml b/pom.xml index 0d0c394dd1..4111a559b6 100644 --- a/pom.xml +++ b/pom.xml @@ -647,20 +647,28 @@ org/apache/ws/commons/schema/** - - - - prepare-agent - - - - report - - report - - prepare-package - - + + + + prepare-agent + + + + report + + report + + prepare-package + + + + aggregate + + report-aggregate + + verify + + org.apache.maven.plugins diff --git a/rest/resource-server/pom.xml b/rest/resource-server/pom.xml index a7868ab25a..f0bff6816d 100644 --- a/rest/resource-server/pom.xml +++ b/rest/resource-server/pom.xml @@ -305,6 +305,31 @@ + + + + org.apache.maven.plugins + maven-failsafe-plugin + ${maven-failsafe-plugin.version} + + + integration-tests + + integration-test + verify + + + false + + **/*IT.java + **/*Test.java + + + **/TestIntegrationBase.java + + + +