DEV Community

Hironori Takahashi
Hironori Takahashi

Posted on

Does Apps Script need CI/CD? — What happens after your scripts multiply.

One Apps Script project is easy. Ten scattered across an org is a mess. Here's how consistent constraints — not more features — solve the problem.

You can't escape Google Sheets

No engineer wakes up excited to open the Apps Script editor.

But in an organization, leaving Google Sheets behind isn't really an option. Finance manages budgets in spreadsheets. Legal tracks contracts in spreadsheets. Sales updates their pipeline in spreadsheets. No matter how many modern tools engineering introduces, everyone else lives in Google Sheets.

And Google Apps Script is the automation layer that naturally grows on top of that.

"Just migrate to Node.js." "Rewrite it in Python." Technically, sure. But the data lives in spreadsheets and the stakeholders read spreadsheets. Apps Script is the rational choice.

The problem isn't choosing Apps Script. It's that the moment you choose it, you tend to abandon software engineering practices.

Scripts multiply

Apps Script projects start small.

A form response triggers a Slack notification. A weekly report generates itself from a spreadsheet. Drive files get archived on a schedule. Each one is a few dozen lines, written directly in the web editor. It works. Done.

But these "quick automations" multiply. Before long, a dozen Apps Script projects are scattered across the organization. Nobody's quite sure who maintains what.

Sound familiar?

What templates don't solve

When you search for Apps Script templates, there are quite a few.

labnol/apps-script-starter is the go-to starter. Many others offer TypeScript support, bundler configuration, and test environments. Templates with CI/CD exist too.

Apps Script Engine is clasp-endorsed. It ships with Vite + Alpine.js + Tailwind, Vitest, and environment management. A feature-rich DX package ideal for a single complex project.

In other words, "how to develop a single Apps Script project with modern tools" is a solved problem.

But there's a different problem that remains unsolved: what happens after your scripts multiply.

I've written before about how constraints expand possibilities. The right boundaries focus effort and improve output. In the Apps Script ecosystem, the opposite is happening. Tooling for individual project DX has matured. But no one has designed the constraints for governing many scripts across an organization.

What a template gives one project differs from what ten projects need at the org level. The latter requires not more features, but consistent constraints.

1 repo = 1 function

That's why I built Apps Script Fleet.

The idea is simple: one function per repository, kept small.

Architecture — 1 repo per function with shared org infrastructure

Apps Script Fleet is deliberately minimal: fewer features, more constraints, smaller scope.

Click "Use this template" on GitHub and you get TypeScript, testing, and CI/CD out of the box. It works on GitLab too — cloud and self-managed — with the same pipeline on both platforms. Clasp authentication is shared via GitHub Organization Secrets or GitLab Group Variables. Set it up once, and every new repo inherits it.

The cost of adding a new Apps Script function drops to nearly zero.

Instead of cramming features into one bloated project, you spawn small repos as needed. Renovate auto-updates dependencies across all of them. Template sync propagates tooling improvements from the upstream template. It uses a whitelist approach where only infrastructure files are synced. Your code (src/, test/, README.md) is never overwritten. Even at 20 repos, the maintenance burden barely changes.

Working examples cover all three patterns: custom functions, Web Apps, and time-driven triggers.

A developer's day: without vs with Apps Script Fleet

"Why not a monorepo?" Because Apps Script projects are typically small, self-contained automations. Workspace tooling and selective deploys add complexity that doesn't pay off at this scale. Separate repos give you independent CI/CD, clear ownership, and simpler mental models.
That said, a monorepo works fine too. Apps Script Fleet doesn't mandate separate repos — it recommends them as the lower-friction default. If your team already has monorepo conventions in place, the same constraints apply. The point isn't the repo structure. It's keeping each function small enough to own.

Constraints that protect quality

The default Jest configuration enforces 80% test coverage. Low enough to not block adoption, but high enough to be a meaningful quality gate. Each project has a tiny scope — typically 5 to 10 functions. At that scale, even 100% coverage is realistically achievable.

The key constraint here is entry point separation. Apps Script only recognizes top-level functions. src/index.ts is reserved for entry points (doGet, doPost, etc.). Business logic lives in separate modules. Entry points depending on Apps Script globals (HtmlService, etc.) are excluded from coverage. Pure business logic gets tested. The constraint guarantees testability.

Add TypeScript strict mode, ESLint, and Prettier, and you match any production codebase.

Deploys are constrained too. Production deploys on main are sequential — they never skip or cancel an in-progress deployment. Dev deploys on the dev branch allow cancel-in-progress for fast iteration. The constraint protects production while preserving development speed.

And constraints don't mean rigidity. The template offers pre/post-deploy hooks as extension points. You can plug in repo-specific deployment logic without touching template-managed files. The right escape hatches, designed into the constraints.

Constraints that unlock AI

Narrow scope, strict types, tests that define correctness. This is exactly the environment where AI coding tools shine.

Claude Code and Copilot struggle most with large, boundary-ambiguous codebases. They thrive when scope is tight, types are strict, and tests define what "correct" means.

Spin up a new repo from Apps Script Fleet. Tell the AI to implement doPost and write the tests. The CI/CD pipeline verifies the output.

From template creation to script ID setup: minutes. From AI writing code to CI passing: minutes. What used to take 2–4 hours of boilerplate per project now takes minutes.

Humans design the quality gates. AI writes the code. CI verifies it. The division of labor emerges naturally.

This wasn't intentionally designed for AI. It's what happened when I brought standard software engineering practices to Apps Script. The right constraints expanded what was possible.

Not despite Apps Script, but because of it

Your org uses Apps Script for good reasons. The data is in spreadsheets. The stakeholders are in spreadsheets.

That's no reason to compromise on engineering just because the runtime is Apps Script.

Tests, CI/CD, code review — the same standards as any other software. Apps Script Fleet exists to make that barrier zero.

If your team has more than three Apps Script projects, give it a try.

GitHub logo h13 / apps-script-fleet

Infrastructure for scaling Google Apps Script across your organization

Apps Script Fleet

CI License: MIT Node.js TypeScript Google Apps Script

日本語

Infrastructure for scaling Google Apps Script across your organization.

Most Apps Script templates help you set up one project with modern tooling. This one is designed so you never have to set up tooling again — create a repo from this template, set a script ID, and your CI/CD pipeline is already running. Works with GitHub and GitLab — cloud and self-managed.

→ Quick Start · What's Included · How This Differs · FAQ

The Problem

Apps Script projects start small, but they multiply. Slack notifications, report generation, form processing, Drive automation — before long, your organization has a dozen scripts. Each one needs:

  • TypeScript configuration
  • A bundler (Rollup, Webpack, Vite)
  • Linting and formatting
  • Test setup with coverage
  • CI/CD workflows for dev and production
  • clasp authentication management
  • Ongoing dependency updates

Setting this up takes 2–4 hours per project. At 10 projects, that's a week of pure…

Top comments (0)