Local plans
gantrycli local-plan answers “what would this change do?” for code that only
exists on your machine. It uploads a tarball of your working tree — uncommitted
changes included — and runs a normal plan on the stack’s runners, with the
stack’s real backend, environment variables, and cloud credentials. Nothing is
pushed to your repository, and the resulting plan can never be applied.
Running a local plan
From anywhere inside the git repository the stack tracks:
gantrycli local-plan <stack-id> --org <org-id> --follow
--follow streams the run’s logs and exits with the deployment’s outcome
(same exit codes as gantrycli deployments create); --wait blocks without
streaming; neither flag just prints the deployment ID.
What gets uploaded: the output of git ls-files --cached --others --exclude-standard — tracked files (with your local modifications) plus
untracked files that are not gitignored. .gitignored content (.terraform/,
build artifacts, local secrets files) never leaves your machine. Submodule
contents are not uploaded. The server enforces a size limit
(LOCAL_DEPLOY_MAX_SOURCE_BYTES, default 512 MiB).
The upload and trigger must complete within the reservation window
(LOCAL_DEPLOY_UPLOAD_TTL, default 15 minutes); on expiry, just run the
command again.
If the repository’s origin remote is not the repository the stack tracks,
the CLI prints a warning but proceeds — planning an unrelated tree against a
stack is allowed, it just usually isn’t what you meant.
The deployment records the user who triggered it (shown on the deployment detail view), since the commit author of an uploaded tree is whatever the local git config says and can’t stand in for an audit trail.
What a local deployment is (and is not)
A local deployment behaves like a pull-request preview plan:
- Plan-only. One plan run, no confirmation stage, no apply. When the changes look right, commit, push, and deploy through the normal flow.
- Unlocked and parallel. It never takes the stack lane or the state lock, so it does not queue behind (or block) real deployments.
- Not retryable, not promotable. The uploaded source is deleted once the
deployment finishes; re-run
gantrycli local-planinstead. - Clearly labeled. The deployment timeline and detail view badge it as
local, the commit snapshot shows a(dirty)marker when the working tree had uncommitted changes, and no commit status is published to your SCM.
Enabling local plans for a stack
Local plans are opt-in per stack: holding the (stack, local_deploy)
permission is necessary but not sufficient. Each stack has an Allow local
plans toggle (in the stack’s Options tab, off by default); a stack rejects
local-plan until an operator turns it on. Existing stacks default to off, so
the capability can never reach a stack an operator didn’t explicitly opt in.
Turning it back off blocks new reservations immediately, and a reservation
made while it was on cannot be triggered after it is turned off.
Permission
Local plans are gated by the dedicated (stack, local_deploy) permission —
separate from (stack, deploy), because the planned code never went through
review in your repository yet still executes providers with the stack’s
runtime credentials. Grant it with the built-in Stack Local Deployer role
or a custom role (see Access control); admin and
stack-admin hold it through their (stack, *) wildcard. Service accounts
cannot use local plans.