くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

GitHub Actionsで差分があるときだけ実行する(Get Diff Action)

以前の記事書いたとおり、Firebase HostingとCloud Functions for Firebaseのデプロイを GitHub Actionsでやっているけど、Cloud Functionsを毎回デプロイしているのでビルドに時間がかかる。。

www.memory-lovers.blog

差分がないときは、実行しなくていいのにな〜と思ったら、いいのがあったので試してみた。

Get Diff Action · Actions · GitHub Marketplace

使い方

使い方はこんな感じ。
PATTERNSに指定したファイルが対象になって、
env.GIT_DIFFsteps.check-diff.outputs.diffに結果が格納される。

on: pull_request
name: CI
jobs:
  eslint:
    name: ESLint
    runs-on: ubuntu-latest
    steps:
      # チェックアウト
      - uses: actions/checkout@v2

      # 差分のチェック
      - uses: technote-space/get-diff-action@v5
        id: check-diff
        with:
          # 対象ファイルのパターン
          PATTERNS: |
            +(src|__tests__)/**/*.ts
      
      # env.GIT_DIFFで分岐
      - name: Install Package dependencies
        run: yarn install
        if: env.GIT_DIFF
        # or 
        # if: steps.check-diff.outputs.diff

サンプル

HostingとFunctionsをビルドしてデプロイするサンプル。

この3つも一緒に。

  • Firestoreのセキュリティルールのデプロイ
  • Cloudflareのキャッシュ削除
  • ビルド結果のSlack通知
name: firebase-deploy
"on":
  push:
    tags:
      - "v*.*.*"

jobs:
  build_and_deploy_test:
    runs-on: ubuntu-latest
    steps:
      # チェックアウト
      - name: Checuout
        uses: actions/checkout@v2

      # functionに差分があるかチェック
      - name: Check Diff Functions
        id: diff_functions
        uses: technote-space/get-diff-action@v5
        with:
          PATTERNS: |
            functions/**/*.ts
            functions/**/*.json

      # firestoreのセキュリティルールに差分があるかチェック
      - name: Check Diff Firestore Rules
        id: diff_firestore_rules
        uses: technote-space/get-diff-action@v5
        with:
          PATTERNS: |
            firestore.rules

      # タグ名からバージョンを取得
      - name: Get the version
        id: get_version
        run: echo ::set-output name=VERSION::$(git rev-parse --short HEAD)

      # firestore.rulesに差分があれば、デプロイを実施
      - name: Deploy for Firestore Rules
        uses: w9jds/firebase-action@master
        with:
          args: deploy --only firestore:rules
        env:
          FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
        if: steps.diff_firestore_rules.outputs.diff

      # Hostingにデプロイする資材のビルド
      - name: Build for Hosting
        run: npm ci && npm run generate
        env:
          VERSION: ${{ steps.get_version.outputs.VERSION }}

      # functionに差分があれば、Functionsにデプロイする資材をビルド
      - name: Build for Function
        run: npm ci --prefix functions && npm run build --prefix functions
        env:
          FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
        if: steps.diff_functions.outputs.diff

      # functionに差分があれば、Functionsをデプロイ
      - name: Deploy for Function
        uses: w9jds/firebase-action@master
        with:
          args: deploy --only functions -f
        env:
          FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
        if: steps.diff_functions.outputs.diff

      # Hostingにデプロイ
      - name: Deploy for Hosting
        uses: w9jds/firebase-action@master
        with:
          args: deploy --only hosting
        env:
          FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}

      # Cloudflareのキャッシュを削除
      - name: Purge cache
        uses: jakejarvis/cloudflare-purge-action@master
        env:
          CLOUDFLARE_ZONE: ${{ secrets.CLOUDFLARE_ZONE }}
          CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }}

      # ビルド成功時のSlack通知
      - name: Slack Notification on Success
        if: success()
        uses: rtCamp/action-slack-notify@v2.0.2
        env:
          SLACK_CHANNEL: notifications
          SLACK_TITLE: Success Deploy(${{ steps.get_version.outputs.VERSION }})
          SLACK_COLOR: good
          SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}

      # ビルド失敗時のSlack通知
      - name: Slack Notification on Failure
        uses: rtCamp/action-slack-notify@v2.0.2
        if: failure()
        env:
          SLACK_CHANNEL: notifications
          SLACK_TITLE: Failure Deploy(${{ steps.get_version.outputs.VERSION }})
          SLACK_COLOR: danger
          SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}

ハマったところ

セキュリティルールは1ファイルなので、
こんな感じでFILESに指定したけど、だめだった。。

なぜか、workflowのファイルが含まれてしまう。。

# firestoreのセキュリティルールに差分があるかチェック
- name: Check Diff Firestore Rules
  id: diff_firestore_rules
  uses: technote-space/get-diff-action@v5
  with:
    FILES: |
      firestore.rules

PATTERNSに設定したらうまくいった(´ω`)

以上!!

参考にしたサイト様