Help us understand the problem. What is going on with this article?

Job,Task,Resourceの説明をしながら簡単なPipelineを作ってみる

More than 1 year has passed since last update.

ConcourseのPipelineとは下図のようなものです。
スクリーンショット 2018-12-03 2.24.47.png

test-prの処理の中身は下図です。
スクリーンショット 2018-12-03 2.25.26.png

  • GitHubのPRを取得する
  • 対象のPRのstatusをpendingにする
  • unit-testを実行する
    • (成功) 対象のPRのstatusをsuccessにする
    • (失敗) 対象のPRのstatusをfailureにする

今回のSampleはcappyzawa/pipelines になります。

Job

Jobはパイプライン中のアクションを定義します。
今回の例でいうと、以下になります。

  • GitHubのPRを取得する
  • 対象のPRのstatusをpendingにする
  • unit-testを実行する
    • (成功) 対象のPRのstatusをsuccessにする
    • (失敗) 対象のPRのstatusをfailureにする

個人的にはJobから記述し始めるのが書きやすいと思います。
以下がPipleine中のJobになります。

pipeline.yml
jobs:
- name: test-pr
  plan:
  - get: pr
    trigger: true
  - put: pr
    params:
      path: pr
      status: pending
  - task: unit-test
    file: pr/ci/tasks/unit-test.yml
    on_success:
      put: pr
      params:
        path: pr
        status: success
    on_failure:
      put: pr
      params:
        path: pr
        status: failure

name: test-pr

Jobの名前を定義します。
Jobにはplanが存在し、処理実行の流れを記述していきます。

get: pr

pull requestを取得します。
これは後述のResourceです。Resourceの取得はget、送信はputのように記述します。

put: pr

unit-testを実行する前にPRのstatusをpendingにしておきます。

task: unit-test

unit-testを実行します。
これは後述のTaskです。Taskの定義は別ファイルに切り出しておくとパイプラインの定義ファイルがすっきりします。

on_success/on_failure

インデントを揃えることでstepの成功時、失敗時の処理を分岐することができます。
今回の場合、task: unit-testが成功したらGitHubのPullRequestに成功のステータスを送信し、失敗したら失敗のステータスを送信します。

Resource

ResourceはJobで利用されるオブジェクトです。
Resourceは振る舞いが抽象化されており、少ない記述量で決められた振る舞いを行うことができます。
今回はPullRequestを取得、ステータスを送信したいのでtelia-oss/github-pr-resource: Github pull request resource for Concourse を利用します。

resource_types

これはConcourse本体にpackagingされていないResourceですので、resource_typesブロックで利用するDockerImageを指定する必要があります。

pipeline.yml
resource_types:
- name: pull-request
  type: docker-image
  source:
    repository: teliaoss/github-pr-resource

上記のように記述するとteliaoss/github-pr-resourceのDockerImageをpull-reqeustというエイリアスをつけて利用することが可能になります。
厳密にいうと、Resourceにはtypeが存在し、このように記述するとpull-request typeということになります。

resource

利用するResourceを定義します。

pipeline.yml
resources:
- name: pr
  type: pull-request
  check_every: 24h
  webhook_token: ((webhook-token))
  source:
    repository: cappyzawa/pipelines
    access_token: ((github-access-token))

先ほど定義したpull-requestのresource typeを利用しています。

check_every

Resourceにはput, getの他にcheckという振る舞いがあります。
これは定義されたResourceに更新があるか定期的に確認するという振る舞いになります(Resourceによってはないものもある)。
今回の場合github.comのPullRequestに対し、更新がないか確認しにいくため、limitを考慮して24hとしています。

webhook_token

上記のcheck_everyではConcourseが定期的に更新を確認しにいくのですが、対象にwebhookを設定し、能動的にConcourseにresourceの更新を確認させることができます。
今回はGitHubのPullRequestが対象なので、該当するRepositoryにwebhookを設定してみます。
Setting->Webhooks->Add Webhook

項目 内容
Payload URL http:///api/v1/teams//pipelines//resources/pr/check/webhook?webhook_token=token
Content type application/json
SSL Verification どちらでも
Which events would you like to trigger this webhook? Pull requests

今回は((webhook-token))tokenを注入します。
注入方法は後述します。

これで、PullRequestに何かしらの更新が入ると、pr resourceに更新の確認をお願いできるようなります。

source

このブロックがResourceの定義になります。
記述の仕方も各Resourceによって異なりますので、対象ResourceのREADMEを見て、適宜記述してください。
今回のpr resourceには以下を記述します。

パラメータ 内容
repository github.comに存在する対象のRepository(ORG/REPO)を記述
access_token Personal Access Tokenを記述

今回は必須のパラメータしか記述していません。
https://github.com 以外のGitHubホストを利用する場合は、v3_endpoint、または、v4_endpointを記述する必要があります。
Source Configuration

Task

TaskではInputに対して任意の処理を実行することができます。
必要であれば、処理結果をOutputとすることも可能です。
今回であれば、unit-testを行うだけで良いのでOutputは利用しません。
Resourceは振る舞いを抽象化することで、利用者は最低限の記述で処理を実行できるようになりますが、このTaskは逆で自分でゴリゴリ処理を書いていくことができます。
任意のDockerImage上で動作するのでできないことというのはあまりないと思います。
Jobにてtask:unit-testpr/ci/tasks/unit-test.ymlを利用すると定義したので対象のファイルを記述します。
prは前のステップで取得したpathであり、prの中にはPullReqeustの対象コードが含まれています。

unit-test.yml

Taskの設定を記述していきます。

pipeline.yml
---
platform: linux

image_resource:
  type: docker-image
  source:
    repository: golang
    tag: 1.11-alpine

inputs:
- name: pr

run:
  path: pr/ci/tasks/unit-test.sh

platform

実行するplatformとしてlinuxを選択します。

image_resource

ここでTaskを実行するためのDockerImageを記述します。
今回はgolang:1.11-alpineを利用します。

inputs

このTaskのinputとして必要なものの名前を記述します。

run

実行するコマンドのconfigを設定します。
今回はpathだけを指定しました。
(unit-test.shに実行権限を付与するのを忘れないようにしましょう)

unit-test.sh

taskの設定ファイル(unit-test.yml)から指定された実行ファイルです。

#!/usr/bin/env sh

mkdir -p ${GOPATH}/src/github.com/cappyzawa/pipelines
cp -r pr/* ${GOPATH}/src/github.com/cappyzawa/pipelines
cd ${GOPATH}/src/github.com/cappyzawa/pipelines

go test ./...

Pipleine

ここまでを終えて、Pipelineの設定ファイル全体は以下のようになりました

pipeline.yml
resource_types:
- name: pull-request
  type: docker-image
  source:
    repository: teliaoss/github-pr-resource
resources:
- name: pr
  type: pull-request
  check_every: 24h
  webhook_token: ((webhook-token))
  source:
    repository: cappyzawa/pipelines
    access_token: ((github-access-token))
jobs:
- name: test-pr
  plan:
  - get: pr
    trigger: true
  - put: pr
    params:
      path: pr
      status: pending
  - task: unit-test
    file: pr/ci/tasks/unit-test.yml
    on_success:
      put: pr
      params:
        path: pr
        status: success
    on_failure:
      put: pr
      params:
        path: pr
        status: failure

このPipelineをsetします。

$ fly -t <target> set-pipeline -p sample-unit-test -c ci/pipeline.yml -v webhook-token=token -v github-access-token=XXXXXXXXX

Pipelineの設定ファイル中にて(())と表記したパラメータに-vで値を注入します。

パラメータ 内容
webhook-token GitHubのWebhookのpayloadに設定したtoken。今回はtokenとして登録している。
github-access-token GitHubのPersonalAccessToken

まとめ

ConcourseのPipelineを開発する上で知っておくべき以下の概念の説明と簡単な例を示しました。

  • Job
  • Resource
  • Task

今回は継続的にPRのunit-testを行うpipelineを作成しましたので、最後に更新時のgifを添えます。

qiita-concourse mov

※ 今回はlocalに立てているConcourseであったためWebhookを使えなかったのですが、GitHubからアクセス可能な場合は上図のように動作します

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away