はじめに
こんにちはSREエンジニアのMakiです。
この記事ではJenkinsで使えるAPIについて紹介します。
Jenkinsのジョブの実行結果や設定の情報をAPIを使って取得したいということってありませんか?
APIを使ってどんなことができるのかを紹介していきたいと思います。
Jenkins API について
JenkinsのAPIは何種類存在しているのか?
3種類のパターンはあるようです。
- Remote access API
- Pipeline REST API
- Blue Ocean REST API
では具体的にどんな情報が取れるのか紹介していきます。
コードが長い部分は折り畳みになっています。
Jsonをクリックで展開します
と書かれた部分を押すとコードを表示できます。
Remote access API
https://wiki.jenkins.io/display/JA/Remote+access+API
もっとも初期からあると思われるAPIです。
具体的には次のようなことができます。
- プログラムでJenkinsから情報を取得する
- 新しいビルドを起動する
- ジョブの作成、コピー
といったことができます。
使い方としてはURLの後ろに /api/json
とつければ 色々情報が取れますというもの。
フォルダの情報取得
以下のページからdecrative-pipeline
という名称のフォルダより情報を取得してみます。
http://jenkins.tielec.blog:8080/job/decrative-pipeline/
APIで情報を取得します。
http://jenkins.tielec.blog:8080/job/decrative-pipeline/api/json
見やすいように整形したものがこちらです。
Jsonをクリックで展開します
{ "_class":"com.cloudbees.hudson.plugins.folder.Folder", "actions":[ { }, { }, { }, { }, { }, { "_class":"com.cloudbees.plugins.credentials.ViewCredentialsAction" } ], "description":"repository: https://github.com/sakamaki-y123/jenkins-continuous-delivery", "displayName":"decrative-pipeline", "displayNameOrNull":null, "fullDisplayName":"decrative-pipeline", "fullName":"decrative-pipeline", "name":"decrative-pipeline", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/", "healthReport":[ { "description":"Worst health: decrative-pipeline » 07_read_json: Build stability: 3 out of the last 5 builds failed.", "iconClassName":"icon-health-20to39", "iconUrl":"health-20to39.png", "score":40 } ], "jobs":[ { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"01_hello_world", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/01_hello_world/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"02_use_sh_step", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/02_use_sh_step/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"03_write_file", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/03_write_file/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"04_archive_artifacts", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/04_archive_artifacts/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"05_clean_workspace", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/05_clean_workspace/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"06_copy_artifacts", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/06_copy_artifacts/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"07_read_json", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/07_read_json/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"08_parallel_step", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/08_parallel_step/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"09_agent_docker", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/09_agent_docker/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"10_use_multiple_docker", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/10_use_multiple_docker/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"11_read_and_write_yaml", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/11_read_and_write_yaml/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"12_input_request", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/12_input_request/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"13_conditional_run_stage", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/13_conditional_run_stage/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"14_run_ansible", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/14_run_ansible/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"15_use_shared_library", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/15_use_shared_library/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"16_use_global_variables", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/16_use_global_variables/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"17_nested_stage", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/17_nested_stage/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"18_matrix_build", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/18_matrix_build/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"19_random_kitten_generator", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/19_random_kitten_generator/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"20_search_youtube_video", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/20_search_youtube_video/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"21_amazon_translator", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/21_amazon_translator/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"22_download_hot_bokete_images", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/22_download_hot_bokete_images/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"23_download_random_kitten_images", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/23_download_random_kitten_images/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"24_download_beautiful_landscape-video", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/24_download_beautiful_landscape-video/", "color":"blue" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "name":"25_upload_artifact_to_dropbox", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/25_upload_artifact_to_dropbox/", "color":"blue" } ], "primaryView":{ "_class":"hudson.model.AllView", "name":"all", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/" }, "views":[ { "_class":"hudson.model.AllView", "name":"all", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/" } ] }
フォルダ内にあるジョブのURLや名前などが確認できてきます。
ジョブの情報取得
続いて、03_write_file
のジョブの情報を取得してみます。
http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/03_write_file/
APIで情報を取得してみます。
http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/03_write_file/api/json
Jsonをクリックで展開します
{ "_class":"org.jenkinsci.plugins.workflow.job.WorkflowJob", "actions":[ { }, { }, { }, { }, { }, { }, { }, { }, { }, { }, { "_class":"com.cloudbees.plugins.credentials.ViewCredentialsAction" } ], "description":"03_write_file", "displayName":"03_write_file", "displayNameOrNull":null, "fullDisplayName":"decrative-pipeline » 03_write_file", "fullName":"decrative-pipeline/03_write_file", "name":"03_write_file", "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/03_write_file/", "buildable":true, "builds":[ { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowRun", "number":17, "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/03_write_file/17/" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowRun", "number":16, "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/03_write_file/16/" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowRun", "number":15, "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/03_write_file/15/" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowRun", "number":14, "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/03_write_file/14/" }, { "_class":"org.jenkinsci.plugins.workflow.job.WorkflowRun", "number":13, "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/03_write_file/13/" } ], "color":"blue", "firstBuild":{ "_class":"org.jenkinsci.plugins.workflow.job.WorkflowRun", "number":13, "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/03_write_file/13/" }, "healthReport":[ { "description":"Build stability: No recent builds failed.", "iconClassName":"icon-health-80plus", "iconUrl":"health-80plus.png", "score":100 } ], "inQueue":false, "keepDependencies":false, "lastBuild":{ "_class":"org.jenkinsci.plugins.workflow.job.WorkflowRun", "number":17, "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/03_write_file/17/" }, "lastCompletedBuild":{ "_class":"org.jenkinsci.plugins.workflow.job.WorkflowRun", "number":17, "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/03_write_file/17/" }, "lastFailedBuild":null, "lastStableBuild":{ "_class":"org.jenkinsci.plugins.workflow.job.WorkflowRun", "number":17, "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/03_write_file/17/" }, "lastSuccessfulBuild":{ "_class":"org.jenkinsci.plugins.workflow.job.WorkflowRun", "number":17, "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/03_write_file/17/" }, "lastUnstableBuild":null, "lastUnsuccessfulBuild":null, "nextBuildNumber":18, "property":[ { "_class":"hudson.model.ParametersDefinitionProperty", "parameterDefinitions":[ { "_class":"hudson.model.TextParameterDefinition", "defaultParameterValue":{ "_class":"hudson.model.StringParameterValue", "name":"OUTPUT_TEXT", "value":"" }, "description":"", "name":"OUTPUT_TEXT", "type":"TextParameterDefinition" } ] }, { "_class":"com.coravy.hudson.plugins.github.GithubProjectProperty" } ], "queueItem":null, "concurrentBuild":true, "resumeBlocked":false }
ビルドの実行履歴などの情報が取得できています。
ビルド結果の情報取得
続いて最新の実行結果に関する情報を取得してみます。このときの最新のビルド番号は17でした。
http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/03_write_file/17/
APIでの取得結果はこちら
http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/03_write_file/17/api/json
Jsonをクリックで展開します
{ "_class":"org.jenkinsci.plugins.workflow.job.WorkflowRun", "actions":[ { "_class":"hudson.model.CauseAction", "causes":[ { "_class":"hudson.model.Cause$UpstreamCause", "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/" } ] }, { }, { "_class":"hudson.model.ParametersAction", "parameters":[ { "_class":"hudson.model.TextParameterValue", "name":"OUTPUT_TEXT", "value":"hoge hoge" } ] }, { "_class":"hudson.plugins.git.util.BuildData", "buildsByBranchName":{ "refs/remotes/origin/master":{ "_class":"hudson.plugins.git.util.Build", "buildNumber":17, "buildResult":null, "marked":{ "SHA1":"2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f", "branch":[ { "SHA1":"2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f", "name":"refs/remotes/origin/master" } ] }, "revision":{ "SHA1":"2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f", "branch":[ { "SHA1":"2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f", "name":"refs/remotes/origin/master" } ] } } }, "lastBuiltRevision":{ "SHA1":"2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f", "branch":[ { "SHA1":"2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f", "name":"refs/remotes/origin/master" } ] }, "remoteUrls":[ "https://github.com/sakamaki-y123/jenkins-continuous-delivery.git" ], "scmName":"" }, { "_class":"hudson.plugins.git.GitTagAction" }, { }, { }, { }, { }, { "_class":"org.jenkinsci.plugins.workflow.cps.EnvActionImpl" }, { }, { }, { }, { }, { }, { "_class":"org.jenkinsci.plugins.pipeline.modeldefinition.actions.RestartDeclarativePipelineAction" }, { }, { "_class":"org.jenkinsci.plugins.workflow.job.views.FlowGraphAction" }, { }, { }, { } ], "artifacts":[ ], "building":false, "description":null, "displayName":"#17", "duration":47339, "estimatedDuration":18597, "executor":null, "fullDisplayName":"decrative-pipeline » 03_write_file #17", "id":"17", "keepLog":false, "number":17, "queueId":84830, "result":"SUCCESS", "timestamp":1567136586337, "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/03_write_file/17/", "changeSets":[ { "_class":"hudson.plugins.git.GitChangeSetList", "items":[ { "_class":"hudson.plugins.git.GitChangeSet", "affectedPaths":[ "pipeline/decrative-pipeline/pipeline_19_random_kitten_generator.groovy" ], "commitId":"2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f", "timestamp":1565431885000, "author":{ "absoluteUrl":"http://jenkins.tielec.blog:8080/user/noreply", "fullName":"noreply" }, "authorEmail":"noreply@github.com", "comment":"Update pipeline_19_random_kitten_generator.groovy\n", "date":"2019-08-10 19:11:25 +0900", "id":"2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f", "msg":"Update pipeline_19_random_kitten_generator.groovy", "paths":[ { "editType":"edit", "file":"pipeline/decrative-pipeline/pipeline_19_random_kitten_generator.groovy" } ] } ], "kind":"git" } ], "culprits":[ { "absoluteUrl":"http://jenkins.tielec.blog:8080/user/noreply", "fullName":"noreply" } ], "nextBuild":null, "previousBuild":{ "number":16, "url":"http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/03_write_file/16/" } }
ビルドの実行結果や、実行時間、上流のジョブなど、より詳細な情報を取得できています。
Pipeline REST API
https://github.com/jenkinsci/pipeline-stage-view-plugin/tree/master/rest-api
パイプラインジョブの情報を取得することができるAPIです。
パイプラインジョブのURLの後ろに/wfapi
をつけると色々情報が取ます。
ジョブの情報取得
Remote access APIと同じように 03_write_file
のジョブの情報をみてみます。
http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/03_write_file/wfapi/
{
"_links":{
"self":{
"href":"/job/decrative-pipeline/job/03_write_file/wfapi/describe"
},
"runs":{
"href":"/job/decrative-pipeline/job/03_write_file/wfapi/runs"
}
},
"name":"03_write_file",
"runCount":5
}
エンドポイントのパスが出てきました。
wfapi/runs
を見てみます。
http://jenkins.tielec.blog:8080/job/decrative-pipeline/job/03_write_file/wfapi/runs
Jsonをクリックで展開します
[ { "_links":{ "self":{ "href":"/job/decrative-pipeline/job/03_write_file/17/wfapi/describe" }, "changesets":{ "href":"/job/decrative-pipeline/job/03_write_file/17/wfapi/changesets" } }, "id":"17", "name":"#17", "status":"SUCCESS", "startTimeMillis":1567136586348, "endTimeMillis":1567136633687, "durationMillis":47339, "queueDurationMillis":11, "pauseDurationMillis":0, "stages":[ { "_links":{ "self":{ "href":"/job/decrative-pipeline/job/03_write_file/17/execution/node/6/wfapi/describe" } }, "id":"6", "name":"Declarative: Checkout SCM", "execNode":"", "status":"SUCCESS", "startTimeMillis":1567136630725, "durationMillis":2430, "pauseDurationMillis":0 }, { "_links":{ "self":{ "href":"/job/decrative-pipeline/job/03_write_file/17/execution/node/13/wfapi/describe" } }, "id":"13", "name":"write file", "execNode":"", "status":"SUCCESS", "startTimeMillis":1567136633197, "durationMillis":469, "pauseDurationMillis":0 } ] }, { "_links":{ "self":{ "href":"/job/decrative-pipeline/job/03_write_file/16/wfapi/describe" } }, "id":"16", "name":"#16", "status":"SUCCESS", "startTimeMillis":1557466865325, "endTimeMillis":1557466871660, "durationMillis":6335, "queueDurationMillis":20, "pauseDurationMillis":0, "stages":[ { "_links":{ "self":{ "href":"/job/decrative-pipeline/job/03_write_file/16/execution/node/6/wfapi/describe" } }, "id":"6", "name":"Declarative: Checkout SCM", "execNode":"", "status":"SUCCESS", "startTimeMillis":1557466869947, "durationMillis":1655, "pauseDurationMillis":0 }, { "_links":{ "self":{ "href":"/job/decrative-pipeline/job/03_write_file/16/execution/node/13/wfapi/describe" } }, "id":"13", "name":"write file", "execNode":"", "status":"SUCCESS", "startTimeMillis":1557466871618, "durationMillis":15, "pauseDurationMillis":0 } ] }, { "_links":{ "self":{ "href":"/job/decrative-pipeline/job/03_write_file/15/wfapi/describe" } }, "id":"15", "name":"#15", "status":"SUCCESS", "startTimeMillis":1554442450777, "endTimeMillis":1554442452894, "durationMillis":2117, "queueDurationMillis":6, "pauseDurationMillis":0, "stages":[ { "_links":{ "self":{ "href":"/job/decrative-pipeline/job/03_write_file/15/execution/node/6/wfapi/describe" } }, "id":"6", "name":"Declarative: Checkout SCM", "execNode":"", "status":"SUCCESS", "startTimeMillis":1554442451871, "durationMillis":868, "pauseDurationMillis":0 }, { "_links":{ "self":{ "href":"/job/decrative-pipeline/job/03_write_file/15/execution/node/13/wfapi/describe" } }, "id":"13", "name":"write file", "execNode":"", "status":"SUCCESS", "startTimeMillis":1554442452776, "durationMillis":71, "pauseDurationMillis":0 } ] }, { "_links":{ "self":{ "href":"/job/decrative-pipeline/job/03_write_file/14/wfapi/describe" } }, "id":"14", "name":"#14", "status":"SUCCESS", "startTimeMillis":1554442389169, "endTimeMillis":1554442395175, "durationMillis":6006, "queueDurationMillis":2, "pauseDurationMillis":0, "stages":[ { "_links":{ "self":{ "href":"/job/decrative-pipeline/job/03_write_file/14/execution/node/6/wfapi/describe" } }, "id":"6", "name":"Declarative: Checkout SCM", "execNode":"", "status":"SUCCESS", "startTimeMillis":1554442393462, "durationMillis":1671, "pauseDurationMillis":0 }, { "_links":{ "self":{ "href":"/job/decrative-pipeline/job/03_write_file/14/execution/node/13/wfapi/describe" } }, "id":"13", "name":"write file", "execNode":"", "status":"SUCCESS", "startTimeMillis":1554442395143, "durationMillis":13, "pauseDurationMillis":0 } ] }, { "_links":{ "self":{ "href":"/job/decrative-pipeline/job/03_write_file/13/wfapi/describe" } }, "id":"13", "name":"#13", "status":"SUCCESS", "startTimeMillis":1552486452530, "endTimeMillis":1552486458565, "durationMillis":6035, "queueDurationMillis":4, "pauseDurationMillis":0, "stages":[ { "_links":{ "self":{ "href":"/job/decrative-pipeline/job/03_write_file/13/execution/node/6/wfapi/describe" } }, "id":"6", "name":"Declarative: Checkout SCM", "execNode":"", "status":"SUCCESS", "startTimeMillis":1552486456845, "durationMillis":1662, "pauseDurationMillis":0 }, { "_links":{ "self":{ "href":"/job/decrative-pipeline/job/03_write_file/13/execution/node/13/wfapi/describe" } }, "id":"13", "name":"write file", "execNode":"", "status":"SUCCESS", "startTimeMillis":1552486458519, "durationMillis":23, "pauseDurationMillis":0 } ] } ]
ビルドの履歴と、実行結果、ジョブの開始時間、実行時間といった情報が取れています。
Remote Access APIよりも情報量がしっかりしていて、なおかつ見やすい作りになっているようです。
ビルド結果の情報
最新のビルド結果の情報を確認してみます。
http://jenkins.tielec.blog:8080//job/decrative-pipeline/job/03_write_file/17/wfapi/describe
Jsonをクリックで展開します
{ "_links":{ "self":{ "href":"/job/decrative-pipeline/job/03_write_file/17/wfapi/describe" }, "changesets":{ "href":"/job/decrative-pipeline/job/03_write_file/17/wfapi/changesets" } }, "id":"17", "name":"#17", "status":"SUCCESS", "startTimeMillis":1567136586348, "endTimeMillis":1567136633687, "durationMillis":47339, "queueDurationMillis":11, "pauseDurationMillis":0, "stages":[ { "_links":{ "self":{ "href":"/job/decrative-pipeline/job/03_write_file/17/execution/node/6/wfapi/describe" } }, "id":"6", "name":"Declarative: Checkout SCM", "execNode":"", "status":"SUCCESS", "startTimeMillis":1567136630725, "durationMillis":2430, "pauseDurationMillis":0 }, { "_links":{ "self":{ "href":"/job/decrative-pipeline/job/03_write_file/17/execution/node/13/wfapi/describe" } }, "id":"13", "name":"write file", "execNode":"", "status":"SUCCESS", "startTimeMillis":1567136633197, "durationMillis":469, "pauseDurationMillis":0 } ] }
ステージごとの情報が取得できていることがわかります。
ステージの名前や、ステージの成功失敗、ステージの開始時間や実行時間といった情報が取れています。
changesets
のエンドポイントも見てみます。
http://jenkins.tielec.blog:8080//job/decrative-pipeline/job/03_write_file/17/wfapi/changesets
[
{
"kind":"git",
"commitCount":1,
"commits":[
{
"commitId":"2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f",
"commitUrl":"https://github.com/sakamaki-y123/jenkins-continuous-delivery/commit/2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f",
"authorJenkinsId":"noreply",
"message":"Update pipeline_19_random_kitten_generator.groovy",
"timestamp":1565431885000,
"consoleUrl":"/job/decrative-pipeline/job/03_write_file/17/changes#2ae5f87662481e3cedaf98b9b6faa64e4e8e0a7f"
}
],
"consoleUrl":"/job/decrative-pipeline/job/03_write_file/17/changes"
}
]
Gitのどのリビジョンで実行されたものかがわかるようになっています。
他にも、artifacts
やpendingInputActions
といったエンドポイントもあり、アーカイブされたファイルの情報を取得したりすることや、ユーザーの入力を求める際の情報などの情報が取得できるみたいです。
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/
Jsonをクリックで展開します
{ "_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やほかの言語を使っていろいろとジョブの分析をしたりといったことができそうです。
おすすめ書籍
[改訂第3版]Jenkins実践入門 ――ビルド・テスト・デプロイを自動化する技術 (WEB+DB PRESS plus)
初めてJenkinsを学ぶ方におすすめです。
Jenkins
Jenkinsでできることについてもう少し詳しく学びたい方におすすめです。
コメント