#はじめに
こんにちは!
最近なにかと話題のGAS.
実はWebアプリケーションとして公開できるのですが,
スプレッドシートを簡易的なデータベースとして使えたり,環境変数も設定できて簡易的なアプリケーションでやりたいことは一通りできます!(自分は社内でGAS製Slackアプリをいくつか運用してます.)
そしてなんといっても無料なところが素晴らしいです!
今回は,そんなGAS製WebアプリをGithubへのpushをトリガーにデプロイする方法を紹介します!
解決できるお悩み
- GASのスクリプトエディタがリッチでないから,ローカルで好きなエディタで作業して,編集後にブラウザ上のGASエディタにコピペしてるけど,めんどくさい
- Webアプリをデプロイするにいろいろ画面をぽちぽちしないといけないのがめんどくさい
今回構築するシステムの構成図
使うもの
- Github Actions
- Clasp : Google製のGAS用コマンドラインツール!これがあって本当に助かった..
大まかな流れ
-- 準備
- 手元でclaspの認証情報などを集める
- 1で集めた情報をgithub secretsに設定する
-- ここからGithubActions
3. secretsの値を埋め込んで認証用jsonを作成・配置する
4. 3のJsonを元にclaspコマンドでdeployする!
手順 全部で6ステップ!
その1:Claspのインストール & ログイン
まずは今回大活躍するツールClaspを手元の環境にインストール.
https://github.com/google/clasp
npm install -g @google/clasp
インストールが完了したら,以下のコマンドを使ってログインしてください.この時使用するアカウントは,今回デプロイしたいGASを所有しているアカウントにしてください
clasp login
ログイン完了すると,ホームディレクトリに.clasprc.json
が作成されます.このファイルに記載されている情報をあとで使います.
その2:Google Apps Script APIを有効にする
以下にアクセスしてGoogle Apps Script APIをONに設定します
https://script.google.com/home/usersettings
その3:作成済みのGASのコードを手元にcloneする
カレントディレクトリにGASのコードと設定ファイル(appsscript.jsonと.clasp.json)がcloneされるので,すでにレポジトリ管理している場合は適宜ディレクトリ移動してください.
clasp clone "スクリプトID"
スクリプトIDはGASエディタのURLの次の部分のことです
https://script.google.com/d/**ここ**/edit?mid=hoge&uiv=fuga
自分はsrcディレクトリ配下にコードをおいたのでこんな感じになりました.この時点で手元に元々あったGASコードは破棄してもいいかもしれません.手元の方が最新であればsrc/index.jsを上書きしましょう.
src
└── appsscript.json
└── .clasp.json
└── index.js(このファイル名はGASエディタで設定されたもの)
その4:Github Secretsに必要な情報を登録していく.
ここでActionsでclaspを使うための準備をします.
secretsはレポジトリ のsettingsのSecretsタブから設定できます!
今回設定する必要のあるシークレットは全部7つです.
骨の折れる作業ですが,ここまできたらもう一息です!
以下がシークレットに保存したい内容です
- アクセストークン
- IDトークン
- リフレッシュトークン
- クライアントID
- クライアントシークレット
- スクリプトID
- デプロイメントID
それぞれのActionsでの役割は以下です
1~5:clasp login
するため
6: clasp push
するため
7: clasp deploy --deploymentId $DEPLOYMENT_ID
デプロイして最新バージョンを公開するため
1~5 をログイン時に生成された.clasprc.json
から抜き出す
以下などでファイルの中身を確認してください.
vim ~/.clasprc.json
おそらく以下のようなjsonになっていると思うので該当する値を一個ずつシークレットに登録してください.
今回Actions用yamlのサンプルでは次のような名前で登録しているのでそれに合わせていただくと楽かもしれません
.clasprc.jsonの中身
{
"token": {
"access_token": "アクセストークン",
"scope": "hoge",
"token_type": "Bearer",
"id_token": "IDトークン",
"expiry_date": 1606063959625,
"refresh_token": "リフレッシュトークン"
},
"oauth2ClientSettings": {
"clientId": "クライアント",
"clientSecret": "クラインアントシークレット",
"redirectUri": "http://localhost"
},
"isLocalCreds": false
}
サンプルyamlで使うシークレットの名前
secrets.HOGEのHOGEの部分
env:
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
ID_TOKEN: ${{ secrets.ID_TOKEN }}
REFRESH_TOKEN: ${{ secrets.REFRESH_TOKEN }}
CLIENT_ID: ${{ secrets.CLIENT_ID }}
CLIENT_SECRET: ${{ secrets.CLIENT_SECRET }}
SCRIPT_ID: ${{ secrets.SCRIPT_ID }}
DEPLOYMENT_ID: ${{ secrets.DEPLOYMENT_ID }}
6 をclone時に生成された.clasp.jsonから抜き出す
こちらも以下のようなjson担っていると思うので値をシークレットに保存してください.サンプルではSCRIPT_ID
で保存してます.
{"scriptId":"スクリプトID"}
7をGASエディタ上から取得する
デプロイメントIDはGASをWebアプリケーションとして公開した際のURLから取得できます.
GASエディタのメニューで,
公開 -> ウェブアプリケーションとして公開
を選択すると次のダイアログが出現すると思います.
赤枠部分のURLが公開URLです.
デプロイメントIDはこのURLのうちの以下の部分です
https://script.google.com/macros/s/**ここ**/exec
これもシークレットに保存してください
サンプルではDEPLOYMENT_ID
で保存してます.
これでシークレット登録作業は終わりです.お疲れ様でした.
##その5:Github Actionsで使用するshellscriptを追加する
いよいよ大詰めです.
Actionsの中で先ほどのシークレットの情報をかき集めて再びjsonファイルにしてあげる必要があります.
そのために以下のshellscriptを適当な位置に配置してください.
サンプルではsrcと同じ階層にdeploymentディレクトリをつくり,その中に配置しています
.clasprc.json生成スクリプト
setup.sh
#!/bin/sh
LOGIN=$(cat <<-END
{
"token": {
"access_token": "$ACCESS_TOKEN",
"refresh_token": "$REFRESH_TOKEN",
"scope": "https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/service.management https://www.googleapis.com/auth/script.deployments https://www.googleapis.com/auth/logging.read https://www.googleapis.com/auth/script.webapp.deploy https://www.googleapis.com/auth/userinfo.profile openid https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/script.projects https://www.googleapis.com/auth/drive.metadata.readonly",
"token_type": "Bearer",
"id_token": "$ID_TOKEN",
"expiry_date": 1595752666211
},
"oauth2ClientSettings": {
"clientId": "$CLIENT_ID",
"clientSecret": "$CLIENT_SECRET",
"redirectUri": "http://localhost"
},
"isLocalCreds": false
}
END
)
echo $LOGIN > ~/.clasprc.json
.clasp.json生成スクリプト
setup_claspjson.sh
#!/bin/sh
CLASPJSON=$(cat <<-END
{
"scriptId": "$SCRIPT_ID"
}
END
)
echo $CLASPJSON > ~/.clasp.json
ここまできたらもう終わったも同然です!
最後にGithub Actionsの設定ファイルを書きます!
#その6:Github Actions用yamlを追加する
レポジトリに.github/workflowsを作成し
その中に以下のdeploy.yamlを配置してください
name: Deploy
on:
push:
#branches: 自分は本番環境用yamlにはこちらを追加して,masterマージのみで反応するようにしてます.
# - master
paths:
- 'src/index.js' #pushを検知したいパスを書く
jobs:
deploy:
runs-on: ubuntu-latest
env:
ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
ID_TOKEN: ${{ secrets.ID_TOKEN }}
REFRESH_TOKEN: ${{ secrets.REFRESH_TOKEN }}
CLIENT_ID: ${{ secrets.CLIENT_ID }}
CLIENT_SECRET: ${{ secrets.CLIENT_SECRET }}
SCRIPT_ID: ${{ secrets.SCRIPT_ID }}
DEPLOYMENT_ID: ${{ secrets.DEPLOYMENT_ID }}
steps:
- name: Setup repository
uses: actions/checkout@v2
- name: Setup Node
uses: actions/setup-node@v1
with:
node-version: '12'
- name: Install Clasp
run: npm install -g @google/clasp
- name: Generate ~/.clasprc.json
run: |
bash deployment/setup.sh
- name: Generate ~/.clasp.json
run: |
bash deployment/setup_claspjson.sh
- name: Push
run: |
cd src
clasp push --force
- name: DEPLOY
run: |
cd src
clasp deploy --deploymentId $DEPLOYMENT_ID
お疲れ様でした!以上で作業は終わりです!
あとは上のファイルで指定したパスに変更を加えてpushすれば
デプロイされるはずです!
#最後に
##運用上の注意
ステージングと本番アプリを分けて運用する場合,
異なるコードをそれぞれのアプリにデプロイしたいと思います.
その場合,GASアプリごとにSCRIPT_IDとDEPLOYMENT_IDが異なるので,シークレットのうちこの2つをアプリケーションごとに用意してください.残りはGmailアカウントが同じなら共有できます!
以下は例えば本番環境向けのyamlを書く場合は以下のように別シークレットを用意してください
SCRIPT_ID: ${{ secrets.PROD_SCRIPT_ID }}
DEPLOYMENT_ID: ${{ secrets.PROD_DEPLOYMENT_ID }}
##clasp deploy コマンドの注意
上記のサンプルyamlを見てもらうと分かるようにdeployコマンドは以下のようにoptionをつけてないと最新のアプリケーションが公開されません.
clasp deploy --deploymentId $DEPLOYMENT_ID
clasp deployは新しいバージョンを作るだけで公開はしてくれないのです.
自分は頭のなかでdepoy==公開だと思っていたのでここでしばらくハマってしまいました.
違いまとめ
clasp push: コードをウェブのGASエディタに反映する(バージョンを作るとは言ってない)
clasp deploy:新しいバージョンを作る(公開するとは言ってない)
clasp deploy --deploymentId $DEPLOYMENT_ID:最新バージョンを公開する
以上で本当に最後です.長文お付き合いありがとうございました!
#参考