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
- 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.
- Install. Gigadrive Network detects your package manager and runs its install command from the repository root, so workspace configurations are picked up.
- Build. Your
buildscript runs from the project root. - Package. The output is collected, measured, and uploaded.
- Provision. Functions and static assets are created. This deployment's permanent hostname is reserved earlier, as soon as the build starts.
- 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 value | Console label | Meaning |
|---|---|---|
PENDING | Pending | Created. An upload stays here until its archive finishes transferring. |
QUEUED | Queued | Waiting for the build to be picked up. |
STARTING | Starting | Reserved. Deployments currently move from QUEUED straight to BUILDING. |
BUILDING | Building | Install and build commands are running. |
PROVISIONING | Deploying | The build finished. Functions and static assets are being created. |
WAITING_FOR_CAPACITY | Waiting for capacity | The build finished, and compute for it is not available yet. |
ACTIVE | Ready | Serving traffic. |
FAILED | Failed | The 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:
| Variables | Applied |
|---|---|
PROJECT_DIRECTORY, VERCEL=1, CI=true, NITRO_PRESET=node-server, package-manager cache paths | Before yours, so you can override them |
GIGADRIVE_* and NEXT_ADAPTER_PATH | After 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:
packageManagerinpackage.json, for examplepnpm@10.28.1.devEngines.packageManagerinpackage.json.- The lockfile:
pnpm-lock.yaml,yarn.lock,bun.lock,bun.lockb,package-lock.json, ornpm-shrinkwrap.json. - A
package.jsonwith 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.
