概要
アイハブアぎっとはぶあくしょんず
アイハブアさーくるしーあい
ンー!
GitHub Actions on CircleCI
前置き
GitHub Actions の Action を GitHub Actions ではなく CircleCI で動かそう、というものです。
この取り組みには2つの目的があります。
- GitHub Actions が使えない旧プラン勢でも Action を使えるようにする
- なんだかイケナイコトをしている気分を楽しむ
ちなみに、GitHub Actions 用の YAML を CircleCI で動かすとか、GitHub Actions のように push
以外のイベントを CircleCI でも動かそう、といった取り組みではありません。
手順
GitHub Actions (Action) on CircleCI を実現するには次の手順が必要になります。
- GitHub Actions の Action をローカル環境で動かす
- 動いたスクリプトを CircleCI の config.yml に書く
GitHub Actions の Action をローカル環境で動かす
今回は stale という Action で試します。
これは放置された Issue や PullRequest を見つけて「放置されてるよ!」や「クローズしとくね!」といった整理をしてくれる便利な Action です。
まずは clone
します。
$ git clone https://github.com/actions/stale
$ cd stale
リポジトリには docs/contributors.md
というファイルがあります。
とてもシンプルなドキュメントになっており、どうすれば手元でも使えるようになるのか予想する手助けをしてくれます。
$ cat docs/contributors.md
# Contributors
### Checkin
- Do check in source (src)
- Do not check in build output (lib)
- Do not check in node_modules
全くわかりませんね。
action.yml
を読む
Actions の設定が記述された action.yml
1 を読むと nodejs v12 な環境で lib/main.js
というファイルを実行すれば良さそうだと分かります。
$ cat action.yml | yq -y '.runs'
using: node12
main: lib/main.js
ちなみに yq は YAML を jq で扱えるようになる便利ツールです。
ビルドする
package.json
を読むとなんとなく npm run build
すれば良さそうです。
その前に npm install
して依存モジュールをインストールしたいところですが、何やらエラーが出ます。
$ npm install
npm ERR! code ETARGET
npm ERR! notarget No matching version found for @actions/exec@^0.0.0.
npm ERR! notarget In most cases you or one of your dependencies are requesting
...略
細かい話はおいといて toolkit
ディレクトリ以下に tgz
ファイルがあるのでこれらを指定して install する必要があります。
$ npm install ./toolkit/*
# ...略
+ @actions/core@0.0.0
+ @actions/tool-cache@0.0.0
+ @actions/io@0.0.0
+ @actions/exec@0.0.0
+ @actions/github@0.0.0
added 646 packages from 453 contributors in 17.345s
これで npm run build
すれば OK.
$ npm run build
> stale-action@1.0.0 build /Users/yasuhiroki/ghq/github.com/actions/stale
> tsc
$ ls lib
main.js
ローカルで動かす
無事にビルドできたので実行してみましょう。
$ node lib/main.js
##[error]Error: Input required and not supplied: repo-token
##[error]Input required and not supplied: repo-token
何やら必須な値があるようです。
ここも action.yml
を読むとヒントが書いてあります。
$ cat action.yml | yq -y .inputs
repo-token:
description: Token for the repository. Can be passed in using {{ secrets.GITHUB_TOKEN }}
required: true
stale-issue-message:
description: The message to post on the issue when tagging it. If none provided, will not mark issues stale.
stale-pr-message:
description: The message to post on the pr when tagging it. If none provided, will not mark pull requests stale
...略
repo-token
や stale-issue-message
などといった値が必要のようです。これらの値は環境変数で設定するのですが stale
ではさらに、 INPUT_XXX
などと INPUT を prefix につけなければなりません。2
というわけでこんな感じです。
$ env INPUT_REPO-TOKEN=xxx \
INPUT_DAYS-BEFORE-STALE=1 \
INPUT_DAYS-BEFORE-CLOSE=1 \
INPUT_STALE-ISSUE-LABEL=stale \
INPUT_STALE-PR-LABEL=stale \
INPUT_STALE-ISSUE-MESSAGE='stale issue' \
INPUT_STALE-PR-MESSAGE='stale pull request' \
INPUT_OPERATIONS-PER-RUN=30 \
GITHUB_REPOSITORY=yasuhiroki/enjoy-circleci \
node lib/main.js
##[debug]found issue: test issue last updated 2019-12-12T08:26:30Z
##[debug]marking issuetest issue as stale
お。無事に動きました。
動いたスクリプトを CircleCI の config.yml に書く
ローカルで動かせたので CircleCI でも動かしてみましょう。
stale を clone
して install
して build
して実行すればOKなので↓のようなスクリプトになりますね。
command: |
git clone https://github.com/actions/stale.git
cd stale
npm install ./toolkit/*
npm run build
node lib/main.js
環境変数を定義
実行には環境変数が必要でした。ということで environment
で定義しましょう。
ただし INPUT_REPO-TOKEN
は GitHub の Token なので YAML にベタ書きしたくありません。
CircleCI のリポジトリ設定や context などで定義しても良いですが、 INPUT_REPO-TOKEN
という他では使わなさそうな名前でわざわざ設定するのはイマイチな気もします。
ここは GITHUB_TOKEN
という汎用性のありそうな名前で設定をしておき、 env INPUT_REPO-TOKEN=${GITHUB_TOKEN} node lib/main.js
という形にしてみましょう。3
command: |
git clone https://github.com/actions/stale.git
cd stale
npm install ./toolkit/*
npm run build
env INPUT_REPO-TOKEN=${GITHUB_TOKEN} node lib/main.js
environment:
# INPUT_REPO-TOKEN: xxx
INPUT_DAYS-BEFORE-STALE: 1
INPUT_DAYS-BEFORE-CLOSE: 1
INPUT_STALE-ISSUE-LABEL: stale
INPUT_STALE-PR-LABEL: stale
INPUT_OPERATIONS-PER-RUN: 30
GITHUB_REPOSITORY: yasuhiroki/enjoy-circleci
node が使える executor を指定
node が必要なので executor は circleci/node
を使いましょう。
docker:
- image: circleci/node:latest
config.yml の完成
そんなこんなで GitHub Actions の stale を実行する CircleCI の config.yml が完成しました。
ついでに cache
の設定もして↓のようなYAMLになります。
version: 2.1
jobs:
build:
docker:
- image: circleci/node:latest
steps:
- run:
command: |
git clone https://github.com/actions/stale.git
- restore_cache:
keys:
- node_modules-{{checksum "stale/package.json"}}
- node_modules
- run:
command: |
cd stale
npm install ./toolkit/*
- save_cache:
key: node_modules-{{checksum "stale/package.json"}}
paths:
- stale/node_modules
- run:
command: |
cd stale
npm run build
env INPUT_REPO-TOKEN=${GITHUB_TOKEN} node lib/main.js
environment:
# INPUT_REPO-TOKEN: xxx
INPUT_DAYS-BEFORE-STALE: 1
INPUT_DAYS-BEFORE-CLOSE: 1
INPUT_STALE-ISSUE-LABEL: stale
INPUT_STALE-PR-LABEL: stale
INPUT_STALE-ISSUE-MESSAGE: 'stale issue'
INPUT_STALE-PR-MESSAGE: 'stale pull request'
INPUT_OPERATIONS-PER-RUN: 30
GITHUB_REPOSITORY: yasuhiroki/enjoy-circleci
workflows:
version: 2
build:
jobs:
- build:
# 環境変数 GITHUB_TOKEN を定義した context
context: my_context
実行結果
無事に CircleCI で stale が動きました。
まとめ
これで GitHub Actions が使えない環境の人でも「GitHub Actions (の Action を CircleCI上で) 使ってるよ 」 と言えますね。
今回紹介した stale 以外の Action も似たような流れで CircleCI 上で動かせる...と言いたいところですが、実際には github
Context に依存していたり、そもそも Node.js じゃなくて Docker で動くものだったりすると、なかなか難しいところがあります。
GitHub Actions の Action を実行するための orb があれば少しは楽になるでしょうが、そこまでしてがんばって GitHub Actions の Action が使いたいなら、Action のロジック部分を抜き出してモジュール化して、orb化する方が適切のような気もします。
-
本記事では action.yml の説明はしません. 気になる方はドキュメントをお読みください -> https://help.github.com/ja/actions/automating-your-workflow-with-github-actions/metadata-syntax-for-github-actions ↩
-
GitHub Actionsのように
INPUT_REPO-TOKEN: ${{secrets.GITHUB_TOKEN}}
などと書けると嬉しいのですが... ↩