Google Apps Script を組織全体でスケールさせるためのインフラ。
既存の GAS テンプレートは「1 つのプロジェクトをモダンに開発する方法」を提供します。Apps Script Fleet はその先にある問題を解決します — このテンプレートからリポジトリを作成して Script ID を設定すれば、CI/CD パイプラインがすでに動いている状態でスタートできます。GitHub でも GitLab でも、クラウドでも Self-Managed でも動作します。
→ クイックスタート · 含まれるもの · 他のテンプレートとの違い · FAQ
GAS プロジェクトは小さく始まりますが、増殖します。Slack 通知、レポート自動生成、フォーム処理、Drive のファイル整理 — 気づけば組織に十数個のスクリプトが存在しています。それぞれに必要なもの:
- TypeScript の設定
- バンドラ(Rollup, Webpack, Vite)
- リント・フォーマッタ
- テスト環境とカバレッジ設定
- dev / prod の CI/CD ワークフロー
- clasp の認証管理
- 依存関係の継続的な更新
1 プロジェクトあたりのセットアップに 2〜4 時間。10 プロジェクトなら丸 1 週間がボイラープレートに消えます。さらにその後も、10 個の異なる設定を個別にメンテナンスし続けることになります。
Apps Script Fleet は各 GAS 機能を独立したリポジトリとして扱い、組織レベルの共有インフラで支えます:
- 初回のみの設定:
CLASPRC_JSONを組織/グループレベルのシークレットに追加(GitHub または GitLab)。このテンプレートから作成されたすべてのリポが自動的に利用します。 - プロジェクトごとの設定(約 5 分): テンプレートからリポを作成 → Script ID を設定 → 完了。PR/MR で CI が走り、マージで本番デプロイ。
- 一括メンテナンス: Renovate が全リポの依存関係を自動更新。Template Sync がツーリングの改善を上流テンプレートから自動伝播。
違いを一目で:
| カテゴリ | ツール |
|---|---|
| 言語 | TypeScript(strict モード) |
| バンドラ | Rollup(GAS 互換出力) |
| デプロイ | clasp(dev / prod 環境) |
| テスト | Jest(カバレッジ閾値 80%) |
| リント | ESLint, Prettier, Stylelint, HTMLHint |
| Git フック | husky + lint-staged |
| CI/CD | GitHub Actions + GitLab CI(PR で CI、マージで CD) |
| 依存管理 | Renovate(自動更新 + オートマージ) |
| 同期 | Template Sync ワークフロー(上流の設定変更を自動反映) |
その結果 — 開発者の1日はこう変わります:
| Apps Script Engine | Apps Script Fleet | |
|---|---|---|
| 設計思想 | 機能豊富な DX | 最小限の制約 |
| 最適な用途 | 単一の複雑なプロジェクト | 多数の小さな自動化 |
| フロントエンド開発 | Vite + Alpine.js + Tailwind | 基本的な HTML(GAS 組み込み) |
| テスト | Vitest(任意) | Jest(80% カバレッジ必須) |
| テンプレート同期 | — | 週次(自動 PR) |
| 組織レベルの認証 | — | CLASPRC_JSON 共有シークレット(GitHub + GitLab) |
リッチな UI をクライアントサイドフレームワークで構築する場合は、Apps Script Engine が適しています。 組織全体で 5 つ以上の小さな GAS 自動化を管理する場合は、Apps Script Fleet の出番です。
チームが Apps Script Fleet を使い始める前に、組織の管理者が clasp の共有認証情報をセットアップします:
-
clasp にログイン(CI/CD デプロイに使う Google アカウントで):
npx @google/clasp login
~/.clasprc.jsonが生成されます。 -
組織のパスワードマネージャーに保存 —
~/.clasprc.jsonの内容を共有クレデンシャルとして登録します(例: 「clasp CI/CD — GAS Fleet」)。 -
CLASPRC_JSONを組織レベルの CI/CD シークレットに設定:- GitHub: Organization secrets →
CLASPRC_JSONを追加(値は JSON 全体) - GitLab: グループ → Settings → CI/CD → Variables →
CLASPRC_JSONを追加(protected, masked)
- GitHub: Organization secrets →
-
各開発者はパスワードマネージャーから
~/.clasprc.jsonをローカルマシンにコピーします。
全 GAS プロジェクトを 1 つの標準 GCP プロジェクトに紐付けることで、Cloud Logging / Error Reporting / API 使用量の一元管理と、CI/CD からの clasp run による Script Properties 自動注入が可能になります。
前提条件:
- 標準 GCP プロジェクトを作成(または既存のものを使用): Google Cloud Console
- Apps Script API を有効化: API とサービス → API を有効化
- OAuth 同意画面を設定: API とサービス → OAuth 同意画面 — Workspace 組織は「内部」を選択
- プロジェクト番号を確認(プロジェクト ID ではなく番号): プロジェクト設定 → プロジェクト番号
GCP_PROJECT_NUMBERを組織レベルの CI/CD 変数に設定:- GitHub: Organization variable →
GCP_PROJECT_NUMBER - GitLab: グループ → Settings → CI/CD → Variables →
GCP_PROJECT_NUMBER
- GitHub: Organization variable →
~/.clasprc.json がローカルにある状態で、init スクリプトを実行すると GAS プロジェクトの作成と CI/CD 変数の設定を自動で行います:
./scripts/init.sh \
--title "My Script" \
--gcp-project 123456789プラットフォーム(GitHub / GitLab)は git remote のホストに対して認証済みの CLI(gh または glab)から自動判定されます。
オプション:
--title "名前"— GAS プロジェクト名(デフォルト: ディレクトリ名)--type standalone|sheets|docs|slides|forms— GAS プロジェクトタイプ(デフォルト:standalone)--gcp-project <番号>— 紐付ける GCP プロジェクト番号(Cloud Logging +clasp runが有効に)
スクリプトは dev/prod の GAS プロジェクトを作成し、初回デプロイを行い、CLASP_JSON + DEPLOYMENT_ID を CI/CD プラットフォームに設定します。--gcp-project を指定した場合、GAS プロジェクトが GCP プロジェクトに紐付けられ、GCP_PROJECT_NUMBER が CI/CD 変数として設定されます。
GCP プロジェクト統合が設定されている場合、デプロイ時に Script Properties を自動注入できます:
SCRIPT_PROPERTIESを CI/CD シークレットとして設定(環境ごとの JSON 文字列):{"API_KEY":"xxx","SLACK_WEBHOOK":"https://hooks.slack.com/..."}GCP_PROJECT_NUMBERとSCRIPT_PROPERTIESの両方が設定されている場合、clasp deploy後に自動的にプロパティが注入されます- hook ベースの代替方法は
.github/hooks/post-deploy.sh.exampleまたは.gitlab/post-deploy.yml.exampleを参照
- GitHub / GitHub Enterprise Server: docs/setup-github.ja.md
- GitLab.com / GitLab Self-Managed: docs/setup-gitlab.ja.md
GitHub Actions と GitLab CI の両方の設定が含まれています。push 先のプラットフォームで同じパイプラインが動きます。CI/CD 変数の設定以外の追加セットアップは不要です。
Push / PR → CI (ci.yml) → CD (cd.yml)
├── Lint └── Build
├── Typecheck └── clasp push
├── Test └── clasp deploy
└── Build
| トリガー | パイプライン | 動作 |
|---|---|---|
main への PR |
CI のみ | lint → typecheck → test → build |
dev へのプッシュ |
CI → CD (dev) | cancel-in-progress(後続が先行をキャンセル) |
main へのプッシュ |
CI → CD (prod) | queued(順次実行、スキップなし) |
.gitlab-ci.yml は .gitlab/ 内の分割設定ファイル(ci.yml, cd.yml, sync-template.yml)をインクルードします。変数設定や Self-Managed runner の要件は docs/setup-gitlab.ja.md を参照してください。
| ジョブ | ステージ | トリガー |
|---|---|---|
check |
check | push / MR |
deploy_dev |
deploy | dev への push |
deploy_prod |
deploy | main への push |
template_sync |
sync | スケジュール / 手動 |
テンプレート管理ファイルを変更せずにデプロイパイプラインをカスタマイズ:
- GitHub Actions:
.github/hooks/pre-deploy.shまたは.github/hooks/post-deploy.shを作成 - GitLab CI:
.gitlab/pre-deploy.ymlまたは.gitlab/post-deploy.ymlを作成
これらのファイルはテンプレートからの同期対象外です。
your-project/
├── src/
│ ├── index.ts # GAS エントリポイント(doGet 等)
│ ├── greeting.ts # ビジネスロジック(サンプル)
│ └── app.html # Web UI(サンプル)
├── test/
│ └── greeting.test.ts
├── .github/workflows/
│ ├── ci.yml # CI: lint → typecheck → test → build
│ ├── cd.yml # CD: CI 成功後にデプロイ
│ └── sync-template.yml # 上流テンプレートとの同期
├── .gitlab-ci.yml # GitLab CI/CD ルート(.gitlab/*.yml をインクルード)
├── .gitlab/
│ ├── ci.yml # CI: lint → typecheck → test → build
│ ├── cd.yml # CD: clasp push + deploy
│ └── sync-template.yml # テンプレート同期(スケジュール実行)
├── rollup.config.mjs
├── tsconfig.json
├── jest.config.json
├── eslint.config.mjs
├── renovate.json # 自動更新設定
└── .templatesyncignore # プロジェクト固有のコードは上書きされない
# src/ を編集 → チェック → dev にデプロイ → 動作確認
pnpm run check
pnpm run deploy
- feature ブランチを作成
- コミット — husky が lint-staged を自動実行
- プッシュして PR を作成 — CI が自動実行
mainにマージ — CD が本番にデプロイ
| コマンド | 説明 |
|---|---|
pnpm run check |
lint + lint:css + lint:html + 型チェック + テスト |
pnpm run build |
TypeScript をバンドル + アセットを dist/ にコピー |
pnpm run deploy |
check → build → dev にデプロイ |
pnpm run deploy:prod |
check → build → 本番にデプロイ |
pnpm run test -- --watch |
Jest のウォッチモード |
- GitHub:
sync-template.ymlワークフローが週次で上流テンプレートの更新をチェック。更新がある場合、template-syncラベル付きの PR が自動作成されます。 - GitLab: Group 内に Template Project を作成し、「Create from template」で各 GAS プロジェクトを作成。User Project は
TEMPLATE_REPO_URL(Group Variable)経由で Template Project から同期します。詳細は docs/setup-gitlab.ja.md を参照。
.templatesyncignore はホワイトリスト形式を採用しています — :! プレフィックス付きのファイルのみが同期対象です。プロジェクト固有のファイル(src/, test/, README.md 等)は自動的に除外されます。
h13/renovate-config:node の共有プリセットで設定:
- minor / patch: オートマージ
- major: 手動レビュー用の PR を作成(
breakingラベル付き) - devDependencies: グループ化してオートマージ
- リリースから 7 日間の安定性バッファ
- 毎週日曜 21 時以降に実行
デフォルトでは appsscript.json に oauthScopes フィールドは含まれていません。これにより、Apps Script が実行時に必要最小限のスコープを自動推論するため、個人 Google アカウントでの OAuth 同意画面ブロックを回避できます(一般ユーザーアカウントは Google の OAuth アプリ確認要件 の対象であり、明示的なスコープは「確認されていないアプリ」警告を発生させることがあります)。
プロジェクトで特定のスコープが必要な場合(例: UrlFetchApp、スプレッドシート、Drive)、appsscript.json に oauthScopes フィールドを追加してください:
{
"oauthScopes": [
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/spreadsheets"
]
}注意:
oauthScopesを宣言すると、Apps Script はスコープの自動推論を停止します。プロジェクトが必要とするすべてのスコープを明示的にリストする必要があります。
src/にモジュールを作成(例:src/utils.ts)src/index.tsでインポート — Rollup がすべてをバンドルtest/にテストを追加
GAS から呼び出せるのは
src/index.tsのトップレベルに定義された関数のみです。
jest.config.json の coverageThreshold を編集。デフォルトは全メトリクス 80% です。スコープの小さなプロジェクト(関数 5〜10 個)では 100% への引き上げを推奨します。
プロジェクトで doGet や doPost を Web App として使用する場合、appsscript.json に webapp セクションを追加してください:
{
"webapp": {
"access": "ANYONE",
"executeAs": "USER_ACCESSING"
}
}| プロパティ | 選択肢 |
|---|---|
access |
MYSELF, DOMAIN, ANYONE, ANYONE_ANONYMOUS |
executeAs |
USER_ACCESSING, USER_DEPLOYING |
詳細は公式ドキュメントを参照してください。
テストは test/ に配置し、Jest で実行します。src/index.ts はカバレッジ対象外です(HtmlService 等の GAS グローバルは Node.js で実行できないため)。
pnpm run test # カバレッジ付きで実行
pnpm run test -- --watch # ウォッチモード
Apps Script Fleet で構築された実プロジェクト:
| プロジェクト | パターン | 説明 |
|---|---|---|
| custom-functions | カスタム関数 | Google Sheets データ検証(メール、電話番号、郵便番号) |
| form-mailer | Web App | お問い合わせフォーム + Gmail 通知 |
| slack-channel-archiver | 時限トリガー | 非アクティブな Slack チャンネルを自動アーカイブ(パブリック + プライベート対応) |
| slack-notifier | 時限トリガー | スプレッドシートの新規行を Slack Bot Token 経由で通知 |
各リポジトリが「1 リポ = 1 機能」パターンを CI/CD・テスト・デプロイ付きで実演しています。
GAS プロジェクトは基本的に小さく自己完結した自動化です。モノレポはワークスペースツーリングや選択的デプロイなど、このスケールでは割に合わない複雑さを持ち込みます。リポを分けることで、独立した CI/CD、明確なオーナーシップ、シンプルなメンタルモデルが得られます。Template Sync と Renovate がメンテナンスのオーバーヘッドを吸収します。
小さく焦点の絞られた GAS 関数であれば、高いカバレッジは現実的に達成可能で、本番に届く前に微妙なバグを捕捉します。80% は採用障壁を低く保ちつつ、意味のある品質ゲートとして機能します。スコープが小さなプロジェクト(関数 5〜10 個)では、jest.config.json で 100% への引き上げを検討してください。


