apps-script-clasp-workflow · v1.0.0 · 2026-09-13 · sha256 a8853d333719a7bf
apps-script-clasp-workflow v1.0.0A
Immutable. This exact content is served forever at /api/v1/blob/a8853d333719a7bf.
---
name: apps-script-clasp-workflow
description: Documents the clasp CLI workflow for Google Apps Script projects — login, project creation/cloning, push vs deploy, versioning, and multi-environment (dev/staging/prod) setups. Use when setting up CI/CD for an Apps Script project, publishing a new version, or switching between multiple script IDs. Framework-agnostic — applies with or without bootgs.
license: Apache-2.0
metadata:
author: Maksym Stoianov
version: "1.0.0"
---
# Apps Script clasp Workflow
## Auth
```bash
clasp login # interactive, opens a browser
clasp login --no-localhost # headless/CI — prints a URL to visit, then paste the resulting code back
```
Produces `~/.clasprc.json`. In CI, inject this file from a secret — never commit it; it's a live OAuth credential.
## Project setup
```bash
clasp create --type standalone --title "My Project" # new project
clasp clone <scriptId> # existing project
```
`.clasp.json` fields that matter:
| Field | Purpose |
|---|---|
| `scriptId` | Target Apps Script project — the single most important field to get right per environment (see Multi-environment below) |
| `rootDir` | Directory clasp pushes from, e.g. `"./dist/appsscript"` — point it at your **build output**, not source, if you bundle |
| `filePushOrder` | Files pushed first, before the rest — `appsscript.json` is commonly listed here since manifest changes should land before code that depends on new scopes/services |
## Push vs. deploy — the distinction that causes silent "my fix isn't live" bugs
- `clasp push` updates the project's **HEAD** (the editor/dev version). Anyone opening the script editor sees it immediately. It does **not** affect any existing versioned deployment.
- `clasp deploy` creates or updates a **versioned deployment** with a stable URL/ID. A web app or add-on installed by end users runs whatever version its deployment points at — pushing new code does nothing for them until you deploy.
```bash
clasp push -f # force push, skip the interactive diff/overwrite prompt — needed for CI
clasp push --watch # dev loop: push on every local file change
clasp deploy -i <deploymentId> -d "Fix widget sorting" # update an existing deployment
clasp deployments # list deployment IDs
clasp versions # list version history
```
Forgetting the deploy step after a push is the single most common "I fixed it but users still see the bug" report — always pair a fix with a deploy when the project has a live deployment.
## Multi-environment (dev/staging/prod)
clasp has no native named-environment concept — one `.clasp.json` points at one `scriptId`. The standard workaround is one config file per environment, copied into place before pushing:
```
.clasp.dev.json
.clasp.staging.json
.clasp.prod.json
```
```json
{
"scripts": {
"push:dev": "cp .clasp.dev.json .clasp.json && clasp push -f",
"push:staging": "cp .clasp.staging.json .clasp.json && clasp push -f",
"deploy:prod": "cp .clasp.prod.json .clasp.json && clasp push -f && clasp deploy -d \"$npm_config_message\""
}
}
```
Never commit the active `.clasp.json` if it varies per developer machine/environment — commit the per-environment copies instead and gitignore the working one, or keep `.clasp.json` itself checked in only for single-environment projects.
## Manifest essentials worth setting explicitly
Don't leave `appsscript.json` at its scaffolded defaults:
- `runtimeVersion: "V8"` — required for modern syntax and decorators (see the `bootgs-quickstart` skill if the project uses bootgs).
- `oauthScopes` — list only what's actually called. GAS shows the full list on the consent screen; an over-broad list (a common copy-paste mistake) increases user friction and review scrutiny for public add-ons without adding capability.
- `webapp.executeAs`/`webapp.access` — only relevant if `doGet`/`doPost` are deployed as a web app.
- `exceptionLogging: "STACKDRIVER"` — otherwise uncaught errors only appear in the legacy execution log tied to the script's lifetime.
## Verification
- [ ] `clasp push -f` used in CI (interactive prompts hang non-interactively without `-f`).
- [ ] A deploy step (`clasp deploy`) runs after push whenever the project has a live deployment end users depend on — push alone is not a release.
- [ ] `.clasprc.json` is never committed; CI injects it from a secret.
- [ ] `oauthScopes` reviewed against what the code actually calls before each release.