@@ -333,18 +333,47 @@ jobs:
333333 }
334334 "version=$($matches[0].Trim())" >> $env:GITHUB_OUTPUT
335335
336+ # The quality gate blocks the release only where a repository opts in, by setting the
337+ # SONAR_BLOCKING_GATE repository variable to true. It is not on by default because most of
338+ # these repositories carry security hotspots that have never been reviewed, and a gate they
339+ # have never been held to would stop every release at once rather than improve anything. The
340+ # analysis is still uploaded and the gate is still evaluated either way, so turning a
341+ # repository on is a variable away once its findings are triaged.
336342 - name : Begin SonarQube
337343 if : ${{ env.SONAR_TOKEN != '' }}
338344 env :
339345 SONAR_TOKEN : ${{ secrets.SONAR_TOKEN }}
346+ SONAR_BLOCKING_GATE : ${{ vars.SONAR_BLOCKING_GATE }}
340347 shell : pwsh
341348 run : |
342- .\.sonar\scanner\dotnet-sonarscanner begin /k:"${{ github.repository_owner }}_${{ github.event.repository.name }}" /o:"${{ github.repository_owner }}" /v:"${{ steps.analysis_version.outputs.version }}" /d:sonar.token="$env:SONAR_TOKEN" /d:sonar.host.url="https://sonarcloud.io" /d:sonar.projectBaseDir="${{ github.workspace }}" /d:sonar.qualitygate.wait=true /d:sonar.cs.vscoveragexml.reportsPaths="coverage/**/coverage.xml" /d:sonar.coverage.exclusions="**/*Test*.cs,**/*.Tests.cs,**/*.Tests/**/*,**/obj/**/*,**/*.dll,**/NativeExports.cs" /d:sonar.cs.vstest.reportsPaths="coverage/**/*.trx" /d:sonar.exclusions="**/NativeExports.cs"
349+ $sonarArgs = @(
350+ 'begin'
351+ '/k:${{ github.repository_owner }}_${{ github.event.repository.name }}'
352+ '/o:${{ github.repository_owner }}'
353+ '/v:${{ steps.analysis_version.outputs.version }}'
354+ "/d:sonar.token=$env:SONAR_TOKEN"
355+ '/d:sonar.host.url=https://sonarcloud.io'
356+ '/d:sonar.projectBaseDir=${{ github.workspace }}'
357+ '/d:sonar.cs.vscoveragexml.reportsPaths=coverage/**/coverage.xml'
358+ '/d:sonar.coverage.exclusions=**/*Test*.cs,**/*.Tests.cs,**/*.Tests/**/*,**/obj/**/*,**/*.dll,**/NativeExports.cs'
359+ '/d:sonar.cs.vstest.reportsPaths=coverage/**/*.trx'
360+ '/d:sonar.exclusions=**/NativeExports.cs'
361+ )
362+
363+ if ($env:SONAR_BLOCKING_GATE -eq 'true') {
364+ $sonarArgs += '/d:sonar.qualitygate.wait=true'
365+ Write-Host 'Quality gate is blocking for this repository.'
366+ } else {
367+ Write-Host 'Quality gate is advisory for this repository. Set the SONAR_BLOCKING_GATE variable to true to enforce it.'
368+ }
369+
370+ & .\.sonar\scanner\dotnet-sonarscanner @sonarArgs
343371
344372 # `ci` rather than restore and build directly, because it is the only place that updates
345373 # and commits the metadata files, updates the repository topics, applies the version gate
346374 # behind `[skip ci]`, and writes the step outputs the security job reads.
347- # The tests already ran in the matrix, and the release waits for the quality gate below.
375+ # The tests already ran in the matrix, and where the gate is blocking the release waits for
376+ # it below.
348377 - name : Run KtsuBuild Pipeline
349378 id : pipeline
350379 shell : pwsh
@@ -372,9 +401,11 @@ jobs:
372401 run : |
373402 .\.sonar\scanner\dotnet-sonarscanner end /d:sonar.token="$env:SONAR_TOKEN"
374403
375- # Gated by the step above. `sonar.qualitygate.wait=true` makes a failed gate fail that
376- # step, and a step whose `if:` names no status function is implicitly gated on success, so
377- # a release cannot proceed past a gate the project did not pass.
404+ # Gated by the step above, but only where the gate is blocking. With SONAR_BLOCKING_GATE
405+ # set, `sonar.qualitygate.wait=true` makes a failed gate fail that step, and a step whose
406+ # `if:` names no status function is implicitly gated on success, so a release cannot proceed
407+ # past a gate the project did not pass. Without it the analysis is still published and the
408+ # gate still evaluated, it just does not hold up the release.
378409 - name : Release
379410 if : steps.pipeline.outputs.should_release == 'true'
380411 shell : pwsh
0 commit comments