はじめに
「この記事誰得? 私しか得しないニッチな技術で記事投稿」を目にしたので、夏の夜のコンビニの灯火にすだく虫のごとく1、ニッチな記事を投稿します。
対象読者
記事のタイトルを読んで、なんのことかわかったあなた。
-
clasp(Command Line Apps Script Projects)とGitHub Actionsを使ってGoogle Apps Scriptを管理しているあなた
- たとえば、『GAS(Google Apps Script)の更新をGithub Actionsで自動化してみた』の記事に書かれているような実装をしている方。
- GitHub Actionsのworkflowは成功しているのに、Google Apps Scriptが反映されていなくて困ったあなた。
解決したい問題
clasp push
を行う際に、ローカルとリモートでappsscript.json
に齟齬があると対話プロンプトが出る。
appsscript.jsonの一例
{
"timeZone": "Asia/Tokyo",
"dependencies": {},
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8",
"webapp": {
"executeAs": "USER_DEPLOYING",
"access": "ANYONE_ANONYMOUS"
}
}
$ clasp push
? Manifest file has been updated. Do you want to push and overwrite? No
GitHub Actionsでpushを行っている場合はここで停止する。
結果、clasp push
はされないが、workflowはエラーとはならず、「成功」となる。そのため、気づかないうちにGit管理しているコードと実際のGoogle Apps Scriptとに差分が生まれてしまう。
問題が起こるケース
よくあるのが、リモート(Googleのスクリプトエディタ)でウェブアプリとしてデプロイをしたことで、appsscript.json
が更新され、齟齬が生じるケース。
あるいは、ライブラリや、YouTube Data API v3
などのサービスを追加したケース。
すこし前までは、古いスクリプトのruntimeVersion
をV8にする場合に起きていました。
解決策1: clasp push -f
を使う
Claspのドキュメントのとおり、clasp push -f
を使うと、appsscript.json
は上書きされ、対話プロンプトが表示されず、force pushができます。
-f --force: Forcibly overwrites the remote manifest.
https://github.com/google/clasp#push
GitHub Actionsのstepのコマンドをclasp push -f
としてあげれば、pushが止まらなくなります。
この方法の問題は、驚くべきことにappsscript.json
が上書きされてしまうことです!ああ、なんと恐ろしい。(真面目な話、上書きされて困るのはruntimeVersion
とライブラリでしょうか。)
もう一つ、こちらの方が問題なのですが、GitHub Actionsのworkflowのステータスが✅successになること。
別にこれでも構わないよ、という方は、フォースと共にあらんことを。
解決策2: clasp push
の出力に応じてエラーを出す
記事タイトルのとおり、workflowをエラーにしたいという場合の解決策です。
流れはシンプル。
- clasp pushの出力を取得
- pushが成功した場合のメッセージかどうかチェック
- 成功でない場合はエラーを出す
clasp push
の成功メッセージは下記です。
Pushed <number of pushed files> files.
これをGitHub Actionsのpush部分に実装します。
Before
- name: deploy
run: |
clasp push
After
- name: deploy
id: deploy
run: |
OUTPUT=$(clasp push)
delimiter="$(openssl rand -hex 8)"
echo "deploy-output<<${delimiter}" >> "$GITHUB_OUTPUT"
echo "$OUTPUT" >> "$GITHUB_OUTPUT"
echo "${delimiter}" >> "$GITHUB_OUTPUT"
shell: bash
- name: check for errors
run: |
OUTPUT="${{ steps.deploy.outputs.deploy-output }}"
if ! echo "$OUTPUT" | grep -Pq "Pushed \d+ files"; then
echo "Deployment failed with unexpected output: $OUTPUT"
exit 1
fi
変更点
出力の受け渡し
stepの出力の受け渡しにはドキュメントに記載のとおり、
- stepへの
id
の追加 -
GITHUB_OUTPUT
の使用
をすることで実現できます。
echo "{name}={value}" >> "$GITHUB_OUTPUT"
アクセスは、steps.${step_id}.outputs.${name}
となります。
ここでclaspの出力が複数行になることに注意が必要で、そのまま、上記のecho
をしても単一行しか取得できません。
複数行の出力の取得については、こちらの記事が日本語でよくまとまっており、Discussionsも参考になります。
今回はこちらの方法を拝借しました。
GitHub Actionsの出力の操作は、ちょうど移行期にあたるようで、注意してください。
具体的にはsave-state
とset-output
のコマンドが廃止予定です。
(※当初2023年5月をもって廃止の予定が、延期されたようです。)
出力チェックのstepを追加
仕上げとして、
-
${{ steps.deploy.outputs.deploy-output }}
で出力を取得 - 出力に
"Pushed \d+ files
が含まれていなければエラーを出す
という処理を加えています。このあたりはChatGPTさんと相談して作りました。
最後に、更新した.yml
でappsscript.json
が上書きされるケースでworkflowがエラーになるかテストします。
この方法の問題点としては、clasp push
が成功時にPushed n files.
の出力を返さなくなるアップデートがあると壊れること。もっと良い方法がありましたら教えてください。
おわりに
この世界の片隅の内容の記事を最後までお読みいただきありがとうございます。
記事タイトルの問題で困っていた方には解決の一助として、そうでない方には「GitHub Actionsでの出力による処理の分岐」の例として、それぞれ参考にしていただけたら幸いです。
参考文献
clasp関連
GitHub Actions関連
-
コンビニのライトがLEDになったので、昨今はあまり寄ってこないらしいです。 ↩