はじめに
GoogleスプレッドシートやGoogleドキュメントなどの複数のファイルに、同じGoogle Apps Script(GAS)コードを添付したいケースは少なくありません。しかし、これを手作業で行うのは時間がかかり、更新時の手間も大きくなります。
そこで、GitHub Actionsとclaspを使用して、1つのGASコードを複数のスクリプトIDに対して一括でデプロイする方法を紹介します。
※今回の記事は以下の記事の派生となります。
背景
弊社ではそれぞれの案件でGoogleスプレッドシートを使用しており、各テンプレートには固有の「スタンドアロン型GAS」を紐づけています。これらのGASコードはGitHubで一元管理しているものの、実際のデプロイに関して問題が生じています。
具体的には、claspツールを使ってGASコードをデプロイする際、一つの.clasp.jsonファイルには一つのスクリプトID(デプロイ先)しか指定できないという制約があります。
以下画像の「スタンドアロン型GAS」は問題ないものの、「案件ごとのスプシ」に紐づくGASに変更が生じた場合、案件の数だけデプロイ操作を繰り返す必要があります。
バグ修正や機能追加のたびにこの作業を行うのは非効率です。また、手動操作によるミスや更新忘れが発生すると、案件間でのコードバージョンの不一致が生じる危険性もあります。
概要
今回構築する仕組みは以下のような流れで動作します。
必要なもの
- GASコードを管理するGitHubリポジトリ
- 各GASのscriptId
動作の流れ
config.jsonで複数のデプロイ先scriptIdを一元管理
GitHub Actionsでmainブランチのマージをきっかけに自動デプロイ
YAMLファイル内のシェルスクリプトで複数scriptIdに対して順次デプロイ
リポジトリの構成
最小限の要素のみ載せています。
gas-project/
├── .github/
│ └── workflows/
│ └── deploy.yml
├── src/
│ ├── appsscript.json
│ └── code.ts
├── deploy.js
└── config.json
実装手順
1. config.jsonの作成
複数のスクリプトIDを管理するファイルを作成します。
形式は自由ですがconfig.json
としました。
{
"scriptIds": [
{
"name": "Test1",
"id": "#########################################################"
},
{
"name": "Test2",
"id": "#########################################################"
},
{
"name": "Test3",
"id": "#########################################################"
}
],
"rootDir": "./src"
}
2. GitHub Secretsの設定
GitHub Actionsでclaspを使用するには、GASへのアクセス認証情報が必要です。これらはGitHubのリポジトリ設定からSecretsとして登録します。
必要なSecrets:
-
CLASP_TOKEN
: claspの認証トークン
claspのトークンの取得方法:
- ローカル環境で
clasp login
を実行 -
~/.clasprc.json
ファイルの内容をコピー - GitHubのリポジトリ設定からSecretsとして登録
3. GitHub ActionsのワークフローYAMLファイル作成
.github/workflows/deploy.yml
に以下のように記述します
name: Deploy GAS to Multiple Scripts
on:
push:
branches: [ main ]
paths:
- 'src/**' # srcディレクトリの変更時のみ実行
workflow_dispatch: # 手動実行も可能
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '16'
- name: Install Dependencie
run: npm install -g @google/clasp
- name: Create clasp config file
run: |
echo '{"token":${{ secrets.CLASP_TOKEN }}}' > ~/.clasprc.json
- name: Deploy to all script IDs
run: node scripts/deploy.js
deploy.js
に処理部分を書きます
const fs = require('fs');
const { execSync } = require('child_process');
// 設定ファイル読み込み
const config = JSON.parse(fs.readFileSync('./config.json', 'utf-8'));
const scriptIds = config.scriptIds;
const rootDir = config.rootDir; // GASのソースディレクトリ
if (!Array.isArray(scriptIds) || scriptIds.length === 0) {
console.error('No scriptIds found in config.json');
process.exit(1);
}
scriptIds.forEach(({ name, id }, index) => {
if (!name || !id) {
console.warn(`Skipping entry ${index + 1} due to missing 'name' or 'id'`);
return;
}
console.log(`\n Deploying to ${name}`);
console.log(` Script ID: ${id}`);
// clasp.json を src/ に作成
const claspConfig = {
scriptId: id,
rootDir: rootDir,
fileExtension: "ts"
};
fs.writeFileSync('.clasp.json', JSON.stringify(claspConfig, null, 2));
// clasp push 実行
try {
execSync(`clasp push -f`, { stdio: 'inherit' });
console.log(`Successfully deployed to ${name}`);
} catch (err) {
console.error(`Failed to deploy to ${name}:`, err.message);
}
});
ポイント
自動化のため、clasp push -f
で強制的にプッシュしています。
claspではclasp push
を行う際にappsscript.jsonに変更が加わっている場合、更新して良いかが求められます。
弊社の運用上は強制プッシュで問題ないと判断しましたが、もし強制プッシュしたくない場合は-f
を消してください。
また、.ts
をプッシュする場合は"fileExtension": "ts"
が必要になります。
デプロイの効率化
srcディレクトリに変更があった場合のみワークフローを実行するよう設定しています。これにより、READMEやその他のファイルの変更時に不要なデプロイが実行されるのを防ぎます。
手動実行を追加
workflow_dispatch
を追加することで、GitHub上から手動でデプロイを実行することも可能になっています。今回はsrcディレクトリの変更がトリガーになるため、ワークフローの定義を変えたときなどは手動で実行する必要があります。
手動デプロイはActionsページのRun workflow
から実行します。
まとめ
GitHub Actionsとclaspを組み合わせることで、scriptIdを貼り替えてpushする手間が省けました。YAMLファイルとscriptファイルを分けたため、管理も容易になったと思います。
この方法を使うことで、共通機能や標準化されたツールの配布・更新が効率化され、一貫性のある状態を保つことができます。組織内でGASを活用している方は、ぜひ試してみてください。