Beta参加の秘密保持条項に反しているのでは?という指摘をいただいたので、一部修正を行いました
1人AdventのDay-7です。なるほど、1週間・・・
adventar.org
私の環境でも、GitHub Actionsを触れるようになりました!!
自分の手で実際に触ってみて、動かしてみると「おお!これはすごい!!」という感想です。。。!
実際に動いているものを見ないと「何があってどういうものなのか」のイメージが付きにくかったのですが、手元で動かしてみると「なるほど、、、そういう!」とワクワクしてきます。
今の自分なりの理解を、改めて、ドキュメント等を整理する形でまとめてみたいと思います。
GitHub Actions、ざっくりいうと
GitHub上での様々なイベントで発火させる「Workflow」と、Workflowから具体的な起動される「Action」からなる
Actionは、利用するDockerイメージを指定して、そのコンテナの内部で実行される
1つのWorkflowに、複数のActionを連鎖・並行させて紐付けることができる
Workflowの編集のためのvisual editorが用意されていたり各Actionごとの実行結果(ログ)の閲覧が可能
個人的な感想としては、
今まで1つの汎用CIにまとめていた処理を、細分化・専門化して組み合わせることが用意になりそう
自前のDockerfileをゴニョゴニョして使い放題なので、ローカルでやっていた処理を簡単にクラウドに移せそう
通常のGitHub(git操作やIssue更新など)だけでなく、incoming hook系のAPIも用意されているので、chatops等の実装とも親和性が抜群に高そう
といったところです。
現在、業務でCIの活用見直しやデプロイフローの最適化を進めている最中です。それと絡めて、「Travis CIの処理をいい感じにする」というネタで触ってみました!
やろうとしていること
今の状態
Travis CIを利用しているプロジェクトにおいて
script/deploy等をベタで書いており
例えば「tagをpushした」際にも丸々とscriptフェーズが実行される
やってみたいこと
master以外のブランチへのpush/prは、scriptまで。deployはしない
masterの修正(merge commit)は、scriptとdeployを行う
コードに差分がないときにはdeplyフェーズのみを実行し、scriptを実行させない
これを、「.travis.ymlの修正を行わずにできるかな」という風に遊んでみたいと思います。
サンプルプロジェクトのセットアップ
実際に遊んで見るに当たり、サンプルとなるプロジェクトを用意しました。CakePHPのスケルトンプロジェクトを設置し、ごくごく簡単なtravis.ymlを一緒に置きます。
$ tree -a -L 3 -I .git
.
├── .travis.yml
├── README.md
└── o0h_home
├── .gitignore
└── app
├── .editorconfig
├── .gitattributes
├── .github
├── .gitignore
├── .htaccess
├── .travis.yml
├── README.md
├── bin
├── composer.json
├── composer.lock
├── config
├── index.php
├── logs
├── phpcs.xml
├── phpunit.xml.dist
├── plugins
├── src
├── tests
├── tmp
├── vendor
└── webroot
.travis.yml
language : php
php :
- 7.2
cache :
composer : true
directories :
- o0h_home/app/vendor
install :
- cd o0h_home/app && composer install && cd $TRAVIS_BUILD_DIR
before_script :
- echo "I'm in before_script!"
script :
- cd o0h_home/app && vendor/bin/phpcs
deploy :
- provider : script
script : echo "I'm in deploy @master!"
on :
branch : master
- provider : script
script : echo "I'm in deploy @tag!"
on :
tags : true
まずはTravis CIのAPIを、最低限理解する
APIがどんな感じになっていれば行けそうかな?を整理する
Actionsは「どんな条件で」「どんな風に」処理を呼び出すか?という機能に見えます。
今回、私が求めている世界は、「.travis.ymlに記述されている内容を部分的に実行する」という術が必要なのではないでしょうか。つまり、「こういう呼び出し方をしたら、scriptをスキップできるよ」という方法があれば勝利に1歩近づきます。
そのためには、
A: 実行対象となるフェーズを任意に組み合わせて、ビルドを実行できる
B: 実行内容をAPIキックのタイミングで任意に改変して、ビルドを実行できる
C: 予め実行内容(のセット)を定義しておき、ビルドを実行できる
このいずれかの手立てがあれば良さそうです。*1
ということで、「Travis CI側のApiがとうなってるの?」を掴まない限りは、何も始まりません。
実際にAPIを見てみる
Triggering builds with API V3 - Travis CI
こちらを覗くと、
ビルド作成のリクエスト時に、.travis.ymlのコンテンツと同じような処理内容を渡すことができる
もともとの.travis.ymlの内容と、リクエストに含めた処理内容を、「どう混ぜるか」を指定することができる(merge_mode)
merge_modeは以下の3種類
replace replaces the full, original build configuration with the configuration in the API request body
merge (default) replaces sections in the original configuration with the configuration in the API request body
deep_merge merges the configuration in the API request body into the build configuration
これを見ると、「scriptだけ内容を変える」ができそうに思います💡
GitHub ActionsからTravis CIを利用できそう?
次にやるのは、「GitHub ActionsからTravis CIのAPIを叩く」です。
そして、そのリクエスト内容に「script処理をスキップする」といった内容を混ぜたり混ぜなかったりしようと思います。
そう思って探していると、「ActionsからTravis」になんだかお誂え向きのものがありました!
github.com
The Travis CI action wraps the Travis CI API so that new builds can be created based on Push and Pull Request GitHub events.
と書いてあります。これを扱えれば、「ActionsからTravis CIにリクエストを飛ばす」は出来そうな感じがしてきました。
では、今度はtravis-ci/actionsを理解するために、そもそものところである「Actionsから○○を実行する」に関する概念をつかみにいきたいと思います。
GitHub Actionsの正体は、○○を実行させるものだった
travis-ci/actionsを見ると、Dockerfileやentrypointといった単語を発見することができます。ということは、なるほど、なにか「Dockerを使ったもの」であるなと推察できます。
github actions docker
でググると、次の記事に行き当たります。
developer.github.com
GitHub Actions are code run in Docker containers.
なるほど、「Dockerコンテナを起動してその中でなんでもやっていいよ!」でしょうか。
そのDockerイメージ/コンテナはどうやって作成されるんだ?
developer.github.com
GitHub Actions execute in Docker containers. An action can use an existing publicly available Docker image, or you can create your own Docker image by including a Dockerfile with your code.
既存のものを使うこともできるし、自作したDockerfileを利用することもできるよ〜と。であれば、恐らく、Actionsの設定のやり方で「どのイメージを使いますか」という設定をする部分があるのでしょう。
ここまできたら、次は「Actionsはどうやって使うんですか」のイメージを掴みに行くのが良さそうです。
Actionsに触ってみる
Actionsへは、GitHubのレポジトリ画面からアクセスできます。
https://help.github.com/articles/creating-a-workflow-with-github-actions/#creating-a-workflow-using-the-visual-editor
ここに、Actionsの作成画面があります。
https://help.github.com/articles/creating-a-workflow-with-github-actions/#creating-a-workflow-using-the-visual-editor
「Workflow」なる概念が飛び出してきました・・・!
Workflowってなんだ・・?
どうやら大本になる概念な予感がするので、Actionsの最も大元となるdocに書いてあるだろうと期待します。
developer.github.com
サイドメニューを見るに、GitHub Actions = Workflow + Action
というイメージですかね?
説明を見てみます。
Workflows are a composite of many different GitHub Actions, or tasks you want to accomplish, and are triggered by webhook events.
Workflowsは、「発動条件」と「発動時の設定」って感じすかね。それで「何をやりますか」というSVOのOに当たる部分が、Actionsである〜という風に理解しました。
それでは、さっきの「どうやったらtravis-ci/actionsを呼び出せるの」は、workflowを作れば何か出てきそうですね。
Workflowを作ってみる!
「Create a new workflow」ボタンを押したら、新規ファイル作成のページに飛びます(ページURLとページタイトルが、new fileのそれ)。
そして、特徴的なGUIが現れます。
https://help.github.com/articles/creating-a-workflow-with-github-actions/#creating-a-workflow-using-the-visual-editor
デフォルトでは、コレは同時に octo-test/.github/main.workflow
というファイルの新規作成でもあるということが、見て取れます。
隣にあるタブ、 Edit new file
ではテキストベースでの編集に入れます。
https://help.github.com/articles/creating-a-workflow-with-github-actions/#creating-a-workflow-using-the-file-editor
あ!なんか、このDSLは見覚えがあるぞ。travis-ci/actiosnレポのREADMEに、こんな感じのサンプルがありました。
いろいろと、点と点がつながってきました・・・!
上部の黒い枠が「workflow」で、下の点線で囲まれた部分に「action」を定義していく
Workflowの定義
黒いボックス、 workflowの方にある Edit
をクリックすると、次のようなメニューが現れます。
キャプチャ上の Issues
になっている部分で、発火条件としたいイベントを選択するという寸法!
どこ見ればいいかな?
定義の一覧があるはずなので、公式docを当たりました。
Workflow configuration options | GitHub Developer Guide
resolve
が何者かまだわかっていませんが、とりあえず今の我々に必要なのは on
に関する知識でしょう。リンクが貼られているので、GitHub eventについて知識を求めに参ります。
今回のスコープでいうと「tagが作成されたとき」です。Event nameとしては、 create
でしょうか。 これに、副条件として「タグ(が作成された)」を加えたいのですが。
具体的な処理を行う前に、イベントをフィルタリングするには?
簡単な比較条件を突っ込んで(branch == 'master'
みたいな)弾ければいいのに・・・と思うのですが、どうやらそういう記述はできなさそう。
我々が使える武器は「workflow」と「action」なので、じゃあ「何かプログラマブルに処理を注入するには、actionを重ねるのかな?」と思いました。GUI的にも、actionを多層化してチェインすることはできそうなので。
どうでしょう、もし「簡単なシェルスクリプトを実行する」ためだけのDockerイメージがあれば、これは実現できそうな気がします。
GitHub公式のActionを見てみます。
github.com
bin って、めっちゃそれっぽいな・・・w 開いてみます。
github.com
Usage information for individual commands can be found in their respective directories.
はい。そして、filter
というディレクトリがあるので、これにすがってみます。
For example, here is a workflow that publishes a package to npm when the master branch receives a push:
どんぴしゃっぽい!
サンプルを見てみます。
workflow "Build, Test, and Publish" {
on = "push"
resolves = ["Publish"]
}
action "Build" {
uses = "actions/npm@master"
args = "install"
}
action "Test" {
needs = "Build"
uses = "actions/npm@master"
args = "test"
}
# Filter for master branch
action "Master" {
needs = "Test"
uses = "actions/bin/filter@master"
args = "branch master"
}
action "Publish" {
needs = "Master"
uses = "actions/npm@master"
args = "publish --access public"
secrets = ["NPM_AUTH_TOKEN"]
}
「masterブランチでフィルタ」をしているのは、 Master
のactionですね。
ついでにというか、さっき疑問だった「どうやって外部のイメージをactionに定義するのか」もこれで解消しました。 use
に指定するんですね。そして、依存関係にあるactionは前ステップにあたるあactionをneeds
として宣言する、と。
我々が実行したい createイベントでtagの場合のみ
は、filterディレクトリのREADMEに言及があるのでこれをそのまま使います。
.workflowはこのようになります。
workflow "on tag push" {
on = "create"
resolves = ["filter-only-tag-created"]
}
action "filter-only-tag-created" {
uses = "actions/bin/filter@master"
args = "tag"
}
on tag push
というworkflowを
create
イベントに反応して起動させ
filter-only-tag-created
actionを呼ばせる
filter-only-tag-created
は
actions/bin/filter@master"
のイメージを利用し
tags
というパラメータ込みで起動する
actionにおけるuseの指定ですが、
自レポジトリの場合は、./
から初めてPJルートからの相対パス指定
他レポジトリの場合は、 user名/レポジトリ名/ディレクトリへのパス@ブランチ
と指定
という形式になるようです。
developer.github.com
filterを設定できたように思うので、Travis CIをキックする処理を入れます。
ここで、request bodyを変えてあげる必要があります。
が、travis-ci/actionsレポでentrypointに指定されているjsの内容を見てみると、どうやらコンテンツが固定されているようです。
自前のDockerfileを用意しよう・・・
どうやら外から注入というのが厳しいような気がしたので、自前で用意してみます。幸い、travis-ci/actionを見ても、複雑な処理は入っていません。なので、丸々っと必要な処理をコピペしてしまいます。
ひとまず、以下のようにしました。
gist.github.com
自レポジトリ内のDockerイメージを利用する方法が、公式ドキュメント に書いてあります。PJルートから、コンテキストとなる = Dockerfileのあるディレクトリへのパスを指定してあげれば良さそうですね。
最終的には、このようになりました。
workflow "on tag push" {
on = "create"
resolves = ["deploy"]
}
action "filter-only-tag-created" {
uses = "actions/bin/filter@master"
args = "tag"
}
action "deploy" {
uses = "./.github-aciton/travis-ci"
needs = ["filter-only-tag-created"]
secrets = ["TRAVIS_TOKEN"]
}
Travis CIの利用には、TRAVIS_TOKEN
が必要です。
https://travis-ci.com/account/preferences で取得し、actionに設定してください。
`Create a new secret` より追加
実行してみる
エディタ右上の、Start commit
からコミットします。
その後にタグを打つと、定義したとおりのworkflowが動きます。
その後は、実行結果をグラフィカルに確認が可能です。
GitHub上で「Actionの履歴・実行結果が見れる様子」は、この動画の1:10辺りで垣間見ることができます。
左側に実行されたworkflowの履歴が表示され、その中にあるactionごとの実行結果ステータスが色により表されます。更に、actionのブロック内にあるlog
をクリックすると、詳細が確認できるわけです。
まとめ
本来であれば、.travis.ymlもちゃんといじりつつ行うべきだと思っています。
ただ、「新機能のポテンシャル」としては、「ここまで簡単に色々とできる!!」という手応えは間違いなく感じたので、個人的には大満足です。
Dockerでいろいろできる!はやばい。
どんどん活用していくしかねぇな・・・!という温度感です。
参考記事等