diff --git a/.github/quality-gates.json b/.github/quality-gates.json new file mode 100644 index 00000000..d8c9fb84 --- /dev/null +++ b/.github/quality-gates.json @@ -0,0 +1,32 @@ +{ + "qualityGates": [ + { + "metric": "tests-success-rate", + "name": "Tests Success Rate", + "threshold": 100.0, + "criticality": "FAILURE" + }, + { + "metric": "line", + "threshold": 80.0, + "criticality": "UNSTABLE" + }, + { + "metric": "branch", + "threshold": 75.0, + "criticality": "UNSTABLE" + }, + { + "metric": "bugs", + "name": "Potential Bugs", + "threshold": 0.0, + "criticality": "FAILURE" + }, + { + "metric": "style", + "name": "Style Violations", + "threshold": 0.0, + "criticality": "FAILURE" + } + ] +} diff --git a/.github/quality-monitor.json b/.github/quality-monitor.json new file mode 100644 index 00000000..be7ec105 --- /dev/null +++ b/.github/quality-monitor.json @@ -0,0 +1,145 @@ +{ + "tests": { + "name": "Tests", + "tools": [ + { + "id": "junit", + "name": "Unit Tests", + "pattern": "**/target/surefire-reports/TEST*forensics*.xml" + }, + { + "id": "junit", + "icon": "rocket", + "name": "Integration Tests", + "pattern": "**/target/failsafe-reports/TEST*.xml" + }, + { + "id": "junit", + "icon": "no_entry", + "name": "Architecture Tests", + "pattern": "**/target/surefire-reports/TEST*archunit*.xml" + } + ] + }, + "analysis": [ + { + "name": "Style", + "id": "style", + "tools": [ + { + "id": "checkstyle", + "pattern": "**/target/**checkstyle-result.xml" + }, + { + "id": "pmd", + "pattern": "**/target/pmd-*/pmd.xml" + }, + { + "id": "java", + "icon": "coffee", + "pattern": "**/maven.log" + } + ] + }, + { + "name": "Bugs", + "id": "bugs", + "icon": "bug", + "tools": [ + { + "id": "spotbugs", + "sourcePath": "src/main/java", + "pattern": "**/target/spotbugsXml.xml" + }, + { + "id": "error-prone", + "pattern": "**/maven.log" + } + ] + }, + { + "name": "API Problems", + "id": "api", + "icon": "no_entry_sign", + "tools": [ + { + "id": "revapi", + "sourcePath": "src/main/java", + "pattern": "**/target/revapi-result.json" + } + ] + }, + { + "name": "Vulnerabilities", + "id": "vulnerabilities", + "icon": "shield", + "tools": [ + { + "icon": "shield", + "id": "owasp-dependency-check", + "icon": "shield", + "pattern": "**/target/dependency-check-report.json" + } + ] + } + ], + "coverage": [ + { + "name": "Code Coverage", + "tools": [ + { + "id": "jacoco", + "metric": "line", + "sourcePath": "src/main/java", + "pattern": "**/target/site/jacoco/jacoco.xml" + }, + { + "id": "jacoco", + "metric": "branch", + "sourcePath": "src/main/java", + "pattern": "**/target/site/jacoco/jacoco.xml" + } + ] + } + ], + "metrics": { + "name": "Software Metrics", + "tools": [ + { + "id": "metrics", + "pattern": "**/metrics/pmd.xml", + "metric": "CYCLOMATIC_COMPLEXITY" + }, + { + "id": "metrics", + "pattern": "**/metrics/pmd.xml", + "metric": "COGNITIVE_COMPLEXITY" + }, + { + "id": "metrics", + "pattern": "**/metrics/pmd.xml", + "metric": "NPATH_COMPLEXITY" + }, + { + "id": "metrics", + "pattern": "**/metrics/pmd.xml", + "metric": "LOC" + }, + { + "id": "metrics", + "pattern": "**/metrics/pmd.xml", + "metric": "NCSS" + }, + { + "id": "metrics", + "pattern": "**/metrics/pmd.xml", + "metric": "COHESION" + }, + { + "id": "metrics", + "pattern": "**/metrics/pmd.xml", + "metric": "WEIGHT_OF_CLASS" + } + ] + } +} diff --git a/.github/workflows/check-md-links.yml b/.github/workflows/check-md-links.yml index 507ba58d..45b54e97 100644 --- a/.github/workflows/check-md-links.yml +++ b/.github/workflows/check-md-links.yml @@ -7,8 +7,8 @@ jobs: name: 'Check Markdown links' runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v5 - - uses: umbrelladocs/action-linkspector@v1.3.7 + - uses: actions/checkout@v6 + - uses: umbrelladocs/action-linkspector@v1.4.0 with: github_token: ${{ secrets.github_token }} reporter: github-pr-check diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cfd4c2d4..cdaf2895 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,19 +10,20 @@ jobs: build: strategy: + fail-fast: false matrix: platform: [ubuntu-latest, macos-latest, windows-latest] - jdk: [17, 21] + jdk: [21, 25] runs-on: ${{ matrix.platform }} name: on ${{ matrix.platform }} with JDK ${{ matrix.jdk }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Set up JDK ${{ matrix.jdk }} uses: actions/setup-java@v5 with: - distribution: 'corretto' + distribution: 'temurin' java-version: '${{ matrix.jdk }}' check-latest: true cache: 'maven' diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 640de6af..ede17e8d 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -23,7 +23,7 @@ jobs: language: [ java ] steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Setup Java uses: actions/setup-java@v5 @@ -38,7 +38,7 @@ jobs: maven-version: 3.9.11 - name: Initialize CodeQL - uses: github/codeql-action/init@v3 + uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} queries: +security-and-quality @@ -47,7 +47,7 @@ jobs: run: mvn -V --color always -ntp clean verify -Pskip - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 + uses: github/codeql-action/analyze@v4 with: upload: false output: sarif-results @@ -62,6 +62,6 @@ jobs: output: sarif-results/${{ matrix.language }}.sarif - name: Upload SARIF results - uses: github/codeql-action/upload-sarif@v3 + uses: github/codeql-action/upload-sarif@v4 with: sarif_file: sarif-results/${{ matrix.language }}.sarif diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml deleted file mode 100644 index 92077b74..00000000 --- a/.github/workflows/coverage.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: 'CodeCov' - -on: - push: - branches: - - main - pull_request: - -jobs: - coverage: - - runs-on: ubuntu-latest - name: Create and upload coverage report - - steps: - - uses: actions/checkout@v5 - - name: Set up JDK 21 - uses: actions/setup-java@v5 - with: - distribution: 'temurin' - java-version: '21' - check-latest: true - cache: 'maven' - - name: Set up Maven - uses: stCarolas/setup-maven@v5 - with: - maven-version: 3.9.11 - - name: Generate coverage with JaCoCo - run: mvn -V --color always -ntp clean verify -Pci - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v5.5.1 - with: - file: 'target/site/jacoco/jacoco.xml' - disable_search: true - token: ${{secrets.CODECOV_TOKEN}} diff --git a/.github/workflows/jenkins-security-scan.yml b/.github/workflows/jenkins-security-scan.yml index 6fc0b2b5..de3257e6 100644 --- a/.github/workflows/jenkins-security-scan.yml +++ b/.github/workflows/jenkins-security-scan.yml @@ -17,5 +17,5 @@ jobs: security-scan: uses: jenkins-infra/jenkins-security-scan/.github/workflows/jenkins-security-scan.yaml@v2 with: - java-cache: 'maven' # Optionally enable use of a build dependency cache. Specify 'maven' or 'gradle' as appropriate. - # java-version: 21 # Optionally specify what version of Java to set up for the build, or remove to use a recent default. + java-cache: 'maven' + java-version: 21 diff --git a/.github/workflows/quality-monitor-build.yml b/.github/workflows/quality-monitor-build.yml new file mode 100644 index 00000000..a799e60f --- /dev/null +++ b/.github/workflows/quality-monitor-build.yml @@ -0,0 +1,59 @@ +name: 'Quality Monitor Build' + +on: + pull_request: + +jobs: + build: + runs-on: [ubuntu-latest] + name: Create quality reports + + steps: + - name: Checkout PR + uses: actions/checkout@v6 + - name: Set up JDK 21 + uses: actions/setup-java@v5 + with: + distribution: 'temurin' + java-version: 21 + check-latest: true + cache: 'maven' + - name: Set up Maven + uses: stCarolas/setup-maven@v5 + with: + maven-version: 3.9.11 + - name: Cache the NVD database + uses: actions/cache@v4 + with: + path: ~/.m2/repository/org/owasp/dependency-check-data + key: dependency-check + - name: Check if quality monitor reports mutation coverage + run: | + FILE='.github/quality-monitor.json' + PATTERN='target/pit-reports/mutations.xml' + if [ -f "$FILE" ]; then + if grep -q "$PATTERN" "$FILE"; then + echo "PIT=-Ppit" >> "$GITHUB_ENV" + fi + fi + - name: Build with Maven + env: + NVD_API_KEY: ${{ secrets.NVD_API_KEY }} + OSS_INDEX_TOKEN: ${{ secrets.OSS_INDEX_TOKEN }} + PIT: ${{ env.PIT }} + BROWSER: chrome-container + run: | + mvn -V --color always -ntp clean verify $PIT -Pci -Powasp | tee maven.log + if [ "${PIPESTATUS[0]}" != "0" ]; then + exit 1; + fi + mv -fv maven.log target/maven.log + - name: Upload Quality Reports + uses: actions/upload-artifact@v5 + with: + name: quality-reports + path: | + **/target/**/*.json + **/target/**/*.xml + **/target/**/*.log + diff --git a/.github/workflows/quality-monitor-comment.yml b/.github/workflows/quality-monitor-comment.yml new file mode 100644 index 00000000..e3d9bf02 --- /dev/null +++ b/.github/workflows/quality-monitor-comment.yml @@ -0,0 +1,52 @@ +name: 'Quality Monitor Comment' + +on: + workflow_run: + workflows: [ "Quality Monitor Build" ] + types: [ completed ] + +permissions: + actions: read + contents: read + pull-requests: write + checks: write + +jobs: + comment: + if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'pull_request' }} + runs-on: ubuntu-latest + name: Comment on PR + + steps: + - name: Extract PR number and SHA + id: pr + run: | + pr_number='${{ github.event.workflow_run.pull_requests[0].number }}' + echo "number=$pr_number" >> "$GITHUB_OUTPUT" + sha='${{ github.event.workflow_run.head_sha }}' + echo "sha=$sha" >> "$GITHUB_OUTPUT" + - name: Checkout PR + uses: actions/checkout@v6 + with: + ref: ${{ steps.pr.outputs.sha }} + - name: Download PR Quality Reports from Quality Monitor Build workflow + uses: dawidd6/action-download-artifact@v11 + with: + run_id: ${{ github.event.workflow_run.id }} + name: quality-reports + - name: Read Quality Monitor Configuration + id: quality-monitor + run: echo "json=$(jq -c . .github/quality-monitor.json)" >> "$GITHUB_OUTPUT" + - name: Read Quality Gates Configuration + id: quality-gates + run: echo "json=$(jq -c . .github/quality-gates.json)" >> "$GITHUB_OUTPUT" + - name: Run Quality Monitor and Comment on PR + uses: uhafner/quality-monitor@v3 + with: + sha: ${{ steps.pr.outputs.sha }} + config: ${{ steps.quality-monitor.outputs.json }} + quality-gates: ${{ steps.quality-gates.outputs.json }} + pr-number: ${{ steps.pr.outputs.number }} + comments-strategy: REMOVE + show-headers: true + title-metric: none diff --git a/.github/workflows/quality-monitor-jenkins.yml b/.github/workflows/quality-monitor-jenkins.yml deleted file mode 100644 index 5675d662..00000000 --- a/.github/workflows/quality-monitor-jenkins.yml +++ /dev/null @@ -1,180 +0,0 @@ -name: 'Quality Monitor PR' - -on: - pull_request_target: - -jobs: - build: - - runs-on: [ubuntu-latest] - name: Build, test and monitor quality on Ubuntu - - steps: - - name: 'Checkout merge commit' - uses: actions/checkout@v5 - with: - ref: "${{ github.event.pull_request.merge_commit_sha }}" - if: github.event.pull_request.merge_commit_sha != '' - - name: 'Checkout PR head commit' - uses: actions/checkout@v5 - with: - ref: "${{ github.event.pull_request.head.sha }}" - if: github.event.pull_request.merge_commit_sha == '' - - name: Set up JDK 21 - uses: actions/setup-java@v5 - with: - distribution: 'temurin' - java-version: 21 - check-latest: true - cache: 'maven' - - name: Set up Maven - uses: stCarolas/setup-maven@v5 - with: - maven-version: 3.9.11 - - name: Cache the NVD database - uses: actions/cache@v4 - with: - path: ~/.m2/repository/org/owasp/dependency-check-data - key: dependency-check - - name: Build with Maven - env: - BROWSER: chrome-container - NVD_API_KEY: ${{ secrets.NVD_API_KEY }} - run: | - mvn -V --color always -ntp clean verify -Pci -Powasp | tee maven.log - if [ "${PIPESTATUS[0]}" != "0" ]; then - exit 1; - fi - - name: Extract pull request number - uses: jwalton/gh-find-current-pr@v1 - id: pr - - name: Run Quality Monitor - uses: uhafner/quality-monitor@v3 - with: - pr-number: ${{ steps.pr.outputs.number }} - show-headers: true - config: > - { - "tests": { - "name": "Tests", - "tools": [ - { - "id": "junit", - "name": "Unit Tests", - "pattern": "**/target/surefire-reports/TEST*git*.xml" - }, - { - "id": "junit", - "icon": "rocket", - "name": "Integration Tests", - "pattern": "**/target/failsafe-reports/TEST*.xml" - }, - { - "id": "junit", - "icon": "no_entry", - "name": "Architecture Tests", - "pattern": "**/target/surefire-reports/TEST*archunit*.xml" - } - ] - }, - "analysis": [ - { - "name": "Style", - "id": "style", - "tools": [ - { - "id": "checkstyle", - "pattern": "**/target/checkstyle-*/checkstyle-result.xml" - }, - { - "id": "pmd", - "pattern": "**/target/pmd-*/pmd.xml" - } - ] - }, - { - "name": "Bugs", - "id": "bugs", - "icon": "bug", - "tools": [ - { - "id": "spotbugs", - "sourcePath": "src/main/java", - "pattern": "**/target/spotbugsXml.xml" - } - ] - }, - { - "name": "Vulnerabilities", - "id": "vulnerabilities", - "icon": "shield", - "tools": [ - { - "id": "owasp-dependency-check", - "icon": "shield", - "pattern": "**/target/dependency-check-report.json" - } - ] - } - ], - "coverage": [ - { - "name": "Code Coverage", - "tools": [ - { - "id": "jacoco", - "metric": "line", - "sourcePath": "src/main/java", - "pattern": "**/target/site/jacoco/jacoco.xml" - }, - { - "id": "jacoco", - "metric": "branch", - "sourcePath": "src/main/java", - "pattern": "**/target/site/jacoco/jacoco.xml" - } - ] - } - ], - "metrics": - { - "name": "Software Metrics", - "tools": [ - { - "id": "metrics", - "pattern": "**/metrics/pmd.xml", - "metric": "CYCLOMATIC_COMPLEXITY" - }, - { - "id": "metrics", - "pattern": "**/metrics/pmd.xml", - "metric": "COGNITIVE_COMPLEXITY" - }, - { - "id": "metrics", - "pattern": "**/metrics/pmd.xml", - "metric": "NPATH_COMPLEXITY" - }, - { - "id": "metrics", - "pattern": "**/metrics/pmd.xml", - "metric": "LOC" - }, - { - "id": "metrics", - "pattern": "**/metrics/pmd.xml", - "metric": "NCSS" - }, - { - "id": "metrics", - "pattern": "**/metrics/pmd.xml", - "metric": "COHESION" - }, - { - "id": "metrics", - "pattern": "**/metrics/pmd.xml", - "metric": "WEIGHT_OF_CLASS" - } - ] - } - } diff --git a/.github/workflows/sync-labels.yml b/.github/workflows/sync-labels.yml index f64e0c5e..fbce7cc7 100644 --- a/.github/workflows/sync-labels.yml +++ b/.github/workflows/sync-labels.yml @@ -13,7 +13,7 @@ jobs: name: Sync labels runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: micnncim/action-label-syncer@v1.3.0 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/ui-tests.yml b/.github/workflows/ui-tests.yml index ae751fcd..2f4c9e52 100644 --- a/.github/workflows/ui-tests.yml +++ b/.github/workflows/ui-tests.yml @@ -17,7 +17,7 @@ jobs: name: ${{ matrix.browser }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Set up JDK 21 uses: actions/setup-java@v5 with: diff --git a/Jenkinsfile b/Jenkinsfile index a853a8c1..626fb053 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,6 +1,6 @@ def configurations = [ [ platform: "linux", jdk: "21" ], - [ platform: "windows", jdk: "17" ] + [ platform: "windows", jdk: "25" ] ] buildPlugin(failFast: false, timeout: 90, configurations: configurations, diff --git a/README.md b/README.md index 6509cc86..b26def77 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,6 @@ [![Join the chat at https://gitter.im/jenkinsci/warnings-plugin](https://badges.gitter.im/jenkinsci/warnings-plugin.svg)](https://gitter.im/jenkinsci/warnings-plugin?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Jenkins](https://ci.jenkins.io/job/Plugins/job/git-forensics-plugin/job/main/badge/icon?subject=Jenkins%20CI)](https://ci.jenkins.io/job/Plugins/job/git-forensics-plugin/job/main/) -[![GitHub Actions](https://github.com/jenkinsci/git-forensics-plugin/workflows/GitHub%20CI/badge.svg)](https://github.com/jenkinsci/git-forensics-plugin/actions) -[![codecov](https://codecov.io/gh/jenkinsci/git-forensics-plugin/branch/master/graph/badge.svg)](https://codecov.io/gh/jenkinsci/git-forensics-plugin) [![CodeQL](https://github.com/jenkinsci/git-forensics-plugin/workflows/CodeQL/badge.svg)](https://github.com/jenkinsci/git-forensics-plugin/actions/workflows/codeql.yml) This Git Forensics Jenkins plugin mines and analyzes data from a Git repository. It implements all extension points of diff --git a/plugin/pom.xml b/plugin/pom.xml index dc6e00ee..ea6896de 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -3,7 +3,7 @@ 4.0.0 - io.jenkins.plugins + io.jenkins.plugins git-forensics-parent ${revision}.${changelist} @@ -35,7 +35,7 @@ 9.2.0 - 1.21.3 + 2.0.2 -Djava.awt.headless=true -Xmx1024m -Djenkins.test.timeout=1000 --add-opens java.base/java.lang=ALL-UNNAMED @@ -45,18 +45,6 @@ - - - org.eclipse.collections - eclipse-collections-api - ${eclipse-collections.version} - - - org.eclipse.collections - eclipse-collections - ${eclipse-collections.version} - - org.jenkins-ci.plugins @@ -73,7 +61,6 @@ io.jenkins.plugins plugin-util-api - 6.1197.v0503eb_85ec2d org.jenkins-ci.plugins @@ -114,7 +101,6 @@ io.jenkins.plugins plugin-util-api - 6.1167.v022176c7e0ca_ test tests @@ -228,30 +214,4 @@ - - - - - - io.jenkins.plugins - plugin-util-api - 6.1197.v0503eb_85ec2d - - - io.jenkins.plugins - plugin-util-api - 6.1197.v0503eb_85ec2d - - - io.jenkins.plugins - plugin-util-api - 6.1197.v0503eb_85ec2d - - - io.jenkins.plugins - plugin-util-api - 6.1197.v0503eb_85ec2d - - - - \ No newline at end of file + diff --git a/plugin/src/main/java/io/jenkins/plugins/forensics/git/blame/GitBlamer.java b/plugin/src/main/java/io/jenkins/plugins/forensics/git/blame/GitBlamer.java index 131b3684..66577e0b 100644 --- a/plugin/src/main/java/io/jenkins/plugins/forensics/git/blame/GitBlamer.java +++ b/plugin/src/main/java/io/jenkins/plugins/forensics/git/blame/GitBlamer.java @@ -51,6 +51,7 @@ class GitBlamer extends Blamer { static final String NO_HEAD_ERROR = "Could not retrieve HEAD commit, aborting"; static final String BLAME_ERROR = "Computing blame information failed with an exception:"; + @SuppressWarnings("serial") private final GitClient git; private final String gitCommit; diff --git a/plugin/src/main/java/io/jenkins/plugins/forensics/git/delta/GitDeltaCalculator.java b/plugin/src/main/java/io/jenkins/plugins/forensics/git/delta/GitDeltaCalculator.java index 48b1d86e..6e3355ab 100644 --- a/plugin/src/main/java/io/jenkins/plugins/forensics/git/delta/GitDeltaCalculator.java +++ b/plugin/src/main/java/io/jenkins/plugins/forensics/git/delta/GitDeltaCalculator.java @@ -32,6 +32,7 @@ public class GitDeltaCalculator extends DeltaCalculator { static final String DELTA_ERROR = "Computing delta information failed with an exception:"; static final String EMPTY_COMMIT_ERROR = "Calculating the Git code delta is not possible due to an unknown commit ID"; + @SuppressWarnings("serial") private final GitClient git; private final String scmKey; @@ -51,6 +52,7 @@ public GitDeltaCalculator(final GitClient git, final String scmKey) { } @Override + @SuppressWarnings("deprecation") public Optional calculateDelta(final Run build, final Run referenceBuild, final String scmKeyFilter, final FilteredLog log) { var scm = StringUtils.defaultIfEmpty(scmKeyFilter, scmKey); diff --git a/plugin/src/main/java/io/jenkins/plugins/forensics/git/miner/CommitStatisticsStep.java b/plugin/src/main/java/io/jenkins/plugins/forensics/git/miner/CommitStatisticsStep.java index b1bfcf18..97203bdd 100644 --- a/plugin/src/main/java/io/jenkins/plugins/forensics/git/miner/CommitStatisticsStep.java +++ b/plugin/src/main/java/io/jenkins/plugins/forensics/git/miner/CommitStatisticsStep.java @@ -225,6 +225,7 @@ public String getDisplayName() { } @Override + @SuppressWarnings("rawtypes") public boolean isApplicable(final Class jobType) { return true; } diff --git a/plugin/src/main/java/io/jenkins/plugins/forensics/git/miner/GitRepositoryMiner.java b/plugin/src/main/java/io/jenkins/plugins/forensics/git/miner/GitRepositoryMiner.java index f22c683e..e84063fd 100644 --- a/plugin/src/main/java/io/jenkins/plugins/forensics/git/miner/GitRepositoryMiner.java +++ b/plugin/src/main/java/io/jenkins/plugins/forensics/git/miner/GitRepositoryMiner.java @@ -31,6 +31,7 @@ public class GitRepositoryMiner extends RepositoryMiner { @Serial private static final long serialVersionUID = 1157958118716013983L; + @SuppressWarnings("serial") private final GitClient gitClient; GitRepositoryMiner(final GitClient gitClient) { diff --git a/plugin/src/main/java/io/jenkins/plugins/forensics/git/reference/BuildCommits.java b/plugin/src/main/java/io/jenkins/plugins/forensics/git/reference/BuildCommits.java index 8c0c4264..925aeb0c 100644 --- a/plugin/src/main/java/io/jenkins/plugins/forensics/git/reference/BuildCommits.java +++ b/plugin/src/main/java/io/jenkins/plugins/forensics/git/reference/BuildCommits.java @@ -23,7 +23,8 @@ class BuildCommits implements Serializable { private final String previousBuildCommit; - private final List commits = new ArrayList<>(); + @SuppressWarnings("PMD.LooseCoupling") + private final ArrayList commits = new ArrayList<>(); private ObjectId head = ObjectId.zeroId(); private ObjectId target = ObjectId.zeroId(); diff --git a/plugin/src/main/java/io/jenkins/plugins/forensics/git/reference/GitCommitsRecord.java b/plugin/src/main/java/io/jenkins/plugins/forensics/git/reference/GitCommitsRecord.java index dc1c8096..bf0e5146 100644 --- a/plugin/src/main/java/io/jenkins/plugins/forensics/git/reference/GitCommitsRecord.java +++ b/plugin/src/main/java/io/jenkins/plugins/forensics/git/reference/GitCommitsRecord.java @@ -1,6 +1,6 @@ package io.jenkins.plugins.forensics.git.reference; -import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Strings; import org.eclipse.jgit.lib.ObjectId; import edu.hm.hafner.util.FilteredLog; @@ -42,7 +42,7 @@ public class GitCommitsRecord implements RunAction2, Serializable { */ public static Optional findRecordForScm(final Run build, final String scmKey) { return build.getActions(GitCommitsRecord.class).stream() - .filter(record -> StringUtils.containsIgnoreCase(record.getScmKey(), scmKey)) + .filter(record -> Strings.CI.contains(record.getScmKey(), scmKey)) .findAny(); } @@ -58,9 +58,12 @@ public static Optional findRecordForScm(final Run build, private final RecordingType recordingType; private final String latestCommitLink; private final String targetParentCommit; - private final List commits; - private final List errorMessages; - private final List infoMessages; + @SuppressWarnings("PMD.LooseCoupling") + private final ArrayList commits; + @SuppressWarnings("PMD.LooseCoupling") + private final ArrayList errorMessages; + @SuppressWarnings("PMD.LooseCoupling") + private final ArrayList infoMessages; /** Determines if this record is the starting point or an incremental record that is based on the previous record. */ enum RecordingType { diff --git a/pom.xml b/pom.xml index 02fd1b7f..91498382 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.jvnet.hudson.plugins analysis-pom - 11.2805.vdb_e83282030b_ + 11.2934.va_a_d795c46a_7b_ diff --git a/ui-tests/pom.xml b/ui-tests/pom.xml index a67d6218..104606c1 100644 --- a/ui-tests/pom.xml +++ b/ui-tests/pom.xml @@ -5,7 +5,7 @@ edu.hm.hafner codingstyle-pom - 5.36.0 + 5.39.0 @@ -16,10 +16,10 @@ UI Tests of Git Forensics Plugin - 2.529 - 3.1762.vd3ff902a_5b_c4 + 2.539 + 3.1773.v3646231d4c22 2.3 - 4.1.1 + 5.1.0 ${project.groupId}.warnings.ui.tests firefox-container @@ -38,7 +38,7 @@ io.netty netty-bom - 4.2.6.Final + 4.2.7.Final pom import @@ -49,12 +49,12 @@ org.jenkins-ci acceptance-test-harness - 6361.vcb_036a_7ffb_a_5 + 6464.vf87c7908f638 com.fasterxml.jackson.core jackson-databind - 2.20.0 + 2.20.1 test diff --git a/ui-tests/src/main/java/io/jenkins/plugins/forensics/git/DetailsTable.java b/ui-tests/src/main/java/io/jenkins/plugins/forensics/git/DetailsTable.java index ece2acc3..65cc5673 100644 --- a/ui-tests/src/main/java/io/jenkins/plugins/forensics/git/DetailsTable.java +++ b/ui-tests/src/main/java/io/jenkins/plugins/forensics/git/DetailsTable.java @@ -1,20 +1,21 @@ package io.jenkins.plugins.forensics.git; +import org.openqa.selenium.By; +import org.openqa.selenium.Keys; +import org.openqa.selenium.WebElement; + import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Locale; import java.util.stream.Collectors; -import org.openqa.selenium.By; -import org.openqa.selenium.Keys; -import org.openqa.selenium.WebElement; - /** * Page object for the details-table of the forensics view. * * @author Mitja Oldenbourg */ -public class DetailsTable { +public final class DetailsTable { static final String FILE_NAME = "File"; static final String AUTHORS = "#Authors"; static final String COMMITS = "#Commits"; @@ -165,6 +166,6 @@ private void updateTableRows() { } private WebElement getHeaderAsWebElement(final int option) { - return page.findElement(By.xpath(String.format(".//thead/tr/th[%d]", option))); + return page.findElement(By.xpath(String.format(Locale.ENGLISH, ".//thead/tr/th[%d]", option))); } } diff --git a/ui-tests/src/main/java/io/jenkins/plugins/forensics/git/ScmForensics.java b/ui-tests/src/main/java/io/jenkins/plugins/forensics/git/ScmForensics.java index ad506aa0..fff35177 100644 --- a/ui-tests/src/main/java/io/jenkins/plugins/forensics/git/ScmForensics.java +++ b/ui-tests/src/main/java/io/jenkins/plugins/forensics/git/ScmForensics.java @@ -1,12 +1,12 @@ package io.jenkins.plugins.forensics.git; -import java.net.URL; - import org.apache.commons.lang3.StringUtils; import org.openqa.selenium.By; import com.google.inject.Injector; +import java.net.URL; + import org.jenkinsci.test.acceptance.po.Build; import org.jenkinsci.test.acceptance.po.PageObject; @@ -52,7 +52,7 @@ public ScmForensics(final Injector injector, final URL url, final String id) { public int getTotal() { String total = find(By.id("forensics_info")).getText(); - return Integer.parseInt(StringUtils.substringAfter(total, "of ").split(" ")[0]); + return Integer.parseInt(StringUtils.substringAfter(total, "of ").split(" ", 0)[0]); } } diff --git a/ui-tests/src/main/java/io/jenkins/plugins/forensics/git/ScrollerUtil.java b/ui-tests/src/main/java/io/jenkins/plugins/forensics/git/ScrollerUtil.java index 652e3333..cc9a4725 100644 --- a/ui-tests/src/main/java/io/jenkins/plugins/forensics/git/ScrollerUtil.java +++ b/ui-tests/src/main/java/io/jenkins/plugins/forensics/git/ScrollerUtil.java @@ -19,8 +19,8 @@ public final class ScrollerUtil { */ public static void hideScrollerTabBar(final WebDriver driver) { WebElement element = driver.findElement(By.xpath("//div[contains(@class, 'jenkins-config-widgets')]")); - if (driver instanceof JavascriptExecutor) { - ((JavascriptExecutor) driver).executeScript("arguments[0].style.visibility='hidden'", element); + if (driver instanceof JavascriptExecutor executor) { + executor.executeScript("arguments[0].style.visibility='hidden'", element); } } diff --git a/ui-tests/src/main/java/io/jenkins/plugins/forensics/git/Summary.java b/ui-tests/src/main/java/io/jenkins/plugins/forensics/git/Summary.java index 4a662968..651ba02a 100644 --- a/ui-tests/src/main/java/io/jenkins/plugins/forensics/git/Summary.java +++ b/ui-tests/src/main/java/io/jenkins/plugins/forensics/git/Summary.java @@ -1,13 +1,13 @@ package io.jenkins.plugins.forensics.git; -import java.util.List; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - import org.apache.commons.lang3.StringUtils; import org.openqa.selenium.By; import org.openqa.selenium.WebElement; +import java.util.List; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + import org.jenkinsci.test.acceptance.po.Build; import org.jenkinsci.test.acceptance.po.PageObject; @@ -34,7 +34,7 @@ public class Summary extends PageObject { * @param id * the type of the result page (e.g. simian, checkstyle, cpd, etc.) */ - @SuppressWarnings("PMD.ConstructorCallsOverridableMethod") + @SuppressWarnings({"PMD.ConstructorCallsOverridableMethod", "this-escape"}) public Summary(final Build parent, final String id) { super(parent, parent.url(id)); diff --git a/ui-tests/src/test/java/io/jenkins/plugins/forensics/git/SmokeTests.java b/ui-tests/src/test/java/io/jenkins/plugins/forensics/git/SmokeTests.java index 7ac7bfeb..93777438 100644 --- a/ui-tests/src/test/java/io/jenkins/plugins/forensics/git/SmokeTests.java +++ b/ui-tests/src/test/java/io/jenkins/plugins/forensics/git/SmokeTests.java @@ -1,7 +1,5 @@ package io.jenkins.plugins.forensics.git; -import java.util.List; - import org.junit.Test; import org.jenkinsci.test.acceptance.junit.AbstractJUnitTest; @@ -30,8 +28,8 @@ public class SmokeTests extends AbstractJUnitTest { */ @Test public void shouldMineGitHubRepository() { - WorkflowJob job = createJob(); - Build build = buildSuccessfully(job); + var job = createJob(); + var build = buildSuccessfully(job); assertThat(build.getConsole()).contains( "Found 428 commits", @@ -40,14 +38,14 @@ public void shouldMineGitHubRepository() { build.open(); - Summary commitStatistics = new Summary(build, "commits-of-" + SCM_HASH); + var commitStatistics = new Summary(build, "commits-of-" + SCM_HASH); assertThat(commitStatistics).hasTitle("SCM: " + SCM_KEY); assertThat(commitStatistics).hasDetails("Initial recording of 200 commits", "Latest commit: 28af63d"); assertThat(commitStatistics.openLinkByText("28af63d")).isEqualTo("https://github.com/jenkinsci/git-forensics-plugin/commit/28af63def44286729e3b19b03464d100fd1d0587"); build.open(); - Summary scmForensics = new Summary(build, "scm-forensics-of-" + SCM_HASH); + var scmForensics = new Summary(build, "scm-forensics-of-" + SCM_HASH); assertThat(scmForensics).hasTitle("SCM Forensics: " + SCM_KEY); assertThat(scmForensics).hasDetails("51 repository files (total lines of code: 6066, total churn: 16966)", "New commits: 402 (from 4 authors in 131 files)", @@ -57,11 +55,11 @@ public void shouldMineGitHubRepository() { // TODO: navigate from summary - ScmForensics forensicsDetails = new ScmForensics(build, "forensics"); + var forensicsDetails = new ScmForensics(build, "forensics"); forensicsDetails.open(); assertThat(forensicsDetails.getTotal()).isEqualTo(51); - DetailsTable detailsTable = new DetailsTable(forensicsDetails); + var detailsTable = new DetailsTable(forensicsDetails); assertTableHeaders(detailsTable); assertTableEntriesAndSorting(detailsTable); assertSearch(detailsTable); @@ -89,7 +87,7 @@ private WorkflowJob createJob() { private void assertTableHeaders(final DetailsTable detailsTable) { assertThat(detailsTable.getHeaderSize()).isEqualTo(7); - List tableHeaders = detailsTable.getHeaders(); + var tableHeaders = detailsTable.getHeaders(); assertThat(tableHeaders.get(0)).isEqualTo(FILE_NAME); assertThat(tableHeaders.get(1)).isEqualTo(AUTHORS); assertThat(tableHeaders.get(2)).isEqualTo(COMMITS); @@ -179,7 +177,7 @@ private void assertPagination(final DetailsTable detailsTable) { private void assertRow(final DetailsTable detailsTable, final int rowNum, final String fileName, final int numAuthors, final int numCommits) { - DetailsTableRow secondRow = detailsTable.getTableRows().get(rowNum); + var secondRow = detailsTable.getTableRows().get(rowNum); assertThat(secondRow.getFileName()).isEqualTo(fileName); assertThat(secondRow.getNumberOfAuthors()).isEqualTo(numAuthors);