检索远程触发的jenkins作业的id

时间:2014-07-01 09:50:25

标签: jenkins

我通过http POST请求从jenkins外部触发参数化Jenkins:

我已在作业配置中启用该作业可以从外部触发,我可以通过向jenkins发送包含以下内容的请求来真正触发它:

POST
http://myJenkins.com/myJob/buildWithParameters?token=MYTOKEN 参数:SCREEN_SIZE:27

触发作业创建会返回成功的201 CREATED http响应。

我的问题是我不知道创建的构建作业的ID。我想监视工作的状态。为了做到这一点,我需要知道id。否则,如果我只是采取最新的工作,我可能会采取错误的工作。

是否有可靠的方法来获取已创建作业的ID?

5 个答案:

答案 0 :(得分:35)

自Jenkins 1.519以来,排队构建以Location中的URL响应,指向构建队列中的项目:

$ nc localhost 8666
POST /jenkins/job/morgRemote/buildWithParameters?jenkins_status=1&jenkins_sleep=20&token=morgRemote HTTP/1.1
Host: localhost:8666

HTTP/1.1 201 Created
Location: http://localhost:8666/jenkins/queue/item/39/
Content-Length: 0
Server: Jetty(winstone-2.8)

现在,如果您将api/json(或api/xml等等)添加到它的末尾(因此在此示例中它将是http://localhost:8666/jenkins/queue/item/39/api/json),那么您将获得一个文档包含给定作业的构建ID。对于json,检索到的对象具有executable属性,该属性又具有numberurl属性。 number是给定作业的构建ID(此处为35),url是jenkins构建页面URL。

{
  "actions" : [
    {
      "parameters" : [
        {
          "name" : "jenkins_status",
          "value" : "1"
        },
        {
          "name" : "jenkins_sleep",
          "value" : "20"
        }
      ]
    },
    {
      "causes" : [
        {
          "shortDescription" : "Started by remote host 127.0.0.1",
          "addr" : "127.0.0.1",
          "note" : null
        }
      ]
    }
  ],
  "blocked" : false,
  "buildable" : false,
  "id" : 39,
  "inQueueSince" : 1423993879845,
  "params" : "\njenkins_status=1\njenkins_sleep=20",
  "stuck" : false,
  "task" : {
    "name" : "morgRemote",
    "url" : "http://localhost:8666/jenkins/job/morgRemote/",
    "color" : "red"
  },
  "url" : "queue/item/39/",
  "why" : null,
  "cancelled" : false,
  "executable" : {
    "number" : 35,
    "url" : "http://localhost:8666/jenkins/job/morgRemote/35/"
  }
}

要注意两件事:

  • 构建队列中的非活动项目在几分钟后被垃圾回收,因此您应该检索构建ID ASAP
  • 默认情况下,将item添加到队列之间需要几秒钟,直到它获得构建ID。在此期间,executablecanceled属性将丢失,why将不为空。您可以在"高级项目选项"中更改此行为。你的工作配置通过修改"安静时期"设置或在jenkins全局配置中。

  ...
  "url" : "queue/item/39/",
  "why" : "In the quiet period. Expires in 2.4 sec",
  "timestamp" : 1423993879845
}

答案 1 :(得分:11)

<强>更新

other answer在我的后8个月后被添加。我当时没有意识到响应中的位置标题。对某些情况来说,这听起来不错。也就是说,基于答案中的警告和评论(特别是围绕参数化构建),似乎这个答案在某些情况下仍然具有一些实用性。

原始回答:

不幸的是,他们并没有尽可能简单明了。例如,通过使用 id 等信息返回 JSON 响应。

但是,我相信一个可靠但非常重要的解决方法是利用您用来触发构建的URL中的 cause 参数,并在此原因中添加< em>唯一文本,您可以稍后解析以确定是否从自动化中触发了它。

为了进一步确定特定作业的独特性,如果多个同时运行,即使从您的自动化,也包括某种类型的唯一ID (它可能只是您的序列ID) RDBMS 或类似的)在cause参数内。

然后,您可以使用 JSON API 获取有关您远程触发的作业的信息。同样,它有点间接,但可行:

点击表格的网址:

http://<server>:<port>/job/<jobname>/lastBuild/api/json

您可以添加?pretty=true以在浏览器中对其进行漂亮打印,以提高人类的可读性。

这将为您提供上一次构建的 JSON 。它将包含 actions 属性中的 cause 属性,并且在那里(在名为 shortDescription 的另一个嵌套属性中),您将找到如果这是您触发的构建之一,则会添加参数。

您可以解析特殊静态文本和生成的ID,以查看它们是否匹配。如果他们这样做,您也可以从 JSON 中获取 Jenkins id (搜索 buildNumber ,它是嵌套的)。

如果该构建要么根本不是由您的自动化触发,要么是,但是ID不匹配,您可以重复 N - 1构建的过程,直到找到您的内容为止正在寻找。

JSON的形式如下:

http://<server>:<port>/job/<jobname>/<buildNumber>/api/json

答案 2 :(得分:2)

结果构建具有原始队列ID。此外,您只能使用队列ID查询构建并轮询它,直到获得结果,因为404通常意味着它已排队。

将“队列ID”从“位置”标题中拉出,例如39

/jenkins/queue/item/39/

在获得答案之前,反复查询具有该队列号的构建

"http://{jenkins}job/{job}/api/xml?tree=builds[number,queueId]&xpath=//build[queueId=\"{queueId}\"]";

<build>
  <number>411</number>
  <queueId>39</queueId>
</build>

从此结果中,您可以使用xpath /build/number/text()

提取内部版本号

(注意我无法在网址中使用&xpath=//build[queueId={queueId}]/number/text()因为"primitive XPath result sets forbidden; implement jenkins.security.SecureRequester"

对于“可执行”构建轮询队列api同样是蹩脚的。一个优点是端点将持续更长时间 - 直到构建被删除,与任意时间(似乎约为5分钟)相比。

答案 3 :(得分:0)

我能够使用Java Jenkins api来实现您的目标。 https://github.com/jenkinsci/java-client-api

示例代码:

JenkinsServer jenkinsServer = new JenkinsServer(newURI("http://yourJenkinsServer:8080/"));
JobWithDetails smokeTestJob = jenkinsServer.getJob("YourJobName");        
Map<String,String> jobParams = new HashMap<String,String>();
QueueReference queueReference = smokeTestJob.build(jobParams);

do {
  Thread.sleep(2000L);
  queueItem = jenkinsServer.getQueueItem(queueReference);
  log("Job still in queue"+queueItem.getExecutable());
  } while (queueItem.getExecutable() == null);

Build build = jenkinsServer.getBuild(queueItem);

while(build.details().isBuilding()){
  log("Job still running");
  Thread.sleep(10000L);
}

log("Result="+build.details().getResult());

答案 4 :(得分:0)

想要使用Location标题添加到morgwai回答。

我刚刚解决了这个问题。 Location头之后的键是轮询作业队列条目,直到它有一个“可执行”条目,该条目给出了已经启动的作业号。

我给出了一个类似的问题的完整答案,我首先看到的并没有完全回答这个问题:

https://stackoverflow.com/a/48531874/9291603

来自Jenkins作业队列条目的JSON,带有可执行条目:

{
    "_class": "hudson.model.Queue$LeftItem",
    "actions": [
        {
            "_class": "hudson.model.CauseAction",
            "causes": [
                {
                    "_class": "hudson.model.Cause$RemoteCause",
                    "addr": "10.20.30.60",
                    "note": null,
                    "shortDescription": "Started by remote host 10.20.30.60"
                }
            ]
        }
    ],
    "blocked": false,
    "buildable": false,
    "cancelled": false,
    "executable": {
        "_class": "org.jenkinsci.plugins.workflow.job.WorkflowRun",
        "number": 45,
        "url": "http://192.168.115.187:8080/job/rf_systest/45/"
    },
    "id": 95,
    "inQueueSince": 1517342648136,
    "params": "",
    "stuck": false,
    "task": {
        "_class": "org.jenkinsci.plugins.workflow.job.WorkflowJob",
        "color": "blue_anime",
        "name": "rf_systest",
        "url": "http://192.168.115.187:8080/job/rf_systest/"
    },
    "url": "queue/item/95/",
    "why": null
}