This repository is an example of how to setup an automatic CI/CD process for Google Apps Script using GitHub Actions.
clasp create to create a new project or clasp clone to download an existing project. This will create a .clasp.json file.git init. .clasp.json file created in the prior step MUST be in the root of the Git repository, .clasp.json may point to source files in a sub folder throgh a rootDir property. .github/workflows/deploy-script.yml from this repository to the same relative path..clasp.json File Format Reference{
"scriptId": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
"rootDir": "src",
"projectId": "project-id-0000000000000000000",
"fileExtension": "js",
"filePushOrder": ["src/File1.js", "src/File1.js", "src/File1.js"],
"parentId": "XXXXXXXXXXXXXXXXXXXXXX"
}
git add .git commit -m "first commit"develop branch: git branch -M developmain branch: git branch -M maingit remote add origin git@github.com:account/repo.gitmain branch to GitHub: git push -u origin maindevelop branch to GitHub: git push -u origin developAt this point the workflow will be triggered, but will fail because it is not configured completely.
Github encrypted secrets are used to configure the workflow and can be set from the repository settings page on GitHub.
CLASPRC_JSONThe clasp command line tool uses a .clasprc.json file to store the current login information. The contents of this file need to be added to a CLASPRC_JSON secret to allow the workflow to update and deploy scripts.
clasp login .clasprc.json file that is created in the home directory (C:\Users\{username} on windows, and ~/.clasprc.json on Linux).clasprc.json into a new secret named CLASPRC_JSONREPO_ACCESS_TOKENA GitHub personal access token must be provided to the workfow to allow it to update the CLASPRC_JSON secret configured about when tokens expire and refresh.
repo scope.REPO_ACCESS_TOKENSCRIPT_ID [OPTIONAL]The clasp command line tool identifies the Google Apps Script project to push and deploy too using the scriptId property in .clasp.json. You may leave this value hard coded in .clasp.json or you may have this set dynamically. To specify the target script dynamically add a SCRIPT_ID secret to the repository. This will cause the workflow to override whatever literal scriptId value is in .clasp.json
DEPLOYMENT_ID [OPTIONAL]The workflow can automatically deploy the script when the main branch is pushed to github.
clasp deploy or on https://scripts.google.com.clasp deployments or checking the projet settings on https://scripts.google.com.DEPLOYMENT_IDmain or develop branches on github will automatically trigger the workflow to push the code to the HEAD deployment on https://scripts.google.com`DEPLOYMENT_ID secret has been setup pushing to main will also deploy the script to the specified deployment..clasprc.jsonThe .clasprc.json file that stores the authentication information contains a access_token which expires at the specified expiry_date and a refresh_token that can be used to request a new access_token. These tokens will change over time, but the workflow should update the CLASPRC_JSON repository secret.
However, there are conditions where the refresh token may also expire. So in addition to the push triggers the workflow is also configured to automatically attempt to login to clasp once a week which will confirm the authentication is still working and potentially refresh and save new tokens.
.clasprc.json File Format Reference{
"access_token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"refresh_token": "YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY",
"scope": "https://www.googleapis.com/auth/script.projects https://www.googleapis.com/auth/script ...",
"token_type": "Bearer",
"expiry_date": 0000000000000
}
The whole system described here copying the credentials out of .clasprc.json and using a scheduled trigger to automatically update the tokens on a regular basis is a hack.
The "correct" way to setup a server to server connection like is through a GCP service account. It is possible to login clasp using a key file for a service account. However, the Apps Scripts API does not work with service accounts.
$ claude mcp add deploy-google-app-script-action \
-- python -m otcore.mcp_server <graph>