はじめに
こんにちは株式会社TIELECのタカシユウトです。この記事ではJenkinsのBlue Ocean REST APIについて紹介します。Blue Ocean REST APIは、Blue Ocean UIで表示される情報をプログラムから取得するためのAPIです。
Blue Ocean REST API
https://github.com/jenkinsci/blueocean-plugin/tree/master/blueocean-rest
最後にBlue Ocean REST APIについての紹介です。 こちらはJenkinsのBlue Oceanのプラグインを入れことにより使えるようになります。
エンドポイントはJenkinsのURLの後ろに/blue/restをつけたものになります。
userやsearchなど様々なエンドポイントがありそうですがよく使いそうなのはとorganizationsになりそうです。
Jenkinsのジョブの情報などを取得する際もorganizationsを使って確認していきます。
では実際に確認していきましょう。 /blue/rest/organizations http://jenkins.tielec.blog:8080/blue/rest/organizations/
[
{
"_class":"io.jenkins.blueocean.service.embedded.rest.OrganizationImpl",
"_links":{
"pipelines":{
"_class":"io.jenkins.blueocean.rest.hal.Link",
"href":"/blue/rest/organizations/jenkins/pipelines/"
},
"self":{
"_class":"io.jenkins.blueocean.rest.hal.Link",
"href":"/blue/rest/organizations/jenkins/"
},
"user":{
"_class":"io.jenkins.blueocean.rest.hal.Link",
"href":"/blue/rest/organizations/jenkins/user/"
},
"users":{
"_class":"io.jenkins.blueocean.rest.hal.Link",
"href":"/blue/rest/organizations/jenkins/users/"
}
},
"displayName":"Jenkins",
"name":"jenkins"
}
]
エンドポイントの情報が見れています。
今回もジョブの情報を見るところまでやっていきたいので、pipelinesを開いてみます。
パイプラインの情報を取得する
/blue/rest/organizations/jenkins/pipelinesフォルダを指定する場合は/pipelines/の後ろに追加します。 http://jenkins.tielec.blog:8080/blue/rest/organizations/jenkins/pipelines/decrative-pipeline
Jsonをクリックで展開します
{
"_class": "io.jenkins.blueocean.service.embedded.rest.PipelineFolderImpl",
"_links": {
"self": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/"
},
"scm": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/scm/"
},
"actions": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/actions/"
},
"runs": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/runs/"
},
"trends": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/trends/"
},
"queue": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/queue/"
}
},
"actions": [],
"disabled": false,
"displayName": "decrative-pipeline",
"fullDisplayName": "decrative-pipeline",
"fullName": "decrative-pipeline",
"name": "decrative-pipeline",
"organization": "jenkins",
"parameters": null,
"permissions": {
"create": false,
"configure": false,
"read": true,
"start": true,
"stop": false
},
"numberOfFolders": 0,
"numberOfPipelines": 25,
"pipelineFolderNames": [
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null
]
}
フォルダの名称等はわかりましたが、piplineの一覧みたいな情報は取れませんでした。
ジョブの詳細を取得
ジョブの詳細を取得する場合はさらにURLの後ろにジョブ名を追加します。 http://jenkins.tielec.blog:8080/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/03_write_file/

{
"_class": "io.jenkins.blueocean.rest.impl.pipeline.PipelineImpl",
"_links": {
"self": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/"
},
"scm": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/scm/"
},
"actions": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/actions/"
},
"runs": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/"
},
"trends": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/trends/"
},
"queue": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/queue/"
}
},
"actions": [],
"disabled": false,
"displayName": "03_write_file",
"estimatedDurationInMillis": 18597,
"fullDisplayName": "decrative-pipeline/03_write_file",
"fullName": "decrative-pipeline/03_write_file",
"latestRun": {
"_class": "io.jenkins.blueocean.rest.impl.pipeline.PipelineImpl$PipelineRunSummary",
"_links": {
"prevRun": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/16/"
},
"parent": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/"
},
"tests": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/tests/"
},
"log": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/log/"
},
"self": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/"
},
"blueTestSummary": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/blueTestSummary/"
},
"actions": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/actions/"
},
"changeSet": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/changeSet/"
},
"artifacts": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/artifacts/"
}
},
"actions": [],
"artifactsZipFile": null,
"causeOfBlockage": null,
"causes": [
{
"_class": "io.jenkins.blueocean.service.embedded.rest.AbstractRunImpl$BlueCauseImpl",
"shortDescription": "Started by upstream project "decrative-pipeline/08_parallel_step" build number 9",
"upstreamBuild": 9,
"upstreamProject": "decrative-pipeline/08_parallel_step",
"upstreamUrl": "job/decrative-pipeline/job/08_parallel_step/"
}
],
"description": null,
"durationInMillis": 47339,
"enQueueTime": "2019-08-30T12:43:06.337+0900",
"endTime": "2019-08-30T12:43:53.687+0900",
"estimatedDurationInMillis": 18597,
"id": "17",
"name": null,
"organization": "jenkins",
"pipeline": "03_write_file",
"replayable": true,
"result": "SUCCESS",
"runSummary": "stable",
"startTime": "2019-08-30T12:43:06.348+0900",
"state": "FINISHED",
"type": "WorkflowRun",
"changeSet": [
{
"_class": "io.jenkins.blueocean.service.embedded.rest.ChangeSetResource",
"_links": {
"self": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/changeSet/2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f/"
}
},
"affectedPaths": [
"pipeline/decrative-pipeline/pipeline_19_random_kitten_generator.groovy"
],
"author": {
"_class": "io.jenkins.blueocean.service.embedded.rest.UserImpl",
"_links": {
"favorites": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/users/noreply/favorites/"
},
"self": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/users/noreply/"
}
},
"avatar": null,
"email": null,
"fullName": "noreply",
"id": "noreply",
"permission": null
},
"checkoutCount": 0,
"commitId": "2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f",
"issues": [],
"msg": "Update pipeline_19_random_kitten_generator.groovy",
"timestamp": "2019-08-10T19:11:25.000+0900",
"url": "https://github.com/sakamaki-y123/jenkins-continuous-delivery/commit/2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f"
}
]
},
"name": "03_write_file",
"organization": "jenkins",
"parameters": [
{
"_class": "hudson.model.TextParameterDefinition",
"defaultParameterValue": {
"_class": "hudson.model.StringParameterValue",
"name": "OUTPUT_TEXT",
"value": ""
},
"description": "",
"name": "OUTPUT_TEXT",
"type": "TextParameterDefinition"
}
],
"permissions": {
"create": false,
"configure": false,
"read": true,
"start": true,
"stop": false
},
"weatherScore": 100
}
ジョブの開始時間、終了時間、ステータス、チェンジセットなど様々な情報が取れています。 Pipeline REST APIよりも一回の情報量は多いですね。ビルド履歴に関しては取れていません。
ビルド履歴を取得する
ビルド履歴を取得するエンドポイントはrunsになります。 取得してみます。 http://jenkins.tielec.blog:8080/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/03_write_file/runs/
Jsonをクリックで展開します
[
{
"_class": "io.jenkins.blueocean.rest.impl.pipeline.PipelineRunImpl",
"_links": {
"prevRun": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/16/"
},
"parent": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/"
},
"tests": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/tests/"
},
"nodes": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/nodes/"
},
"log": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/log/"
},
"self": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/"
},
"blueTestSummary": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/blueTestSummary/"
},
"actions": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/actions/"
},
"steps": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/steps/"
},
"changeSet": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/changeSet/"
},
"artifacts": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/artifacts/"
}
},
"actions": [],
"artifactsZipFile": null,
"causeOfBlockage": null,
"causes": [
{
"_class": "io.jenkins.blueocean.service.embedded.rest.AbstractRunImpl$BlueCauseImpl",
"shortDescription": "Started by upstream project "decrative-pipeline/08_parallel_step" build number 9",
"upstreamBuild": 9,
"upstreamProject": "decrative-pipeline/08_parallel_step",
"upstreamUrl": "job/decrative-pipeline/job/08_parallel_step/"
}
],
"description": null,
"durationInMillis": 47339,
"enQueueTime": "2019-08-30T12:43:06.337+0900",
"endTime": "2019-08-30T12:43:53.687+0900",
"estimatedDurationInMillis": 18597,
"id": "17",
"name": null,
"organization": "jenkins",
"pipeline": "03_write_file",
"replayable": true,
"result": "SUCCESS",
"runSummary": "stable",
"startTime": "2019-08-30T12:43:06.348+0900",
"state": "FINISHED",
"type": "WorkflowRun",
"changeSet": [
{
"_class": "io.jenkins.blueocean.service.embedded.rest.ChangeSetResource",
"_links": {
"self": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/changeSet/2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f/"
}
},
"affectedPaths": [
"pipeline/decrative-pipeline/pipeline_19_random_kitten_generator.groovy"
],
"author": {
"_class": "io.jenkins.blueocean.service.embedded.rest.UserImpl",
"_links": {
"favorites": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/users/noreply/favorites/"
},
"self": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/users/noreply/"
}
},
"avatar": null,
"email": null,
"fullName": "noreply",
"id": "noreply",
"permission": null
},
"checkoutCount": 0,
"commitId": "2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f",
"issues": [],
"msg": "Update pipeline_19_random_kitten_generator.groovy",
"timestamp": "2019-08-10T19:11:25.000+0900",
"url": "https://github.com/sakamaki-y123/jenkins-continuous-delivery/commit/2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f"
}
],
"branch": null,
"commitId": null,
"commitUrl": null,
"pullRequest": null
},
{
"_class": "io.jenkins.blueocean.rest.impl.pipeline.PipelineRunImpl",
"_links": {
"prevRun": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/15/"
},
"parent": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/"
},
"tests": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/16/tests/"
},
"nodes": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/16/nodes/"
},
"log": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/16/log/"
},
"self": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/16/"
},
"blueTestSummary": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/16/blueTestSummary/"
},
"actions": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/16/actions/"
},
"steps": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/16/steps/"
},
"changeSet": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/16/changeSet/"
},
"artifacts": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/16/artifacts/"
},
"nextRun": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/"
}
},
"actions": [],
"artifactsZipFile": null,
"causeOfBlockage": null,
"causes": [
{
"_class": "io.jenkins.blueocean.service.embedded.rest.AbstractRunImpl$BlueCauseImpl",
"shortDescription": "Started by upstream project "decrative-pipeline/08_parallel_step" build number 8",
"upstreamBuild": 8,
"upstreamProject": "decrative-pipeline/08_parallel_step",
"upstreamUrl": "job/decrative-pipeline/job/08_parallel_step/"
}
],
"description": null,
"durationInMillis": 6335,
"enQueueTime": "2019-05-10T14:41:05.305+0900",
"endTime": "2019-05-10T14:41:11.660+0900",
"estimatedDurationInMillis": 18597,
"id": "16",
"name": null,
"organization": "jenkins",
"pipeline": "03_write_file",
"replayable": true,
"result": "SUCCESS",
"runSummary": "stable",
"startTime": "2019-05-10T14:41:05.325+0900",
"state": "FINISHED",
"type": "WorkflowRun",
"changeSet": [],
"branch": null,
"commitId": null,
"commitUrl": null,
"pullRequest": null
},
{
"_class": "io.jenkins.blueocean.rest.impl.pipeline.PipelineRunImpl",
"_links": {
"prevRun": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/14/"
},
"parent": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/"
},
"tests": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/15/tests/"
},
"nodes": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/15/nodes/"
},
"log": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/15/log/"
},
"self": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/15/"
},
"blueTestSummary": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/15/blueTestSummary/"
},
"actions": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/15/actions/"
},
"steps": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/15/steps/"
},
"changeSet": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/15/changeSet/"
},
"artifacts": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/15/artifacts/"
},
"nextRun": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/16/"
}
},
"actions": [],
"artifactsZipFile": null,
"causeOfBlockage": null,
"causes": [
{
"_class": "io.jenkins.blueocean.service.embedded.rest.AbstractRunImpl$BlueCauseImpl",
"shortDescription": "Started by user anonymous",
"userId": null,
"userName": "anonymous"
},
{
"_class": "io.jenkins.blueocean.service.embedded.rest.AbstractRunImpl$BlueCauseImpl",
"shortDescription": "Restarted from build #14, stage write file"
}
],
"description": null,
"durationInMillis": 2117,
"enQueueTime": "2019-04-05T14:34:10.771+0900",
"endTime": "2019-04-05T14:34:12.894+0900",
"estimatedDurationInMillis": 18597,
"id": "15",
"name": null,
"organization": "jenkins",
"pipeline": "03_write_file",
"replayable": true,
"result": "SUCCESS",
"runSummary": "stable",
"startTime": "2019-04-05T14:34:10.777+0900",
"state": "FINISHED",
"type": "WorkflowRun",
"changeSet": [],
"branch": null,
"commitId": null,
"commitUrl": null,
"pullRequest": null
},
{
"_class": "io.jenkins.blueocean.rest.impl.pipeline.PipelineRunImpl",
"_links": {
"prevRun": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/13/"
},
"parent": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/"
},
"tests": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/14/tests/"
},
"nodes": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/14/nodes/"
},
"log": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/14/log/"
},
"self": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/14/"
},
"blueTestSummary": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/14/blueTestSummary/"
},
"actions": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/14/actions/"
},
"steps": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/14/steps/"
},
"changeSet": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/14/changeSet/"
},
"artifacts": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/14/artifacts/"
},
"nextRun": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/15/"
}
},
"actions": [],
"artifactsZipFile": null,
"causeOfBlockage": null,
"causes": [
{
"_class": "io.jenkins.blueocean.service.embedded.rest.AbstractRunImpl$BlueCauseImpl",
"shortDescription": "Started by user anonymous",
"userId": null,
"userName": "anonymous"
}
],
"description": null,
"durationInMillis": 6006,
"enQueueTime": "2019-04-05T14:33:09.167+0900",
"endTime": "2019-04-05T14:33:15.175+0900",
"estimatedDurationInMillis": 18597,
"id": "14",
"name": null,
"organization": "jenkins",
"pipeline": "03_write_file",
"replayable": true,
"result": "SUCCESS",
"runSummary": "stable",
"startTime": "2019-04-05T14:33:09.169+0900",
"state": "FINISHED",
"type": "WorkflowRun",
"changeSet": [],
"branch": null,
"commitId": null,
"commitUrl": null,
"pullRequest": null
},
{
"_class": "io.jenkins.blueocean.rest.impl.pipeline.PipelineRunImpl",
"_links": {
"parent": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/"
},
"tests": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/13/tests/"
},
"nodes": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/13/nodes/"
},
"log": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/13/log/"
},
"self": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/13/"
},
"blueTestSummary": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/13/blueTestSummary/"
},
"actions": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/13/actions/"
},
"steps": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/13/steps/"
},
"changeSet": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/13/changeSet/"
},
"artifacts": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/13/artifacts/"
},
"nextRun": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/14/"
}
},
"actions": [],
"artifactsZipFile": null,
"causeOfBlockage": null,
"causes": [
{
"_class": "io.jenkins.blueocean.service.embedded.rest.AbstractRunImpl$BlueCauseImpl",
"shortDescription": "Started by user anonymous",
"userId": null,
"userName": "anonymous"
}
],
"description": null,
"durationInMillis": 6035,
"enQueueTime": "2019-03-13T23:14:12.526+0900",
"endTime": "2019-03-13T23:14:18.565+0900",
"estimatedDurationInMillis": 18597,
"id": "13",
"name": null,
"organization": "jenkins",
"pipeline": "03_write_file",
"replayable": true,
"result": "SUCCESS",
"runSummary": "stable",
"startTime": "2019-03-13T23:14:12.530+0900",
"state": "FINISHED",
"type": "WorkflowRun",
"changeSet": [],
"branch": null,
"commitId": null,
"commitUrl": null,
"pullRequest": null
}
]
こちらもかなり細かく情報が取れています。
最後にビルド結果を見てみます。 ビルド結果はrunsの後ろにビルド番号を追加すると取得できます。 http://jenkins.tielec.blog:8080/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/03_write_file/runs/17
Jsonをクリックで展開します
{
"_class": "io.jenkins.blueocean.rest.impl.pipeline.PipelineRunImpl",
"_links": {
"prevRun": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/16/"
},
"parent": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/"
},
"tests": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/tests/"
},
"nodes": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/nodes/"
},
"log": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/log/"
},
"self": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/"
},
"blueTestSummary": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/blueTestSummary/"
},
"actions": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/actions/"
},
"steps": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/steps/"
},
"changeSet": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/changeSet/"
},
"artifacts": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/artifacts/"
}
},
"actions": [],
"artifactsZipFile": null,
"causeOfBlockage": null,
"causes": [
{
"_class": "io.jenkins.blueocean.service.embedded.rest.AbstractRunImpl$BlueCauseImpl",
"shortDescription": "Started by upstream project "decrative-pipeline/08_parallel_step" build number 9",
"upstreamBuild": 9,
"upstreamProject": "decrative-pipeline/08_parallel_step",
"upstreamUrl": "job/decrative-pipeline/job/08_parallel_step/"
}
],
"description": null,
"durationInMillis": 47339,
"enQueueTime": "2019-08-30T12:43:06.337+0900",
"endTime": "2019-08-30T12:43:53.687+0900",
"estimatedDurationInMillis": 18597,
"id": "17",
"name": null,
"organization": "jenkins",
"pipeline": "03_write_file",
"replayable": true,
"result": "SUCCESS",
"runSummary": "stable",
"startTime": "2019-08-30T12:43:06.348+0900",
"state": "FINISHED",
"type": "WorkflowRun",
"changeSet": [
{
"_class": "io.jenkins.blueocean.service.embedded.rest.ChangeSetResource",
"_links": {
"self": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/changeSet/2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f/"
}
},
"affectedPaths": [
"pipeline/decrative-pipeline/pipeline_19_random_kitten_generator.groovy"
],
"author": {
"_class": "io.jenkins.blueocean.service.embedded.rest.UserImpl",
"_links": {
"favorites": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/users/noreply/favorites/"
},
"self": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/users/noreply/"
}
},
"avatar": null,
"email": null,
"fullName": "noreply",
"id": "noreply",
"permission": null
},
"checkoutCount": 0,
"commitId": "2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f",
"issues": [],
"msg": "Update pipeline_19_random_kitten_generator.groovy",
"timestamp": "2019-08-10T19:11:25.000+0900",
"url": "https://github.com/sakamaki-y123/jenkins-continuous-delivery/commit/2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f"
}
],
"branch": null,
"commitId": null,
"commitUrl": null,
"pullRequest": null
}
ここでの情報は先ほどまで出てきた情報とあまり変わりがありませんが、logやstepsといったエンドポイントが扱えることがわかります。
stepsの内容を確認してみます。 http://jenkins.tielec.blog:8080/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/03_write_file/runs/17/steps

[
{
"_class": "io.jenkins.blueocean.rest.impl.pipeline.PipelineStepImpl",
"_links": {
"self": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/steps/7/"
},
"actions": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/steps/7/actions/"
}
},
"actions": [
{
"_class": "org.jenkinsci.plugins.workflow.support.actions.LogStorageAction",
"_links": {
"self": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/steps/7/log/"
}
},
"urlName": "log"
}
],
"displayDescription": null,
"displayName": "Check out from version control",
"durationInMillis": 2420,
"id": "7",
"input": null,
"result": "SUCCESS",
"startTime": "2019-08-30T12:43:50.731+0900",
"state": "FINISHED",
"type": "STEP"
},
{
"_class": "io.jenkins.blueocean.rest.impl.pipeline.PipelineStepImpl",
"_links": {
"self": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/steps/14/"
},
"actions": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/steps/14/actions/"
}
},
"actions": [
{
"_class": "org.jenkinsci.plugins.workflow.support.actions.LogStorageAction",
"_links": {
"self": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/steps/14/log/"
}
},
"urlName": "log"
}
],
"displayDescription": "output.txt",
"displayName": "Write file to workspace",
"durationInMillis": 4,
"id": "14",
"input": null,
"result": "SUCCESS",
"startTime": "2019-08-30T12:43:53.230+0900",
"state": "FINISHED",
"type": "STEP"
}
]
Pipelineで実行されているstepごとの実行時間が取得できています。ここまでの情報はPipeline REST APIでは取れなかったと思います。
stepにはIDが振られておりさらに掘り下げて確認することができます。
http://jenkins.tielec.blog:8080/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/03_write_file/runs/17/steps/7/
{
"_class": "io.jenkins.blueocean.rest.impl.pipeline.PipelineStepImpl",
"_links": {
"self": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/steps/7/"
},
"actions": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/steps/7/actions/"
}
},
"actions": [
{
"_class": "org.jenkinsci.plugins.workflow.support.actions.LogStorageAction",
"_links": {
"self": {
"_class": "io.jenkins.blueocean.rest.hal.Link",
"href": "/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/pipelines/03_write_file/runs/17/steps/7/log/"
}
},
"urlName": "log"
}
],
"displayDescription": null,
"displayName": "Check out from version control",
"durationInMillis": 2420,
"id": "7",
"input": null,
"result": "SUCCESS",
"startTime": "2019-08-30T12:43:50.731+0900",
"state": "FINISHED",
"type": "STEP"
}
さらにlogのエンドポイントがあるので、ステップごとのログが取得できそうです。
ステップのログを確認してみます。 http://jenkins.tielec.blog:8080/blue/rest/organizations/jenkins/pipelines/decrative-pipeline/03_write_file/runs/17/steps/7/log

No credentials specified
Cloning the remote Git repository
Cloning repository https://github.com/sakamaki-y123/jenkins-continuous-delivery.git
> git init /var/lib/jenkins/workspace/decrative-pipeline/03_write_file # timeout=10
Fetching upstream changes from https://github.com/sakamaki-y123/jenkins-continuous-delivery.git
> git --version # timeout=10
> git fetch --tags --progress https://github.com/sakamaki-y123/jenkins-continuous-delivery.git +refs/heads/*:refs/remotes/origin/*
> git config remote.origin.url https://github.com/sakamaki-y123/jenkins-continuous-delivery.git # timeout=10
> git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
> git config remote.origin.url https://github.com/sakamaki-y123/jenkins-continuous-delivery.git # timeout=10
Fetching upstream changes from https://github.com/sakamaki-y123/jenkins-continuous-delivery.git
> git fetch --tags --progress https://github.com/sakamaki-y123/jenkins-continuous-delivery.git +refs/heads/*:refs/remotes/origin/*
> git rev-parse refs/remotes/origin/master^{commit} # timeout=10
> git rev-parse refs/remotes/origin/origin/master^{commit} # timeout=10
Checking out Revision 2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f (refs/remotes/origin/master)
> git config core.sparsecheckout # timeout=10
> git checkout -f 2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f
Commit message: "Update pipeline_19_random_kitten_generator.groovy"
BlueOceanで確認できるログが取得できました。
まとめ
APIを使うとJenkinsの情報を色々取得することができます。 この記事では以下の3種類のAPIを紹介しました。
- Remote access API
- Pipeline REST API
- Blue Ocean REST API
それぞれのAPIで取得できる情報の粒度がだいぶ違うので用途に合わせて使い分けることができればやれることの幅が広がると思います。
Remote access API を使って全体的な大まかな情報を取得、Pipeline REST API を使って細かな情報の取得。 さらにpipelineのステップごとの情報といったより細かな情報を取得するときは Blue Ocean REST APIと使い分けるのがポイントだと思いました。
3つのAPIは取れる情報が重複する部分もありますが、そのAPIでしか取れない情報もあるので色々と眺めてみると面白いのでなないでしょうか?
Pipeline には readJSON という便利なステップがあるので、組み合わせて使うと色々と情報の加工ができると思います。また、pythonやほかの言語を使っていろいろとジョブの分析をしたりといったことができそうです。
まとめ
この記事では、JenkinsのAPIを使ってジョブの情報を取得する方法について紹介しました。APIを活用することで、Jenkinsの情報をプログラムから取得したり、自動化を進めることができます。
おすすめ書籍
[
[改訂第3版]Jenkins実践入門 ――ビルド・テスト・デプロイを自動化する技術 (WEB+DB PRESS plus)
[
Jenkins
[
サーバ/インフラエンジニアの基本がこれ1冊でしっかり身につく本

コメント