🐢

Github ActionsでGoogleCloudのCI/CDを導入し、デプロイを完全自動化!

に公開

こんにちは、普段はジュニアエンジニアとして研究開発をやっている
亀ちゃん🐰🐢 (@usagi_kamechan) です。
先日、Google Cloud Japan AI Hackathon Vol.2に参加し、
CI/CDパイプラインの自動化で劇的な効率化を実現しました。

【初心者歓迎】第2回 AI Agent Hackathon、開催決定! 【初心者歓迎】第2回 AI Agent Hackathon、開催決定! zenn.dev

📢 この記事が役に立ったら「いいね」で応援お願いします!
👥 ゆる〜く技術やAIの呟きをしてるのでXでフォローお願いします!

Google Cloud Japan AI Hackathon Vol.2での開発現場の生々しい実録

きっかけは Google Cloud Japan AI Hackathon Vol.2 の開発期間中でした。
毎日GCPにデプロイする作業が死ぬほど非効率で大変でした。

プロダクトや技術の詳細はこちら

【学校だよりAI】なくならない "紙" 文化。それなら「今」を照らそう。AIと。 zenn.dev

毎日のストレス:待ち時間地獄

画像

手動デプロイの現実

# バックエンドデプロイ(手動)
cd backend
gcloud run deploy gakkoudayori-backend \
  --source=. \
  --region=asia-northeast1 \
  --allow-unauthenticated
# → 5-10分待機...

# フロントエンドデプロイ(手動)  
cd frontend
flutter build web --release
firebase deploy --only hosting
# → また5-10分待機...

毎回この作業で 合計20-30分 。しかも途中で他の作業をして「あ、デプロイ終わったっけ?」で確認作業。完全に時間の無駄でした。

さらなる危機:本番環境保護の必要性

ハッカソン中盤、ユーザーアンケートを実施している段階で バックエンドの仕様を大幅変更 する必要が発生。

でも 本番のユーザーには継続して体験してもらいたい

「ステージング環境を作らないと、本番を壊したら終わりだ...」

そこで今回は、3つの仕組みを実現しました。

  1. 🚀 デプロイを自動化する仕組み
  2. 🛡️ 本番環境を絶対に壊さない仕組み
  3. 🔔 チーム全員にデプロイ状況を通知する仕組み

フロー全体像

今回実現したフローは以下のようになります。

画像

自動化されたデプロイフロー

developブランチ(ステージング環境)

  1. 📝 コードプッシュ → `develop`ブランチにプッシュ
  2. 🧪 自動テスト実行 → フロントエンド・バックエンドのテスト
  3. 🚀 ステージング環境デプロイ → テスト通過後に自動デプロイ
  4. 🔔 LINE通知 → デプロイ完了をチームに通知

mainブランチ(本番環境)

  1. 📝 マージ・プッシュ → `main`ブランチにマージ
  2. 🧪 自動テスト実行 → 再度テストを実行
  3. 🚀 本番環境デプロイ → テスト通過後に本番デプロイ
  4. 🏷️ リリースタグ作成 → 自動でバージョンタグを生成
  5. 🔔 LINE通知 → 本番デプロイ完了をチームに通知

Pull Request(プレビュー環境)

  1. 📝 PR作成 → Pull Requestを作成
  2. 🧪 自動テスト実行 → コード品質チェック
  3. 👀 プレビューデプロイ → 7日間限定のプレビュー環境を作成
  4. 💬 PR コメント → プレビューURLをPRに自動コメント

最終的には Vercelと同じような感覚 で、pushするだけで自動デプロイが完了する環境を実現します。

🔰 基礎知識:GitHub ActionsとMakefileって何?

GitHub Actionsとは?

GitHub Actions は、GitHubが提供する 自動化サービス です。
yaml形式 のファイルでDifyのような ワークフローが組める のが特徴です。

用途

  • テストの実行
  • デプロイの実行
  • その他外部サービスとのAPI連携(LINEやSlackへの通知等)
  • Claude Code や gemini CLIを活用した開発やレビュー

メリット:

  • 無料利用枠が充実 (詳細は下記参照)
  • ✅ 24時間365日稼働
  • ✅ 人間のミスがゼロ
  • ✅ 複数人での開発でも一貫性を保てる

GitHub Actions無料利用枠(2025年9月時点):

  • 🆓 Publicリポジトリ: 実質無制限(標準ランナー使用時)
  • 🔒 Privateリポジトリ: プランにより異なる
    • GitHub Free: 月2,000分・500MB
    • GitHub Pro/Team: 月3,000分・1〜2GB
    • GitHub Enterprise: 月50,000分・50GB

GitHub Actions の課金 - GitHub Docs GitHub Actions の使用量が無料使用枠に対してどのように測定されるか、また追加使用分をどのように支払うかについ docs.github.com

Makefileとは?

Makefile は、複雑なコマンドを 1つの短いコマンドにまとめる仕組み です。

身近な例で説明すると:

  • 📱 スマホのショートカット機能 のようなもの
  • 「おはよう」と言うだけで、アラーム停止 + 天気確認 + ニュース読み上げ

Makefileは「make deploy」と打つだけで、複雑なデプロイコマンドを自動実行してくれます。

Google Cloudにデプロイするコマンドがあるんですが、 すごく長い んです。
これを毎回実行するのは 面倒だし 、チーム開発する際にこの手順を作成、共有するのには 手間とコスト がかかります。

Before(手動):

cd backend
gcloud run deploy gakkoudayori-backend --source=. --region=asia-northeast1...

cd ../frontend
flutter build web --dart-define=ENVIRONMENT=production...
firebase deploy --only hosting --project...

makefileを使うと以下のコマンドで上記を実行できるようになります。
After(Makefile):

make deploy

たった1行で全部完了!

メリット:

  • ✅ コマンドを覚える必要がない
  • ✅ タイポによるミスがない
  • ✅ チームメンバー全員が同じ手順で実行可能

ステップ1: Makefileによるコマンド集約で作業効率化(15分で完了)

自動化ステップのレベル1として、
複雑なデプロイコマンドをMakefileにまとめます。
これをやるだけでもかなりの時短になりますよ。

Makefileの作成と設定

以下に私が使用した設定例を載せておきます。
makefileというファイルを作成して、ショートカットコマンドを書くだけです。

画像

実際の設定例

# バックエンドデプロイ(Buildpacks使用)
deploy-backend:
    cd backend && gcloud run deploy gakkoudayori-backend \
        --source=. \
        --region=asia-northeast1 \
        --allow-unauthenticated \
        --memory=2Gi \
        --min-instances=1 \
        --max-instances=10 \
        --set-env-vars="ENVIRONMENT=production"

# フロントエンドデプロイ  
deploy-frontend: 
    cd frontend && flutter build web \
        --dart-define=ENVIRONMENT=production \
        --dart-define=API_BASE_URL=https://your-backend-url.run.app \
        --release
    firebase deploy --only hosting --project your-project-id

# ステージング環境デプロイ
deploy-staging:
    cd backend && gcloud run deploy your-backend-staging \
        --source=. --region=asia-northeast1 \
        --min-instances=0 --memory=1Gi \
        --set-env-vars="ENVIRONMENT=staging"

# 全体デプロイ
deploy: deploy-backend deploy-frontend

ステップ2: GitHub Actions完全自動化でVercel級の快適さ(45分で完了)

画像

いよいよVercelのような自動デプロイを実現します。

2-1. GitHub Secretsの設定

GitHub リポジトリの Settings > Secrets and variables > Actions で以下を設定します。

各値の設定方法は生成AIに聞きながら進めましょう!
(今回は説明を省きますが気になる方はコメントを!)

GCP_PROJECT_ID: your-project-id
GCP_SERVICE_ACCOUNT_KEY: {your-gcp-service-account-json}
FIREBASE_SERVICE_ACCOUNT_JSON: {your-firebase-service-account-json}
LINE_CHANNEL_ACCESS_TOKEN: your-line-token (optional)
LINE_TARGET_GROUP_ID: your-group-id (optional)

2-2. GitHub Actionsワークフロー作成

`.github/workflows/deploy.yml` を作成:
下記実際のワークフローの設定例です。
ワークフローも基本的にclaudeに作成->動作確認しながらブラッシュアップしています。

name: 🚀 CI/CD Pipeline

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

permissions:
  contents: read
  id-token: write
  pull-requests: write
  checks: write

jobs:
  deploy-staging:
    if: github.ref == 'refs/heads/develop'
    runs-on: ubuntu-latest
    
    steps:
    - name: 🛎️ Checkout
      uses: actions/checkout@v4

    - name: 🔧 Google Cloud認証
      uses: google-github-actions/auth@v2
      with:
        credentials_json: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }}

    - name: ☁️ gcloud CLI セットアップ
      uses: google-github-actions/setup-gcloud@v2
      with:
        project_id: ${{ secrets.GCP_PROJECT_ID }}

    - name: 🚀 ステージング環境デプロイ
      run: |
        cd backend
        gcloud run deploy your-backend-staging \
          --source=. \
          --region=asia-northeast1 \
          --allow-unauthenticated \
          --memory=1Gi \
          --min-instances=0 \
          --set-env-vars="ENVIRONMENT=staging"

    - name: 📱 フロントエンドデプロイ(ステージング)
      uses: FirebaseExtended/action-hosting-deploy@v0
      with:
        repoToken: '${{ secrets.GITHUB_TOKEN }}'
        firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_JSON }}'
        channelId: staging
        projectId: ${{ secrets.GCP_PROJECT_ID }}
        entryPoint: ./frontend

  deploy-production:
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    
    steps:
    - name: 🛎️ Checkout
      uses: actions/checkout@v4

    - name: 🔧 Google Cloud認証
      uses: google-github-actions/auth@v2
      with:
        credentials_json: ${{ secrets.GCP_SERVICE_ACCOUNT_KEY }}

    - name: ☁️ gcloud CLI セットアップ
      uses: google-github-actions/setup-gcloud@v2

    - name: 🚀 本番環境バックエンドデプロイ
      run: |
        export PROJECT_ID=${{ secrets.GCP_PROJECT_ID }}
        make deploy-backend

    - name: 📱 本番環境フロントエンドデプロイ
      uses: FirebaseExtended/action-hosting-deploy@v0
      with:
        repoToken: '${{ secrets.GITHUB_TOKEN }}'
        firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_JSON }}'
        channelId: live
        projectId: ${{ secrets.GCP_PROJECT_ID }}
        entryPoint: ./frontend

    - name: 🔔 LINE通知(成功)
      if: success() && secrets.LINE_CHANNEL_ACCESS_TOKEN
      run: |
        MESSAGE_TEXT="🎉 本番環境デプロイ完了!
        プロジェクト: ${{ github.repository }}
        実行者: ${{ github.actor }}
        コミット: '${{ github.sha }}'
        URL: https://your-app.web.app"
        
        curl -X POST \
          -H "Authorization: Bearer ${{ secrets.LINE_CHANNEL_ACCESS_TOKEN }}" \
          -H "Content-Type: application/json" \
          -d "{
            \"to\": \"${{ secrets.LINE_TARGET_GROUP_ID }}\",
            \"messages\":[{
              \"type\":\"text\",
              \"text\":\"$MESSAGE_TEXT\"
            }]
          }" https://api.line.me/v2/bot/message/push

  deploy-preview:
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    
    steps:
    - name: 🛎️ Checkout
      uses: actions/checkout@v4

    - name: 👀 プレビュー環境デプロイ
      uses: FirebaseExtended/action-hosting-deploy@v0
      with:
        repoToken: '${{ secrets.GITHUB_TOKEN }}'
        firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_JSON }}'
        channelId: pr-${{ github.event.number }}
        expires: 7d
        projectId: ${{ secrets.GCP_PROJECT_ID }}
        entryPoint: ./frontend

実際のワークフロー実行画面

画像

デプロイが完了するとLINEにも通知されます。

画像

これを応用すれば、LINEだけでなく好みの環境に合わせたカスタマイズが可能になります。

  • PRをチームのSlackに自動通知
  • デプロイ時にDiscordへ通知
  • Chat Workへ通知

よくあるエラーと解決方法

🔧 エラー1: OIDC認証失敗

Error: google-github-actions/auth failed with workload identity pool

解決方法:

# プロジェクト番号確認
gcloud projects describe YOUR_PROJECT_ID --format="value(projectNumber)"

# 正しいプロジェクト番号でWorkload Identity設定を再実行

🔧 エラー2: Cloud Run権限不足

ERROR: does not have permission to access namespaces instance

解決方法:

# Service Account Token Creator権限追加
gcloud iam service-accounts add-iam-policy-binding \
  github-actions-sa@PROJECT_ID.iam.gserviceaccount.com \
  --member="serviceAccount:service-PROJECT_NUMBER@serverless-robot-prod.iam.gserviceaccount.com" \
  --role="roles/iam.serviceAccountTokenCreator"

🔧 エラー3: Firebase Deploy失敗

Error: HTTP Error: 401, Request had invalid authentication credentials

解決方法:
Firebase Console > Project Settings > Service accounts で
新しい秘密鍵を生成し、`FIREBASE_SERVICE_ACCOUNT_JSON`を再設定。

あなたも今日からデプロイ地獄から解放される!

画像

正直、半年前の私だったら「CI/CDなんて難しそう...」って諦めていたと思います。

でも今回、この2ステップの自動化を実際にやってみて、 意外と簡単だった んです。最初のMakefileなんて、本当に15分で作れました。そしてGitHub Actionsも、エラーと格闘しながらですが、1日あれば動くようになりました。

一番の収穫は時間です。 毎日のデプロイが30分 → 0分になって、その浮いた時間で新機能開発に集中できるようになりました。本当にコスパ最強です。

今では、Vercelと同じ感覚で `git push` するだけ。
GitHub Actionsが裏で全部やってくれて、完了したらLINEでお知らせが来る。

📢 この記事が役に立ったら「スキ」で応援お願いします!
🔄 同じような課題を抱えている方にシェアしていただけると嬉しいです。

Discussion