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.
Scanned 9/19/2026
Install to Claude Code
npx -y skills add bootgs/skills --skill apps-script-clasp-workflow --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Apps Script Clasp Workflow?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/bootgs-apps-script-clasp-workflow)More formats (shields.io, HTML) on the badges page.
---
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.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!