🚀

アクションを自作する際の CI/CD [GitHub Actions]

2022/05/01に公開

概要

自作アクションにおける CI/CD を一通り整えたので紹介します。
TypeScript で作成された JavaScript アクションです。

https://github.com/snow-actions/tweet

全体像

  1. [手動] コードを書いて PR
  2. [自動] npm run package が走って dist/ をコミット
  3. [自動] テスト
  4. [手動] レビュー後 PR をマージ
  5. [自動] リリースするためにバージョンを書き換えて PR
  6. [手動] バージョン PR をマージ(スキップ可)
  7. [自動] バージョンを書き換えたらリリースの draft を作成
  8. [手動] リリースを公開(スキップ可)
  9. [自動] リリースをツイート

番外. [自動] 依存パッケージの更新

分類としては 1. ~ 4. が CI, 5. ~ 9. が CD でしょうか。

1. [手動] コードを書いて PR

ブランチを切ってコードを書いたら PR を送ります。
TypeScript のソース (src/) だけコミットします。

2. [自動] npm run package が走って dist/ をコミット

https://github.com/snow-actions/tweet/blob/0c4e3097cf5adbacd515eb59329a9ec42b09485c/.github/workflows/package.yml

dist/ を自動でコミットします。
ビルド環境を統一し src/dist/ が一致していることを保証するためにソースか成果物に変更があったら常に走ります。

GITHUB_TOKEN では新たにワークフローが実行されないので、プッシュ時に CI が走るように GitHub Apps でトークンを払い出しています。
https://zenn.dev/suzutan/articles/how-to-use-github-apps-token-in-github-actions
https://zenn.dev/tatsuo48/articles/72c8939bbc6329

3. [自動] テスト

https://github.com/snow-actions/tweet/blob/0c4e3097cf5adbacd515eb59329a9ec42b09485c/.github/workflows/test.yml

PR が作成されたとき、プッシュされたとき、マージされたときにテストが走ります。
PR におけるテストであれば on.pull_request だけで構いません。

4. [手動] レビュー後 PR をマージ

https://github.com/snow-actions/tweet/blob/0c4e3097cf5adbacd515eb59329a9ec42b09485c/.github/CODEOWNERS

保護ブランチの設定でコードオーナーのレビューを必須にしています。
もちろん自分で PR を作成した場合は不要です。

5. [自動] リリースするためにバージョンを書き換えて PR

https://github.com/snow-actions/tweet/blob/0c4e3097cf5adbacd515eb59329a9ec42b09485c/.github/workflows/version-up.yml

リリースできる段階になったら次のバージョンを決定します。
実行タイミングとバージョンの選択をしないといけないのでトリガーだけ手動です。
実行すると package.json と README.md を変更した PR が作られます。

詳細はこちら。
https://zenn.dev/snowcait/articles/aa3a7b234fd104

6. [手動] バージョン PR をマージ

5. で作成された PR をマージ。

この手順はスキップしてもいいかもしれません。
最後に gh pr merge --auto を実行することで CI が通った後に自動的にマージされます。

7. [自動] バージョンを書き換えたらリリースの draft を作成

https://github.com/snow-actions/tweet/blob/0c4e3097cf5adbacd515eb59329a9ec42b09485c/.github/workflows/draft-release.yml

バージョン PR をマージするとリリースが draft の状態で作成されます。
リリースノートも自動生成されます。

(よく見たら workflow_dispatch の方は実装が中途半端で機能しませんね。pull_request の方だけ見ていただければ。)

8. [手動] リリースを公開

リリースノートを編集してリリースを公開します。

編集なしで公開しても問題ないようであればこの手順はスキップ可能です。
7. の gh release create--draft を外して 9. まで実行してしまって良さそうです。

9. [自動] リリースをツイート

https://github.com/snow-actions/tweet/blob/3380d7c45548a77440427417ceb847088e0e62dd/.github/workflows/released.yml

リリースが公開されたら自動的にツイートします。

https://twitter.com/snow_cait/status/1520685049707999235?s=20

番外. [自動] 依存パッケージの更新

https://github.com/snow-actions/tweet/blob/0c4e3097cf5adbacd515eb59329a9ec42b09485c/.github/workflows/npm-update.yml
https://github.com/snow-actions/tweet/blob/0c4e3097cf5adbacd515eb59329a9ec42b09485c/.github/dependabot.yml

npm update と GitHub Actions のバージョン更新を月 1 で実行しています。
npm も Dependabot に任せても良いのですが PR が複数作られてしまうので自前で実装してます。
(コメントに残骸がありますが npm update の代わりに npm-check-updates にしようかと思ったのですがうまく動かないケースがあったのでやめました)

Renovate という選択肢もあります。

まとめと今後の課題

CI/CD のフローは好みもあると思うのであくまで一例といった感じです。
パッケージ化する手間が省けたのとポチポチするだけでリリースできるようになったのでだいぶ楽になりました。
コミッターが自分だけであればこれで十分だと思いますが Fork したリポジトリから PR を送ると Secrets が読み込めず CI が失敗しそうなので pull_request_target の使用も検討したいところです。

Discussion