Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Apps Script and Cloudbuild CI Login

So I am pretty stuck yet so close to getting a Google Apps Script project to push and deploy with Clasp through Googles Cloudbuild. So the push and deploy commands come from Googles Clasp cli which requires you to log in with your Google credentials with clasp login. The login will create a file in your home dir called ~/.clasprc.json with your credentials. This is needed to push and deploy. In the cloudbuild.yaml I created a substitution called _CLASPRC to hold the contents of this file and used my own custom image to write it to the container while running the build.

Now for the issue, I get the error below when the push command runs which is basically a not very useful way of saying I'm not logged in or any other error with the .clasprc.json. Since this is the only error I ever get no matter what the problem is, the issue is a bit hard to debug.

Could not read API credentials. Are you logged in globally?

I have tried putting the .clasprc.json in the home dir and the project dir but get the same issue both ways. I'm pretty sure the file is getting written to the projects dir because when I try to run on my local without the .clasp.json it complains it's missing before complaining I'm not logged in. When the .clasp.json is there it only complains I'm not logged in.

The project is just a personal project of mine and it is all open source on Github so here is the link to the actual project if you want some reference to the actual code. My Lil Admin and the builder I used My Builders. However you really don't need the project, to reproduce follow the steps below on your local.

  1. make sure to have a GCP project created and the gcloud cli with Apps Script API enabled
  2. have the clasp cli with npm install -g @google/clasp
  3. clasp login to get a .clasprc.json and auth with GCP
  4. clasp create --title "My Script" --type webapp and take note of the Scripts ID
  5. associate the apps script project with your GCP project

The following steps are the files which lead to the problem. Simply add them to the clasp project created. 6. Here is the entrypoint for my Clasp Builder Image:

builder/clasp_ci.sh

#!/bin/bash

# if there is a _CLASPRC var and no .clasprc.json file
if [ ! -z "${_CLASPRC}" -a ! -f "${HOME}/.clasprc.json" ]; then
echo $_CLASPRC > "$HOME/.clasprc.json"
fi

# if there is a _SCRIPT_ID and PROJECT_ID and no .clasp.json file
if [ ! -z "${_SCRIPT_ID}" -a ! -z "$PROJECT_ID" -a ! -f ".clasp.json" ]; then
cat > '.clasp.json' << EOF
{"scriptId":"$_SCRIPT_ID","projectId": "$PROJECT_ID"}
EOF
fi

# pass args to clasp
clasp "$@"
  1. The builders dockerfile

builder/Dockerfile

# use Node LTS (Boron)
FROM node:8.16.1

COPY clasp_ci.sh /usr/local/bin/clasp_ci

# install Clasp CLI
RUN npm install -g @google/clasp && \
    chmod +x /usr/local/bin/clasp_ci

ENTRYPOINT ["/usr/local/bin/clasp_ci"]
  1. now the cloudbuild to push the clasp builder

builder/cloudbuild.yaml

steps:
  - name: 'gcr.io/cloud-builders/docker'
    args: [ 'build', '-t', 'gcr.io/$PROJECT_ID/clasp', '.' ]
images:
  - 'gcr.io/$PROJECT_ID/clasp'
  1. my cloudbuild ci for an apps script project. If you're making a new project to follow along you don't need the build steps nor the dir key in the push and deploy steps. This is pretty specific to the project in the links to my project above.

cloudbuild.yaml

steps:

- id: install
  name: 'gcr.io/cloud-builders/npm'
  args: ['install']

- id: build-server
  name: 'gcr.io/cloud-builders/npm'
  args: ['run','gas']
  env:
    - 'NODE_ENV=production'

- id: build-client
  name: 'gcr.io/cloud-builders/npm'
  args: ['run','prod']
  env:
    - 'NODE_ENV=production'

- id: push
  name: 'gcr.io/$PROJECT_ID/clasp'
  dir: './dist/gas'
  args: ['push','-f']

- id: deploy
  name: 'gcr.io/$PROJECT_ID/clasp'
  dir: './dist/gas'
  args: ['deploy','$TAG_NAME']

substitutions:
  _CLASPRC: 'your clasp rc file in your home dir after logging in locally'
  _SCRIPT_ID: 'your script id of the apps script project to deploy to'
  1. Here is the command to load the builder. Make sure to replace yourproject with your actual project ID.
cd builder && gcloud builds submit --project yourproject --config=cloudbuild.yaml .
  1. the command to finally get the error. Make sure to replace yourproject with your actual project ID and your_script_id with your actual script ID you took note of in step 4.
gcloud builds submit --project yourproject --config=cloudbuild.yaml . \
--substitutions=_CLASPRC="$(cat $HOME/.clasprc.json)" \
--substitutions=_SCRIPT_ID="your_script_id"

I have also tried using the credentials created from logging in with OAuth but I got the same exact error. However this may be useful in solving the issue. Docs for Clasp Run with OAuth

Hopefully someone can help me get this working. If so, this would be the first documentation online for a Cloudbuild CI with Apps Script and Clasp since I can't find anyone doing this anywhere. I have found some links using travis and jenkins but what they are doing for some reason does not work. Does anyone see what something that I'm not? What am I missing here?!?!

Some other somewhat related or never solved issues:

  • https://github.com/google/clasp/issues/524
  • https://github.com/google/clasp/blob/master/tests/README.md
  • https://github.com/google/clasp/issues/225
  • https://github.com/gazf/google-apps-script-ci-starter
like image 343
mr haven Avatar asked Sep 24 '19 16:09

mr haven


1 Answers

OK, so after a bunch of debugging I find out the cloudbuild substitution variables do not translate to environment variables in the container. You have to manually set the environment variables to the substitution variables and then the container will get the variables it needs.

Here is the updated CI Entry point:

builder/clasp_si.sh

#!/bin/bash

if [ ! -z "${CLASPRC}" -a ! -f "${HOME}/.clasprc.json" ]; then
echo $CLASPRC > "${HOME}/.clasprc.json"
fi

if [ ! -z "${SCRIPT_ID}" -a ! -z "$PROJECT_ID" -a ! -f ".clasp.json" ]; then
cat > '.clasp.json' << EOF
{"scriptId":"$SCRIPT_ID","projectId": "$PROJECT_ID"}
EOF
fi

clasp "$@"

and then the updated cloudbuild config:

cloudbuild.yaml

steps:

- id: install
  name: 'gcr.io/cloud-builders/npm'
  args: ['install']

- id: build-server
  name: 'gcr.io/cloud-builders/npm'
  args: ['run','gas']
  env:
    - 'NODE_ENV=production'

- id: build-client
  name: 'gcr.io/cloud-builders/npm'
  args: ['run','prod']
  env:
    - 'NODE_ENV=production'

- id: push
  name: 'gcr.io/$PROJECT_ID/clasp'
  dir: './dist/gas'
  args: ['push','-f']
  env:
    - 'CLASPRC=$_CLASPRC'
    - 'SCRIPT_ID=$_SCRIPT_ID'
    - 'PROJECT_ID=$PROJECT_ID'

- id: deploy
  name: 'gcr.io/$PROJECT_ID/clasp'
  dir: './dist/gas'
  args: ['deploy','$TAG_NAME']
  env:
    - 'CLASPRC=$_CLASPRC'
    - 'SCRIPT_ID=$_SCRIPT_ID'
    - 'PROJECT_ID=$PROJECT_ID'

substitutions:
  _CLASPRC: 'your clasp rc file in your home dir after logging in locally'
  _SCRIPT_ID: 'your script id of the apps script project to deploy to'
like image 78
mr haven Avatar answered Nov 19 '22 14:11

mr haven