日別アーカイブ: 2022年9月11日

Google Apps Script を Gitub Actions で簡単デプロイ

GASをさわり始めては見たものの、GAS標準で備わっているコードエディタは悪くはないんだけど、せっかくなのでローカルのVSCodeで開発をしてGithubへPush。
Github Actions を利用してデプロイまでやってしまおうかと。

GASのコードエディタだと、弄り倒してもGithubに草生えないし

Claspのインストール周り

claspという、Apps Script をローカル開発するためのコマンドラインツールをインストールします

clasp
https://github.com/google/clasp

インストールは以下のコマンドを叩くだけ

npm install -g @google/clasp

インストール完了後、claspを使ってログインを行います

clasp login

上記コマンドを打つと、Googleへのログイン情報を取得することができます。
Github Actions では、ここで取得する情報を用いて、Apps Script側へDeployすることになります。

その際、Apps Script の API を呼ぶことが出来るように、Apps Script側でAPIを有効にしておきます

GASの設定値を入手する

作成済みのGASのコードを入手するために、claspを使ってプロジェクトをcloneします

clasp clone "スクリプトID

スクリプトIDは対象とするApps Scriptのプロジェクト詳細から確認することができます

単純に、AppsScriptを表示した際に表示されるURLの一部でもあります。「https://script.google.com/d/**ID**/edit?mid=hoge&uiv=fuga」

clone をすることで、下記のファイルが取得されます

appsscript.json
.clasp.json
コード.js
.clasp.json

コード.jsはAppsScriptのエディタで編集していたJavaScriptファイルです。
HTMLファイルなどを追加している場合は同様にcloneされてくるはずです。

appsscript.json には、プロジェクトに関する設定が記載されていて、対象とするApps ScriptをWebアプリとして利用する場合にはこんな記述になっていると思います

{
  "timeZone": "Asia/Tokyo",
  "dependencies": {},
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "webapp": {
    "executeAs": "USER_DEPLOYING",
    "access": "ANYONE_ANONYMOUS"
  }
}

初回デプロイ時にWebアプリとするのか、APIとするのかなどを選択することになるので、実際にcloneする際には初回デプロイ後のほうがいいかもしれません。

また、.clasp.jsonファイルではディレクトリの指定が可能です。
Github Actions のフォルダなどを作ることを考えると、ソースファイルはsrcフォルダに移動しておいたほうがいいです。

{"scriptId":"XXXX スクリプトID XXXXX","rootDir":"./src"}

必要事項をGithub Secrets へ保存する

clasp login コマンドを実行したことで、ホームディレクトリ配下に.clasprc.jsonファイルができているはずです。
注意しないといけないのは、clasp clone で取得した.clasp.jsonファイルとは別となります。名前が似ていますが。
Windowsであれば、「C:\Users\XXX\.clasprc.json」に保存されている形です

{
    "token": {
        "access_token": "XXXXX",
        "refresh_token": "XXXXX",
        "scope": "https://www.googleapis.c...",
        "token_type": "Bearer",
        "id_token": "XXXXX",
        "expiry_date": 1662717440887
    },
    "oauth2ClientSettings": {
        "clientId": "XXXXX",
        "clientSecret": "XXXXX",
        "redirectUri": "http://localhost"
    },
    "isLocalCreds": false
}

上記の中から、Deployに必要となる下記の値をGithub Secretsへ登録します

  • access_token
  • refresh_token
  • id_token
  • clientId
  • clientSecret

さらに、デプロイを管理メニューで表示されるデプロイIDも登録します

Github Actions用の定義追加

ここまで来たらあと一息。
というわけで、workflowを定義します

name: CD

on:
  push:
    branches:
      - main
  workflow_dispatch:
jobs:
  deploy:
    runs-on: ubuntu-20.04
    timeout-minutes: 15
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Setup Node.js 16.x
        uses: actions/setup-node@v2
        with:
          node-version: '16.x'
      - name: Install Clasp
        run: |
          npm init -y
          npm install clasp -g
      - name: Create claspc.json
        run: |
          echo \{\"token\":\{\"access_token\":\"${{ secrets.ACCESS_TOKEN}}\",\"scope\":\"https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/script.projects https://www.googleapis.com/auth/script.webapp.deploy https://www.googleapis.com/auth/logging.read openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/script.deployments https://www.googleapis.com/auth/service.management https://www.googleapis.com/auth/cloud-platform\",\"token_type\":\"Bearer\",\"id_token\":\"${{ secrets.ID_TOKEN }}\",\"expiry_date\":1620870307822,\"refresh_token\":\"${{ secrets.REFRESH_TOKEN }}\"\},\"oauth2ClientSettings\":\{\"clientId\":\"${{ secrets.CLIENTID }}\",\"clientSecret\":\"${{ secrets.CLIENTSECRET }}\",\"redirectUri\":\"http://localhost\"\},\"isLocalCreds\":false\} > ~/.clasprc.json
      - name: Push
        run: |
          clasp push
      - name: DEPLOY
        run: |
          clasp deploy --deploymentId ${{secrets.PROD_DEPLOYMENT_ID}}

mainブランチに対してのpushで起動するようになっています。

将来的に、デプロイ先を分けられるように、DEPLOYMENT_IDはPRODをつけて定義しています。
上記yamlファイルを

.github/workflows

フォルダに配備します。
最終的なディレクトリ構成としては下記の様に私はしてみました

PROJECT_FOLDER
  └── .github
       └── workflows
              └── cd.yaml
 └── src
       └── .appsscript.json
           コード.js
  .clasp.json
  README.md

これで動いていることを確認できます。

うまくいかなかった時

Github ActionsのFlowが成功したからと言って、実際にAppsScriptがちゃんとデプロイされるとは限らないです。

Run clasp push
  clasp push
  shell: /usr/bin/bash -e {0}
? Manifest file has been updated. Do you want to push and overwrite? (y/N) 

上記の様なログがclasp push 時に発生していました。

原因としては、clasp clone 後にAppsScriptのコンソール上から、AppsScriptを初デプロイした際にWebアプリの選択を行いました。

デプロイ後にclasp clone していれば問題なかったのですが、Webアプリを選択したことで、appsscript.jsonの中身が更新されたのです。

clasp push 時にその差分が検知されてしまい、上書きするのかどうかを問われて、返答なしでそのまま終わってしまったのですね。。。

現状の不満

なんとか目論見通り、ローカルでの開発とPushすることでのDeployまで持っていくことができました。

一方で、ローカルで作ったものを動かすことができていません。。。
そのため、毎回デプロイして本番確認。デプロイして本番確認を行っています。。。

Githubに無駄に草がわんさか生えることになっているんだけど、実際のところ、ただのタイプミスだったりすることも多くて、少し悲しい。
できれば、動作確認してからcommitしたい。。

というのも、フロントエンドが不得手な私はサンプルを探してきて使ってみているんですが、なかなかこれがうまく動かない。
そして、恐ろしくエラーの原因調査・デバッグが難しい。。。

Vue.jsで書かれたサンプルを改造しようとしていますが、正直心が折れそうで、見た目とか気にせずにものすごく単純なHTMLにしてしまおうか迷っているところです。
とは言え、なんかこのまま引き下がるのも悔しいんですよね~。

というわけで、Vue.jsに関して少し勉強してみようかな・・・?

参考