在Jenkins管道中按顺序运行多个异步步骤的最佳方法

时间:2016-03-13 05:00:55

标签: jenkins jenkins-workflow jenkins-pipeline

首先让我简单介绍一下我想要实现的用例。

上下文

  • 我正在使用Spring Boot开发一个服务器应用程序并使用maven来构建它。
  • 应用程序需要Redis数据库,因此我可以在构建应用程序并启动并运行Redis数据库后启动该应用程序。
  • 我正在用JavaScript编写REST API测试,一旦我的应用程序启动,我就可以运行它们。

实施

  • 要构建应用程序,不需要任何特殊内容。我可以做一个mvn clean install。我也可以用mvn package创建一个可执行jar,我可以在Docker镜像中使用它。
  • 为了运行应用程序,我使用Docker Compose来表达我的应用程序和Redis之间的依赖关系。我可以使用docker-compose up启动我的环境。 这很好,但这是一个异步的步骤:我不知道让所有服务完全启动接受请求需要多长时间
  • 当我知道应用程序准备就绪后,我就可以启动用JavaScript编写的API测试。
  • 在流程结束时,我可以执行docker-compose down来拆除测试环境。

问题

  • 我正在寻找有关处理异步步骤的建议。在这个简化的示例中,有一个步骤:如何处理redis需要一些时间(例如5-15秒)以及应用程序完全启动的事实?
  • 我可以在这种情况下使用Jenkins Pipeline插件的功能吗?我无法在教程或文档中找到很多信息。我见过waitUntil步骤,但我正在寻找一些指导......
  • 我是否应该实现一个简单的shell脚本,该脚本会在循环中向我的某个应用REST端点发出HTTP请求,并在应用发送响应后立即完成?我应该在waitUntil步骤中调用此脚本吗?
  • 我的要求有更好的方法吗?

2 个答案:

答案 0 :(得分:0)

  

我是否应该实现一个简单的shell脚本,该脚本在循环中向我的某个应用REST端点发出HTTP请求,并在应用发送响应后立即完成?我应该在waitUntil步骤中调用此脚本吗?

是的,这是一种合法的方法。

您也可以将其折叠到运行测试的脚本中。为了使Pipeline脚本保持简洁和重点,并使其更容易单独测试逻辑,将该脚本存储在SCM中。假设它是在Bash中(但Python或其他什么工作正常):

while :
do
  if curl http://endpoint/
  then
    echo Up and running
    break
  else
    echo Still waiting
  fi
done
make test

然后您的Pipeline脚本可以读取类似

的内容
node {
  stage 'build'
  checkout scm
  sh 'mvn clean install'
  stage 'test'
  sh 'docker-compose up'
  try {
    sh './run-tests-when-ready'
  finally {
    sh 'docker-compose down'
  }
}

当然,如果您愿意,可以将对docker-compose的调用放入这样的外部脚本中。在Bash中可以可靠地进行清理(可以使用trap EXIT '…'),在实际语言中更容易。

答案 1 :(得分:0)

我最终在Jenkinsfile中做了类似的事情:

stage 'Validation'
  dir("microservice") {
  sh "docker-compose down"
  sh "docker-compose up &"
}

waitUntil {
    def appIsReady = false
    try {
        echo "Checking Spring Boot status page via ${GAMEDOCK_URL}"
        sh "set +e; curl -f -sL -w \"%{http_code}\\n\" ${GAMEDOCK_URL} -o /dev/null; echo \$? > springBootAppStatus; return 0"
        def status = readFile('springBootAppStatus').trim()
        echo 'status: ' + status
        appIsReady = (status == '0')
    } catch (e) {
        echo 'exception: ' + e
        appIsReady = false
    }
    echo 'return appIsReady'
    return appIsReady == true

}

   echo "application is ready"