解决 sonarQube Quality Gate 的全局 webhook
Work around global webhook for sonarQube Quality Gate
我有兴趣为我的项目添加质量门。在 Jenkins 构建后,我添加了一个脚本,用于在 SonarQube 服务器上创建一个项目并确定测试质量是否足够(可以找到代码来源 here)。脚本如下
stage('SonarCloud') {
steps {
withSonarQubeEnv('SonarQube') {
sh 'mvn clean package sonar:sonar '
}
}
}
stage("Quality Gate") {
steps {
timeout(time: 15, unit: 'MINUTES') { // If analysis takes longer than indicated time, then build will be aborted
waitForQualityGate abortPipeline: true
script{
def qg = waitForQualityGate() // Waiting for analysis to be completed
if(qg.status != 'OK'){ // If quality gate was not met, then present error
error "Pipeline aborted due to quality gate failure: ${qg.status}"
}
}
}
}
}
问题是我的构建永远不会自行完成(它会在超时后中止。删除超时会使它看起来永远运行。话虽如此,分析已创建并放置在 SonarQube 服务器上)。这是我在超时前看到的消息:
SonarQube task 'AXUx0uqFm6myUuXQbknO' status is 'IN_PROGRESS'
Cancelling nested steps due to timeout
我的问题是我不是我们 SonarQube 服务器的管理员,所以我无法添加可以解决此问题的 webhook。我想知道是否有解决方法?
我试过更换
sh 'mvn clean package sonar:sonar '
和
sh 'mvn clean package sonar:sonar -Dsonar.webhooks.project=https://my-jenkins-server.com/sonarqube-webhook/'
但一无所获。
我也尝试适应,在类似的问题中讨论过,但也没有走多远。
实际上有一种方法可以解决这个问题。正确的解决方法是将 webhook 安装回 Jenkins,但您显然无法解决这个问题。
下一个“正确的”修复是使用 SonarQube REST api,但首先我需要解释“waitForQualityGate()”中发生的事情。
它做的第一件事是使用 REST api 端点“/api/ce/task”查看后台任务是否完成。它从“report-task.txt”文件中获取要检查的任务 ID,该文件的格式类似于属性文件。如果第一次检查不是 SUCCESS 或 ERROR,那么它会进入等待循环,等待调用 webhook。
因此,您可以通过简单地添加比后台任务花费的秒数更多的“睡眠”,然后调用“waitForQualityGate()”来实现一个非常便宜的修复。
更合适的修复方法如下:
def reportFilePath = "target/sonar/report-task.txt"
def reportTaskFileExists = fileExists "${reportFilePath}"
if (reportTaskFileExists) {
echo "Found report task file"
def taskProps = readProperties file: "${reportFilePath}"
echo "taskId[${taskProps['ceTaskId']}]"
while (true) {
sleep 20
def taskStatusResult =
sh(returnStdout: true,
script: "curl -s -X GET -u ${authString} \'${sonarProps['sonar.host.url']}/api/ce/task?id=${taskProps['ceTaskId']}\'")
echo "taskStatusResult[${taskStatusResult}]"
def taskStatus = new JsonSlurper().parseText(taskStatusResult).task.status
echo "taskStatus[${taskStatus}]"
// Status can be SUCCESS, ERROR, PENDING, or IN_PROGRESS. The last two indicate it's
// not done yet.
if (taskStatus != "IN_PROGRESS" && taskStatus != "PENDING") {
break;
}
}
}
我有兴趣为我的项目添加质量门。在 Jenkins 构建后,我添加了一个脚本,用于在 SonarQube 服务器上创建一个项目并确定测试质量是否足够(可以找到代码来源 here)。脚本如下
stage('SonarCloud') {
steps {
withSonarQubeEnv('SonarQube') {
sh 'mvn clean package sonar:sonar '
}
}
}
stage("Quality Gate") {
steps {
timeout(time: 15, unit: 'MINUTES') { // If analysis takes longer than indicated time, then build will be aborted
waitForQualityGate abortPipeline: true
script{
def qg = waitForQualityGate() // Waiting for analysis to be completed
if(qg.status != 'OK'){ // If quality gate was not met, then present error
error "Pipeline aborted due to quality gate failure: ${qg.status}"
}
}
}
}
}
问题是我的构建永远不会自行完成(它会在超时后中止。删除超时会使它看起来永远运行。话虽如此,分析已创建并放置在 SonarQube 服务器上)。这是我在超时前看到的消息:
SonarQube task 'AXUx0uqFm6myUuXQbknO' status is 'IN_PROGRESS'
Cancelling nested steps due to timeout
我的问题是我不是我们 SonarQube 服务器的管理员,所以我无法添加可以解决此问题的 webhook。我想知道是否有解决方法?
我试过更换
sh 'mvn clean package sonar:sonar '
和
sh 'mvn clean package sonar:sonar -Dsonar.webhooks.project=https://my-jenkins-server.com/sonarqube-webhook/'
但一无所获。
我也尝试适应
实际上有一种方法可以解决这个问题。正确的解决方法是将 webhook 安装回 Jenkins,但您显然无法解决这个问题。
下一个“正确的”修复是使用 SonarQube REST api,但首先我需要解释“waitForQualityGate()”中发生的事情。
它做的第一件事是使用 REST api 端点“/api/ce/task”查看后台任务是否完成。它从“report-task.txt”文件中获取要检查的任务 ID,该文件的格式类似于属性文件。如果第一次检查不是 SUCCESS 或 ERROR,那么它会进入等待循环,等待调用 webhook。
因此,您可以通过简单地添加比后台任务花费的秒数更多的“睡眠”,然后调用“waitForQualityGate()”来实现一个非常便宜的修复。
更合适的修复方法如下:
def reportFilePath = "target/sonar/report-task.txt"
def reportTaskFileExists = fileExists "${reportFilePath}"
if (reportTaskFileExists) {
echo "Found report task file"
def taskProps = readProperties file: "${reportFilePath}"
echo "taskId[${taskProps['ceTaskId']}]"
while (true) {
sleep 20
def taskStatusResult =
sh(returnStdout: true,
script: "curl -s -X GET -u ${authString} \'${sonarProps['sonar.host.url']}/api/ce/task?id=${taskProps['ceTaskId']}\'")
echo "taskStatusResult[${taskStatusResult}]"
def taskStatus = new JsonSlurper().parseText(taskStatusResult).task.status
echo "taskStatus[${taskStatus}]"
// Status can be SUCCESS, ERROR, PENDING, or IN_PROGRESS. The last two indicate it's
// not done yet.
if (taskStatus != "IN_PROGRESS" && taskStatus != "PENDING") {
break;
}
}
}