CircleCIで重複したWorkflow(Job)を止める
-
問題
CircleCIではGitのリポジトリに変更があるたびにWorkflowが実行される
場合によっては、変更が同時にマージされ複数のWorkflowが走ることがある -
やりたいこと
実行中のWorkflowのうち、リポジトリが同じものは止めたい
CircleCIのAPIを使ってWorkflowを止める
CircleCIのAPIを叩くだけですが、今回はnodejsを使います
(シェルスクリプトでもできますが、ブランチ名がチェインケースやスネークケースの場合はjq
が使えないので・・)
APIトークンについては以下を参照してください
リポジトリの直下に以下を作成
cancelCircleCI.js
var request = require('request');
const CIRCLE_API_HOST = "https://circleci.com/api/v1.1/project/github"
const CIRCLE_USERNAME = process.env.CIRCLE_PROJECT_USERNAME
const CIRCLE_REPONAME = process.env.CIRCLE_PROJECT_REPONAME
const CIRCLE_TOKEN = '?circle-token=' + '<CircleCIのAPIトークン>'
const CIRCLE_BRANCH = process.env.CIRCLE_BRANCH
const CIRCLE_BUILD_NUM = process.env.CIRCLE_BUILD_NUM
const BASE_URL = CIRCLE_API_HOST + '/' + CIRCLE_USERNAME + '/' + CIRCLE_REPONAME
const GET_JOB_API_URL = BASE_URL + CIRCLE_TOKEN
// 直近30個のJobのうち、実行中のJobだけをとってくる
function get_build_num(base_url, api_url, circleci_branch, circleci_build_num, token){
var options = {
url: api_url,
method: 'GET',
json: true
}
var build_nums = []
request(options, function (error, response, body) {
body.forEach(function(body){
if (body.build_num < circleci_build_num && body.status == "running" && body.branch == circleci_branch) {
build_nums.push(body.build_num)
}
})
// 実行中のJobをキャンセル
cacnel_running_job(build_nums, base_url, token)
})
}
// 実行中のJobをキャンセル
function cacnel_running_job(build_nums, base_url, token){
build_nums.forEach(function(build_num){
var options = {
url: base_url + '/' + build_num + '/cancel' + token,
method: 'POST',
json: true
}
request(options, build_num, function (error, response, body) {
console.log('[INFO] Cancel job => ' + body.build_url)
})
})
}
get_build_num(BASE_URL, GET_JOB_API_URL, CIRCLE_BRANCH, CIRCLE_BUILD_NUM, CIRCLE_TOKEN)
config.ymlで呼び出し
- run: npm install request && node cancelCircleCI.js
CircleCIで使える環境変数
1.0と2.0の対応表もあるのですごくわかりやすい