特定の条件下では CircleCI のワークフローを実行したくないとき、ありますよね。
ブランチをフィルターするだけで済むならそちらの方が楽ですが、Pull Request のラベルを参照したい場合は自前でスクリプトを書く必要があります。多分。
というわけでスクリプトを書いてみたところ、こんな感じになりました。
installation_id
などは適宜読み替えてください。
scripts/confirmNeedForDistribution.ts
import { createAppAuth } from '@octokit/auth-app';
import { request } from '@octokit/request';
import { Buffer } from 'buffer';
(async () => {
const appId = process.env.GITHUB_APP_ID;
const privateKey = process.env.GITHUB_APP_PRIVATE_KEY;
const commitSha = process.env.CIRCLE_SHA1;
const owner = "my-owner";
const repo = "my-repository";
if (!appId || !privateKey || !commitSha) {
throw new Error('id または privateKey または commitSha が存在しません。');
}
// GitHub App として認証し、JWT を取得
const auth = createAppAuth({ appId, privateKey });
const { token: jwt } = await auth({ type: 'app' });
// GitHub API のアクセストークンを取得
const {
data: { token },
} = await request('POST /app/installations/{installation_id}/access_tokens', {
headers: { Authorization: 'Bearer ' + jwt },
installation_id: 99999999,
});
// CI 実行のトリガーとなったコミットが属する Pull Request を取得
const { data: pullRequests } = await request(
'GET /repos/{owner}/{repo}/commits/{commit_sha}/pulls',
{
headers: { Authorization: 'Token ' + token },
owner,
repo,
commit_sha: commitSha,
},
);
// Pull Request のラベルを取得
const { data: labels } = await request(
'GET /repos/{owner}/{repo}/issues/{issue_number}/labels',
{
headers: { Authorization: 'Token ' + token },
owner,
repo,
issue_number: pullRequests[0].number,
},
);
// ラベルを確認
console.log(
labels.some((label) =>
['feat', 'fix', 'hotfix', 'refactor', 'deps'].includes(label.name),
),
);
})();
.circleci/config.yml
version: 2.1
commands:
confirm-need-for-distribution:
steps:
- run:
name: Confirm need for distribution
command: |
flag=$(yarn -s ts-node scripts/confirmNeedForDistribution.ts)
if [ $flag = "false" ]; then
circleci-agent step halt
fi
個人のトークンに紐付けたくなかったので GitHub App を作成し、それを使いました。
また、認証には octokit/auth-app.js を使用しました。
誰かの参考になれば幸いです。
(もっと良いやり方をご存知の方がいれば、コメントにてお教えください。)