RAKUS Developers Blog | ラクス エンジニアブログ

株式会社ラクスのITエンジニアによる技術ブログです。

GitHub Actionsを活用したワークフローのコツと教訓

こんにちは、あるいはこんばんは。
だいたいサーバサイドのエンジニアの(@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つのポイントを押さえておけば、初心者でも安全かつスムーズにワークフローを作成できるはずです。

  1. run セクションで式 ${{}} は使わず、代わりに env を活用しよう。
  2. workflow_call では github コンテキストと secrets の扱いに注意!
  3. GITHUB_TOKEN の操作では再度ワークフローがトリガーされない仕様を覚えておこう。

このコツを頭に入れて、快適なGitHub Actionsライフを送ってくださいね!

参考記事・お勧めサイト

最後に参考にした記事やお勧めのサイトを紹介しておきます。

zenn.dev

Copyright © RAKUS Co., Ltd. All rights reserved.