diff --git a/.github/workflows/sonarqube.yaml b/.github/workflows/sonarqube.yaml new file mode 100644 index 0000000..b159c34 --- /dev/null +++ b/.github/workflows/sonarqube.yaml @@ -0,0 +1,104 @@ +name: SonarQube Scan + +on: + push: + branches: + - master + pull_request: + types: [opened, synchronize, reopened] + branches: + - master + workflow_dispatch: + inputs: + scan_type: + description: 'Type of scan to run' + required: true + type: choice + options: + - branch + - pr + default: branch + ref: + description: 'Commit SHA, branch, or tag to check out and scan (leave blank to use the default branch)' + required: false + type: string + default: '' + +concurrency: + group: sonarqube-${{ github.ref }} + cancel-in-progress: true + +env: + TRUSTSTORE_PATH: ./ibm_castorevpcprod + # Maven tuning — mirrors settings used across the rest of the CI workflows. + MAVEN_OPTS: >- + -Xss1500k + -Xmx2048m + -XX:+UnlockDiagnosticVMOptions + -XX:+IgnoreUnrecognizedVMOptions + -XX:GCLockerRetryAllocationCount=100 + -Daether.connector.http.reuseConnections=false + -Daether.connector.requestTimeout=60000 + -Dhttp.keepAlive=false + -Dmaven.wagon.http.pool=false + -Dmaven.wagon.http.retryHandler.class=standard + -Dmaven.wagon.http.retryHandler.count=3 + -Dmaven.wagon.http.retryHandler.requestSentEnabled=true + -Dmaven.wagon.http.serviceUnavailableRetryStrategy.class=standard + -Dmaven.wagon.rto=60000 + +jobs: + sonarqube-scan: + name: SonarQube Scan + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + # Full history required for accurate blame and new-code period detection. + fetch-depth: 0 + # When triggered manually with a specific ref (commit SHA, branch, tag), + # check out that ref; otherwise fall back to the default event ref. + ref: ${{ (github.event_name == 'workflow_dispatch' && inputs.ref != '') && inputs.ref || github.ref }} + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + distribution: corretto + java-version: '17' + cache: maven + + # Decode the IBM truststore from the base64 secret and write it to disk. + # Secret is bound to an env var to avoid shell-injection (S7636). + - name: Decode IBM SonarQube truststore + env: + TRUSTSTORE_B64: ${{ secrets.IBM_SONARQUBE_CERT_TRUSTSTORE_BASE64 }} + run: | + echo "$TRUSTSTORE_B64" | base64 --decode > "${{ env.TRUSTSTORE_PATH }}" + + # Produce .class files required by SonarQube's Java bytecode analyser. + - name: Build + run: mvn -B package -DskipTests --no-transfer-progress + + # Pinned to v8.2.1 (SHA: 22918119ff8e1ca75a623e15c8296b6ea4fbe28f). + - name: Run SonarQube scan + uses: SonarSource/sonarqube-scan-action@22918119ff8e1ca75a623e15c8296b6ea4fbe28f + env: + SONAR_TOKEN: ${{ secrets.IBM_SONARQUBE_API_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + with: + args: > + -D sonar.projectKey=${{ vars.SONAR_PROJECT_KEY }} + -D sonar.projectName=${{ vars.SONAR_PROJECT_NAME }} + -D sonar.java.source=17 + -D sonar.sources=. + -D sonar.exclusions=**/proto/**,**/shade/**,**/shaded/**,**/target/** + -D sonar.java.binaries=**/target/classes + -D sonar.scanner.truststorePath=${{ env.TRUSTSTORE_PATH }} + -D sonar.scanner.truststorePassword=${{ secrets.IBM_SONARQUBE_CERT_PASSWORD }} + ${{ (github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && inputs.scan_type == 'pr')) + && format('-Dsonar.pullrequest.key={0} -Dsonar.pullrequest.branch={1} -Dsonar.pullrequest.base={2}', + github.event.pull_request.number, github.head_ref, github.base_ref) + || format('-Dsonar.branch.name={0}', + (github.event_name == 'workflow_dispatch' && inputs.ref != '') && inputs.ref || github.ref_name) }}