こんにちは、あるいはこんばんは。
だいたいサーバサイドのエンジニアの(@taclose)です☆
GitHub Copilotが活躍している昨今、弊社ではGitHubで更に開発効率を良くしていこうという流れで日々自動化が行われております。
今回はそんな時代だからこそ求められているGitHub Actionsについて、初心者向けにワークフロー作成の際に知っておきたいコツと教訓について紹介します。
GitHub Actionsのワークフローを読めるけど、まだ自信がないという方はぜひ参考にしてください!
「それもっと早く知っておきたかった!」「初心者がつまづきがちなポイント!」を解説します!
読者ターゲット
GitHubアクションなんとなく書いてるけど、最適な書き方が出来ているか自信がない方とか!
ワークフロー作成のコツ
1. run
セクションで式 ${{}}
は極力使わない
例:
jobs: example-job: runs-on: ubuntu-latest steps: - run: echo "Hello, ${{ github.event.inputs.name }}!"
このように、run
セクションで ${{ }}
式を使われるのはよく見かけますが、実は避けるべきです!
理由は主に2つあります。
危険その1:コードインジェクションのリスク
${{ github.event.inputs.name }}
などを直接 run
に渡すと、もしその値が悪意のあるものであった場合、意図しないコマンドが実行される危険があります。
例えば、もしシークレットの中に rm -rf /
なんてあったら…ッ!!
危険その2:データのサニタイズ不足
データをサニタイズ(無害化)せずに渡すことで、特定の記号や文字列が予期しない動作を引き起こすことがあります。
GitHub Actions内で式を使う場合は、env
変数や他の手段を使ってデータの安全性を確保しましょう。
良い例:
jobs: example-job: runs-on: ubuntu-latest steps: # "${NAME}" このダブルクォーテーションで囲んでいるのがミソ!何を代入されてもこけません! - run: echo "Hello, ${NAME}!" env: NAME: ${{ github.event.inputs.name }}
このように、式を直接 run
に渡さず、環境変数 (env
) に渡してから使うと、"(ダブルクォーテーション)
が混じっているかも?とかの考慮が要らず安全です。
2. workflow_call
を使う際の注意点
workflow_call
を使うと、他のワークフローを再利用できて便利です。
時にはリポジトリを跨いで共通のワークフローなんて事もやりたいですよね。
しかし、いくつか気を付けるべき点があります。
注意点その1:github
コンテキストは引き継がれる
呼び出し元のワークフローで使用していた github
コンテキストは、そのまま呼び出し先にも引き継がれます。
例えば、github.event
や github.actor
などは呼び出し元のものが反映されるため、何か特定のイベントやユーザーで動作させたい場合には注意が必要です。
例:
on: workflow_call: inputs: name: required: true type: string jobs: example-job: runs-on: ubuntu-latest steps: # ここで出力されるevent_nameは呼び出し元になります! - run: echo "Running as ${{ github.actor }} for event ${{ github.event_name }}"
注意点その2:secrets
の扱い
workflow_call
では、secrets
が自動で渡されるわけではなく、呼び出し側で明示的に渡す必要があります。
忘れがちなポイントなので注意しましょう!
例:
# workflow_callを呼び出してる側の実装 jobs: call-reusable-workflow: uses: ./.github/workflows/reusable-workflow.yml secrets: # secretsはこのように渡してあげないと参照出来ません! MY_SECRET: ${{ secrets.MY_SECRET }}
呼び出し元でこのシークレットを適切に設定しないと、ワークフローがうまく動かない可能性があるので、しっかりと設定してください。
3. GITHUB_TOKEN
で行った操作は再度トリガーされない
何言ってるんだろ?って思うかもしれませんが、ワークフローで色々自動化していると案外詰まるポイントです!
GitHub Actionsでは、デフォルトで GITHUB_TOKEN
が提供されており、これを使ってAPI操作やリポジトリへの変更を行うことができます。
しかし、ここで一つ覚えておきたい仕様があります。
それは、GITHUB_TOKEN
で行った操作は再度ワークフローがトリガーされないという点です。
例:
# GITHUB_TOKENを使ってissueを投稿しているサンプルです。 jobs: example-job: runs-on: ubuntu-latest steps: - name: Create a new issue run: | curl -X POST -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ -d '{"title":"New Issue","body":"This issue is created by GitHub Actions!"}' \ https://api.github.com/repos/your-repo/issues
このように GITHUB_TOKEN
を使って何かissueを投稿した場合、その操作自体が新しいワークフローを起動することはありません。
つまり、「issueが作成されたら通知するワークフロー」とかを作っていたとしても通知が飛ばない結果になります。
これを知らないと「なんでワークフローが動かないんだろう?」とハマることがあるので覚えておきましょう!
補足: workflow_run
トリガーを活用する
もし、GITHUB_TOKEN
での操作後にワークフローを自動的に起動したい場合は、workflow_run
トリガーを活用することを検討してみるのも良いかもしれません。
これで他のワークフローの完了をトリガーにできます。
まとめ
GitHub Actionsでワークフローを作成する際には、いくつかの落とし穴や仕様に注意する必要があります。
今回紹介した3つのポイントを押さえておけば、初心者でも安全かつスムーズにワークフローを作成できるはずです。
run
セクションで式${{}}
は使わず、代わりにenv
を活用しよう。workflow_call
ではgithub
コンテキストとsecrets
の扱いに注意!GITHUB_TOKEN
の操作では再度ワークフローがトリガーされない仕様を覚えておこう。
このコツを頭に入れて、快適なGitHub Actionsライフを送ってくださいね!
参考記事・お勧めサイト
最後に参考にした記事やお勧めのサイトを紹介しておきます。
- actionlint playground
- workflowの構文チェックが出来ます。pushする前にサッと確認すると無駄が減ります!
- GitHub CI/CD実践ガイド――持続可能なソフトウェア開発を支えるGitHub Actionsの設計と運用 (エンジニア選書)
- 初心者から上級者まで幅広い人にお勧めできる良書です!