一覧に戻る
    【Jenkins】Blue Ocean REST API でパイプライン情報を取得する
    CI/CD
    PRこの記事には広告が含まれています

    【Jenkins】Blue Ocean REST API でパイプライン情報を取得する

    (更新日: 2026/2/8)
    106 分で読める

    はじめに

    こんにちは株式会社TIELECのタカシユウトです。この記事ではJenkinsのBlue Ocean REST APIについて紹介します。Blue Ocean REST APIは、Blue Ocean UIで表示される情報をプログラムから取得するためのAPIです。

    Blue Ocean REST API

    ⚠️ 重要な注意事項

    Blue Ocean プラグインは、2024年3月をもって非推奨となりました。Jenkins コミュニティは、Blue Ocean に代わる新しいUIおよびビジュアライゼーションソリューションの開発に移行しています。

    この記事で紹介している Blue Ocean REST API は引き続き動作しますが、将来的には利用できなくなる可能性があります。新規プロジェクトでは、以下の代替手段の使用を推奨します:

    - Jenkins REST API - ジョブ、ビルド、キューの基本情報取得に使用
    - Pipeline REST API - パイプライン実行の詳細情報取得に使用
    - クラシックUI - Jenkins の標準インターフェース

    既存の Blue Ocean API 実装を移行する場合は、上記の標準 REST API エンドポイントへの移行を検討してください。

    https://github.com/jenkinsci/blueocean-plugin/tree/master/blueocean-rest

    最後にBlue Ocean REST APIについての紹介です。 こちらはJenkinsのBlue Oceanのプラグインを入れことにより使えるようになります。

    エンドポイントはJenkinsのURLの後ろに/blue/restをつけたものになります。

    usersearchなど様々なエンドポイントがありそうですがよく使いそうなのはと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を開いてみます。

    パイプラインの情報を取得する

    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
    }

    ここでの情報は先ほどまで出てきた情報とあまり変わりがありませんが、logstepsといったエンドポイントが扱えることがわかります。


    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を紹介しました。

    1. Remote access API
    2. Pipeline REST API
    3. 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の情報をプログラムから取得したり、自動化を進めることができます。

    おすすめ書籍

    もっと深く学びたい方へ

    この記事で、複数のJenkins APIの違いと使い分けは理解できたと思います。

    でも、「どのAPIをどの目的で使うべきか」「取得した情報をどう分析するか」という実践的な判断は、運用の経験から学ぶことが多いです。

    より深い理解のために、こちらの記事もおすすめです:

    戦略的トラブルシュート - DECSARメソッドとは -

    戦略的トラブルシュート - DECSARメソッドとは -

    Tech
    SRE
    JenkinsがじわじわGitクローンできなくなっていった話 ― EFSメタデータIOPSとの闘い

    JenkinsがじわじわGitクローンできなくなっていった話 ― EFSメタデータIOPSとの闘い

    Tech
    SRE

    この記事は役に立ちましたか?

    Coffee cup

    この記事が、何かの整理につながったら

    コーヒー1杯分の応援をもらえると嬉しいです。

    ※ これは応援とは別の話ですが、

    同じようなテーマを自分の文脈で整理したい場合は、 (文章だけだと詰まりやすい人向けに) 思考整理の壁打ちという形で対話の時間も取っています。

    対話の時間について