LoginSignup
6
1
この記事誰得? 私しか得しないニッチな技術で記事投稿!

Google Apps ScriptをGitHub Actionsでclasp pushする際に、"Manifest file has been updated. Do you want to push and overwrite? (y/N) " と出た場合はworkflowsを失敗させる

Last updated at Posted at 2023-06-19

はじめに

この記事誰得? 私しか得しないニッチな技術で記事投稿」を目にしたので、夏の夜のコンビニの灯火にすだく虫のごとく1、ニッチな記事を投稿します。

対象読者

記事のタイトルを読んで、なんのことかわかったあなた。

  • clasp(Command Line Apps Script Projects)とGitHub Actionsを使ってGoogle Apps Scriptを管理しているあなた
  • GitHub Actionsのworkflowは成功しているのに、Google Apps Scriptが反映されていなくて困ったあなた。

解決したい問題

clasp pushを行う際に、ローカルとリモートでappsscript.jsonに齟齬があると対話プロンプトが出る。

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とに差分が生まれてしまう

image.png

問題が起こるケース

よくあるのが、リモート(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

.github/workflows/actions.yml
    - name: deploy
      run: |
        clasp push

After

.github/workflows/actions.yml
      - 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-stateset-outputのコマンドが廃止予定です。
(※当初2023年5月をもって廃止の予定が、延期されたようです。)

https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/

出力チェックのstepを追加

仕上げとして、

  • ${{ steps.deploy.outputs.deploy-output }}で出力を取得
  • 出力に"Pushed \d+ filesが含まれていなければエラーを出す

という処理を加えています。このあたりはChatGPTさんと相談して作りました。

最後に、更新した.ymlappsscript.jsonが上書きされるケースでworkflowがエラーになるかテストします。

無事に(?)エラーになりました。めでたし。(??)
image.png

この方法の問題点としては、clasp pushが成功時にPushed n files.の出力を返さなくなるアップデートがあると壊れること。もっと良い方法がありましたら教えてください。

おわりに

この世界の片隅の内容の記事を最後までお読みいただきありがとうございます。

記事タイトルの問題で困っていた方には解決の一助として、そうでない方には「GitHub Actionsでの出力による処理の分岐」の例として、それぞれ参考にしていただけたら幸いです。

参考文献

clasp関連

GitHub Actions関連

  1. コンビニのライトがLEDになったので、昨今はあまり寄ってこないらしいです。

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1