Zum Inhalt springen
GigadriveDocs

Builds

What runs between a commit and a live URL, and how to read the build log while it happens.

A build turns the commit you deployed into the assets and Functions that serve traffic. Every build runs in a fresh sandbox, and writes each step to a log you can follow while it happens.

What runs, in order

  1. Source. A Git-linked application downloads the commit from GitHub. An upload from Deploy without Git, the CLI, or the API downloads the ZIP you sent instead.
  2. Install. Gigadrive Network detects your package manager and runs its install command from the repository root, so workspace configurations are picked up.
  3. Build. Your build script runs from the project root.
  4. Package. The output is collected, measured, and uploaded.
  5. Provision. Functions and static assets are created. This deployment's permanent hostname is reserved earlier, as soon as the build starts.
  6. Publish. The branch URL, and the production URL for a production deployment, move onto the new deployment. The CDN cache for those hostnames is purged and the deployment goes live.

Deployment status

The console labels a few statuses differently from the values the API returns.

API valueConsole labelMeaning
PENDINGPendingCreated. An upload stays here until its archive finishes transferring.
QUEUEDQueuedWaiting for the build to be picked up.
STARTINGStartingReserved. Deployments currently move from QUEUED straight to BUILDING.
BUILDINGBuildingInstall and build commands are running.
PROVISIONINGDeployingThe build finished. Functions and static assets are being created.
WAITING_FOR_CAPACITYWaiting for capacityThe build finished, and compute for it is not available yet.
ACTIVEReadyServing traffic.
FAILEDFailedThe build or provisioning failed, or you cancelled it.

There is no separate cancelled status. Cancelling a running deployment marks it FAILED, and so does a build that a newer commit on the same branch supersedes.

The build sandbox

Each build gets its own sandbox with pnpm, yarn, bun, git, curl, and Composer already installed, plus a warm package-manager store. A build is stopped after 25 minutes.

Your resolved environment variables are injected before install runs, so a private registry token or a build-time API key is available to install and build scripts. Values marked sensitive are injected too, and their plaintext is stripped from the build log and from error output.

The platform sets some variables of its own, and the order decides who wins:

VariablesApplied
PROJECT_DIRECTORY, VERCEL=1, CI=true, NITRO_PRESET=node-server, package-manager cache pathsBefore yours, so you can override them
GIGADRIVE_* and NEXT_ADAPTER_PATHAfter yours, so you cannot

Anything in the first row is a default you can replace with a variable of your own. VERCEL=1 is there because a large part of the ecosystem branches on it, and NITRO_PRESET=node-server is pinned so that Nuxt keeps writing to .output. The second row identifies the deployment and points the Next.js adapter at its runtime files, so those values always win. GIGADRIVE_ is a reserved prefix, and a variable of yours cannot start with it. See System variables for the full list.

Install command

You do not choose the install command. It follows from your project, in this order:

  1. packageManager in package.json, for example pnpm@10.28.1.
  2. devEngines.packageManager in package.json.
  3. The lockfile: pnpm-lock.yaml, yarn.lock, bun.lock, bun.lockb, package-lock.json, or npm-shrinkwrap.json.
  4. A package.json with no lockfile, which means npm.

The frozen-lockfile form runs first: pnpm install --frozen-lockfile, npm ci, yarn install --immutable on Yarn 2 and later, bun install --frozen-lockfile. If that fails, the build retries with a plain install. A composer.lock adds composer install --no-interaction, and PHP projects install through Composer whatever their JavaScript lockfile says. With neither a lockfile nor a package.json the log reads No package manager lock file found, skipping install.

Install only your application's package

In a pnpm workspace, the install covers the whole repository by default. To install only the package at your root directory and its dependencies, open Settings, General and select Install only this application's package under Root directory. The build then runs pnpm install --frozen-lockfile --filter "{./<root directory>}...", which installs that package and the workspace packages it depends on.

The scoped install applies only when the root directory is a workspace member. Otherwise the log reads Root directory <path> is not a pnpm workspace member; installing the whole workspace and the build continues with the default install. A scoped install that cannot satisfy the lockfile fails the build instead of retrying without the lockfile. Yarn, npm, and Bun projects always install the whole workspace.

Build command

If package.json has a string build script, it runs with the detected package manager. Without one, the step is skipped and your project is deployed as it stands, which is what a plain static site wants.

Set Root directory under Settings, General when your application does not live at the repository root. Everything after the source download runs from there, and the path must be relative, must stay inside the repository, and must be a real directory rather than a symlink.

When a build fails

A build command that dies on a transient network error is retried once in the same sandbox, two seconds later. The log line reads Build lost a transient network dependency; retrying once in the same sandbox.

Build output has an 8 GiB budget, measured both as the compressed archive and after extraction. Crossing it fails the deployment with a message naming the size and the budget, rather than letting packaging run out of disk.

Failures caused by your code, your build output size, or a Function that exceeds its size or memory limit write the reason into the deployment log. Failures inside the platform write a short label instead, deliberately: those messages carry internal detail that does not belong in your log.

Following a build

The console streams the log live on the deployment's Logs tab. Outside the console:

import { GigadriveClient } from '@gigadrive/sdk';

const client = new GigadriveClient();

const deployment = await client.deployments.create({
  applicationId: '0197b2f1-2f4a-7a0b-8a2d-222222222222',
  gitSource: { ref: 'main' },
});

let offset = 0;
let status = deployment.status;

while (status !== 'ACTIVE' && status !== 'FAILED') {
  await new Promise((resolve) => setTimeout(resolve, 1000));

  const logs = await client.deployments.getLogs(deployment.id, { offset, limit: 100 });
  for (const line of logs.items) {
    console.log(`[${line.type}] ${line.message}`);
  }
  offset += logs.items.length;

  status = (await client.deployments.get(deployment.id)).status;
}

console.log(`Deployment ${deployment.id} finished as ${status}`);

The stream resumes from where it stopped if you send the last event id back in a Last-Event-ID header. One connection lasts 900 seconds by default, and budgetSeconds shortens it to as little as 5.