SISuperintelligenceDocs

Search docs

Search every page of the documentation.

Projects and deployments

The build pipeline

What happens between a push and a ready deployment, when a push is skipped, and what the build detects and caches on its own.

What starts a build

A push that creates or updates a branch creates one deployment for every project linked to the repository. Pushing tags and deleting branches don't deploy.

The deployment's target is production when the branch is the project's production branch, and preview otherwise. Redeploys keep the target of the deployment they rebuild, and always build.

Skipped pushes

A push builds a project only when something that affects it changed. Otherwise the project gets a deployment with status skipped, and its previous deployment keeps serving.

A push is skipped when all of these hold:

  • The branch has a ready deployment to compare with.
  • The build inputs outside git are the same as that deployment's: target, framework, root directory, install and build commands, the environment variables for the target, and the linked databases and buckets. Saving a variable again counts as a change, even with the same value.
  • No file changed between that deployment's commit and the pushed commit that affects the project:
    • anything under the project's root directory, including its si.json;
    • an install file in a directory above the root directory: package.json, a lockfile (pnpm-lock.yaml, yarn.lock, package-lock.json, npm-shrinkwrap.json, bun.lock, bun.lockb), pnpm-workspace.yaml, .pnpmfile.cjs, .npmrc, .yarnrc, .yarnrc.yml, or anything under .yarn/ or patches/;
    • a path matching one of the root directory's si.json watch patterns.

When the change list can't be read, or si.json can't be read, the push builds. Projects whose root directory is the repository root build on every change.

A skipped deployment records the deployment it reused and the reason; a built one records why it built (for example changed apps/web/page.tsx or first deployment of this branch).

Where it runs

Builds run on the platform, one per deployment, on ARM (Graviton) Linux with 4 GB of memory and Node.js 22. Each build gets its own short-lived credentials (one hour) that reach only its own repository, its own deployment's files and its project's build cache: one build can't read or overwrite another deployment's output.

The build log marks each step with a ::step line:

StepDoes
sourceChecks out the commit.
restoreRestores the dependency and Next.js caches.
installInstalls dependencies.
buildBuilds the app for its framework.
uploadUploads static files and the server bundle.
saveSaves the caches for the next build.
doneFinished; publishing starts.

The deployment's page in Cloud shows how long each step took and whether the caches hit.

Install

The build installs from the nearest directory with a lockfile, starting at the root directory and going up to the repository root, so a workspace member installs from its workspace root:

LockfilePackage managerRuns
pnpm-lock.yamlpnpmpnpm install --frozen-lockfile
yarn.lockYarnyarn install --immutable (Yarn 2+), or yarn install --frozen-lockfile (Yarn 1)
package-lock.json or npm-shrinkwrap.jsonnpmnpm ci
none, but package.json in the root directorynpmnpm install

The package manager version comes from the packageManager field of that directory's package.json (for example "pnpm@9.15.4"). Without it, pnpm's version follows the lockfile format (7, 8 or 9), Yarn is 4 for a Yarn 2+ lockfile or .yarnrc.yml and 1 otherwise, and npm is the one that ships with Node.js.

An install command set on the project replaces this step and runs in the root directory.

Build

Next.js:

  • Without a next.config.* file, an empty next.config.mjs is created (OpenNext needs one).
  • OpenNext (@opennextjs/aws 3) builds the app and packages the server function.
  • Prerendered pages seed the deployment's incremental cache.

Static:

  • The project's build command runs if it has one; otherwise the package manager's run build runs when package.json has a build script.
  • The output directory is the project's setting, or else the first of dist, out and build that exists, or else the root directory itself.

Caches

Builds of a project share two caches:

CacheHoldsUsed
DependenciesThe package manager's store, for one lockfile and package manager version.Restored before install. A changed lockfile restores the project's newest archive for the same package manager and saves a new one.
Next.js.next/cache of the root directory.Restored with the dependencies and saved after the upload.

Archives over 1 GB aren't saved. Caches expire 14 days after they were last written; an archive still in use is refreshed after 7. A cache that can't be read is ignored and the build installs from scratch.

Upload

  • Files under _next/static/ are uploaded with Cache-Control: public,max-age=31536000,immutable.
  • Every other file is uploaded with Cache-Control: public,max-age=0,must-revalidate.
  • .git/, .next/ and node_modules/ are never uploaded.
  • si.json in the root directory is saved with the deployment (see si.json).

Environment during the build

The build sees the project's environment variables for the deployment's target, so values such as NEXT_PUBLIC_* are compiled in. It also sees DEPLOYMENT_ID, PROJECT_ID and ORG_ID.

Platform variables (SI_*, linked storage, the cron secret) are set on the server function only; they aren't available while building, or to static sites.

When a build fails

The deployment's status becomes error with a short reason:

ReasonMeaning
Build could not startThe build couldn't be started. Push again or redeploy.
Build failedA step exited with an error. The build logs show which.
Deploy failedThe build succeeded but publishing didn't.

A build stopped before it finished leaves the deployment canceled.

Planned

  • Passing build variables through Parameter Store instead of build environment overrides. Coming soon