在 jenkins 管道节点内时,Sonarqube 质量门卡在待定状态
Sonarqube quality gate stuck on pending when inside jenkins pipeline node
我们正在尝试将 Sonarqube 扫描添加到我们的 Jenkins 管道脚本中。
我们有一个多模块 Maven 项目,我们正在使用 Maven Sonarqube 插件来 运行 聚合扫描。为了启动扫描,我们按照 Sonarqube 文档中的说明进行操作,如图所示 here(向下滚动到页面末尾)。
所以管道脚本看起来像这样:
node {
stage('SonarQube analysis') {
withSonarQubeEnv('My SonarQube Server') {
sh 'mvn clean package sonar:sonar'
}
}
}
stage("Quality Gate") {
timeout(time: 1, unit: 'HOURS') {
def qg = waitForQualityGate()
if (qg.status != 'OK') {
error "Pipeline aborted due to quality gate failure: ${qg.status}"
}
}
}
并且它按预期工作。但是因为我们在多个文件中使用它,所以我们希望尽可能减少重复代码,所以我们希望将它放在节点中,如下所示:
node {
stage('SonarQube analysis') {
withSonarQubeEnv('My SonarQube Server') {
sh 'mvn clean package sonar:sonar'
}
}
stage("Quality Gate") {
timeout(time: 1, unit: 'HOURS') {
def qg = waitForQualityGate()
if (qg.status != 'OK') {
error "Pipeline aborted due to quality gate failure: ${qg.status}"
}
}
}
}
但由于某种原因,这会使质量门卡在 PENDING 状态,直到达到超时为止。
我试图了解为什么会发生这种情况,以及可以采取哪些措施来避免将质量门检查移到节点之外。
如有任何帮助,我们将不胜感激!
waitForQualityGate
对 SonarQube 服务器执行 HTTP call。
确保您的构建节点具有对您的 SonarQube 实例的 HTTP 访问权限(能够访问它的 Jenkins master 并不意味着构建节点也具有它)。
无论如何,正如我在评论中所说,在 node
中使用等待步骤通常不是一个好主意。
我也遇到了同样的问题,我通过在 waitForQualityGate
阶段
之前添加睡眠来解决它
sleep 10
stage("Quality Gate") {
timeout(time: 1, unit: 'HOURS') {
def qg = waitForQualityGate()
if (qg.status != 'OK') {
error "Pipeline aborted due to quality gate failure: ${qg.status}"
}
}
}
这可能是更好的重试方法。
def retryForTimeoutExceeded(count = 3, Closure closure) {
for (int i = 1; i <= count; i++) {
try {
closure()
break
} catch (FlowInterruptedException error) {
int retriesLeft = count - i
def hasTimeoutExceeded = error.causes[0].getClass().toString() == 'class org.jenkinsci.plugins.workflow.steps.TimeoutStepExecution$ExceededTimeout'
println "Timeout Exceeded for clousre.\nRetries left: $retriesLeft"
if (retriesLeft == 0 || !hasTimeoutExceeded) {
throw error
}
}
}
}
stage("Quality Gate") {
retryForTimeoutExceeded {
timeout(time: 5, unit: 'MINUTES') {
// Just in case something goes wrong, pipeline will be killed after a timeout
def qg = waitForQualityGate() // Reuse taskId previously collected by withSonarQubeEnv
if (qg.status != 'OK') {
error "Pipeline aborted due to sonar quality gate failure: ${qg.status}"
}
}
}
}
可以相应地配置超时
我们正在尝试将 Sonarqube 扫描添加到我们的 Jenkins 管道脚本中。 我们有一个多模块 Maven 项目,我们正在使用 Maven Sonarqube 插件来 运行 聚合扫描。为了启动扫描,我们按照 Sonarqube 文档中的说明进行操作,如图所示 here(向下滚动到页面末尾)。
所以管道脚本看起来像这样:
node {
stage('SonarQube analysis') {
withSonarQubeEnv('My SonarQube Server') {
sh 'mvn clean package sonar:sonar'
}
}
}
stage("Quality Gate") {
timeout(time: 1, unit: 'HOURS') {
def qg = waitForQualityGate()
if (qg.status != 'OK') {
error "Pipeline aborted due to quality gate failure: ${qg.status}"
}
}
}
并且它按预期工作。但是因为我们在多个文件中使用它,所以我们希望尽可能减少重复代码,所以我们希望将它放在节点中,如下所示:
node {
stage('SonarQube analysis') {
withSonarQubeEnv('My SonarQube Server') {
sh 'mvn clean package sonar:sonar'
}
}
stage("Quality Gate") {
timeout(time: 1, unit: 'HOURS') {
def qg = waitForQualityGate()
if (qg.status != 'OK') {
error "Pipeline aborted due to quality gate failure: ${qg.status}"
}
}
}
}
但由于某种原因,这会使质量门卡在 PENDING 状态,直到达到超时为止。 我试图了解为什么会发生这种情况,以及可以采取哪些措施来避免将质量门检查移到节点之外。
如有任何帮助,我们将不胜感激!
waitForQualityGate
对 SonarQube 服务器执行 HTTP call。
确保您的构建节点具有对您的 SonarQube 实例的 HTTP 访问权限(能够访问它的 Jenkins master 并不意味着构建节点也具有它)。
无论如何,正如我在评论中所说,在 node
中使用等待步骤通常不是一个好主意。
我也遇到了同样的问题,我通过在 waitForQualityGate
阶段
sleep 10
stage("Quality Gate") {
timeout(time: 1, unit: 'HOURS') {
def qg = waitForQualityGate()
if (qg.status != 'OK') {
error "Pipeline aborted due to quality gate failure: ${qg.status}"
}
}
}
这可能是更好的重试方法。
def retryForTimeoutExceeded(count = 3, Closure closure) {
for (int i = 1; i <= count; i++) {
try {
closure()
break
} catch (FlowInterruptedException error) {
int retriesLeft = count - i
def hasTimeoutExceeded = error.causes[0].getClass().toString() == 'class org.jenkinsci.plugins.workflow.steps.TimeoutStepExecution$ExceededTimeout'
println "Timeout Exceeded for clousre.\nRetries left: $retriesLeft"
if (retriesLeft == 0 || !hasTimeoutExceeded) {
throw error
}
}
}
}
stage("Quality Gate") {
retryForTimeoutExceeded {
timeout(time: 5, unit: 'MINUTES') {
// Just in case something goes wrong, pipeline will be killed after a timeout
def qg = waitForQualityGate() // Reuse taskId previously collected by withSonarQubeEnv
if (qg.status != 'OK') {
error "Pipeline aborted due to sonar quality gate failure: ${qg.status}"
}
}
}
}
可以相应地配置超时