# Deploy commands

> Deploy a project with helix deploy, wait for the rollout, check a deployment's status and build errors, and generate a CI pipeline with helix ci init.

`helix deploy` ships your project to Tray's cloud in one command, and prints the URL where it's running. There's no separate build step to run first: deploy builds what it needs. `helix deployment get` looks up what happened on a given deploy, `helix deployment wait` blocks until it finishes, and `helix ci init` generates a CI pipeline that deploys for you.

## helix deploy

```bash
helix deploy
```

Deploys the project in the current directory. What happens depends on whether the project has been deployed before.

**The first deploy provisions the project.** Helix creates the project on the platform, generates a name for it, writes an AI-generated description of what the app does, and records the project ID. If no workspace is set yet, the command asks you to pick one.

**Later deploys upload a new artifact** to the project that already exists. The AI description is regenerated on each deploy, so it tracks what your app currently does.

| Flag | What it does |
|---|---|
| `--name <name>` | Name to provision the project under, used on the first deploy only. Defaults to `name` in `helix.config.ts` |
| `--config <path>` | Config file to use instead of `./helix.config.ts`. The file names the deploy target, so this is how you deploy a target other than your development default. The `HELIX_CONFIG` environment variable has the same effect; the flag wins |
| `--wait` | Keep polling after the upload until the platform finishes rolling out (v1.3.0 and later). Exits 0 once the deployment is ready; exits 1 with the build errors printed if it fails, or with a "still deploying" message if the time limit is hit |
| `--wait-interval <seconds>` | Seconds between status checks when waiting. Default 10 |
| `--wait-timeout <seconds>` | Give up waiting after this many seconds. Default 600 |

Because `--name` only applies at provisioning time, passing it to a later deploy won't rename an existing project.

Without `--wait`, the command returns as soon as the upload is accepted, while the platform is still building; the status it prints is `deploying`. Use `--wait` in scripts and CI, where the exit code has to mean the deployment is live:

```bash
helix deploy --config helix.production.config.ts --wait
```

```bash
helix deploy --config helix.production.config.ts
```

A deploy always lands in the workspace and project the selected file names, and a first deploy with `--config` writes the provisioned project ID into that file. See [the configuration model](/documentation/concepts/configuration/) for the one-config-file-per-target workflow.

### What you get back

A successful deploy prints three things:

| Output | What it's for |
|---|---|
| Project ID | The project's identifier, also written into `helix.config.ts` |
| App URL | Where the app runs: `https://{project-id}.helix-app.ai` |
| Dashboard link | The project in the Helix dashboard at `https://app.helix.tray.ai` |

:::note{title="Deployed apps are never public"}
Every Helix app sits behind login. Visitors must be users in your Tray organization who have been granted access to the project. Sharing the URL isn't enough to give someone access, and there's no anonymous mode.
:::

There's no rollback command in the CLI yet. To restore a previous deployment, use **Restore** on the project's Deployments tab in the Helix dashboard; see [restoring a previous deployment](/documentation/guides/deployment/#restore-a-previous-deployment).

## helix deployment get

```bash
helix deployment get <deploymentId>
```

Shows the status of one deployment: whether it succeeded, any warnings raised during the build, and the build errors if it failed. Use it when a deploy doesn't come back clean, or when you want to confirm which deployment is live.

```bash
helix deployment get 4f2b8c1e-9d3a-4e77-b5c0-6a1f8e2d4b90
```

Like `helix deploy`, it accepts `--config <path>` to look up a deployment against a config file other than `./helix.config.ts`.

Deployments are retained for 30 days, apart from the live deployment and the one before it, which are always kept. A deployment past that window is deleted and no longer returned. See [how long previous deployments are kept](/documentation/guides/deployment/#how-long-previous-deployments-are-kept).

The Helix dashboard shows the same deployment history per project, alongside execution logs, and adds two things the CLI doesn't have yet: restoring a previous deployment and downloading a deployment's source. See [restoring a previous deployment](/documentation/guides/deployment/#restore-a-previous-deployment).

## helix deployment wait

```bash
helix deployment wait <deploymentId>
```

Waits for a deployment you already started (v1.3.0 and later). Polls its status every 10 seconds and exits 0 once it's ready. Exits 1, with the warnings and build errors printed, if it fails, and exits 1 with a "still deploying" message if the time limit passes first. A status lookup that fails for a moment is retried, not treated as a failed deployment.

| Flag | What it does |
|---|---|
| `--interval <seconds>` | Seconds between status checks. Default 10 |
| `--timeout <seconds>` | Give up after this many seconds. Default 600 |
| `--config <path>` | Config file to look the deployment up against, as for `helix deployment get` |

## helix ci init

```bash
helix ci init
```

Generates the CI pipeline that deploys the project (v1.3.0 and later). It asks which CI service you use and how deploys should be triggered, writes the workflow file or files under `.github/workflows/`, and prints the one-time setup to do on GitHub. Before writing anything it checks that every target it will deploy has a config file with a `projectId` and `workspaceId`, and stops with the fix when one doesn't. The full walkthrough, including creating the token the workflow uses, is in [Deploy from CI](/documentation/guides/continuous-deployment/).

| Flag | What it does |
|---|---|
| `--provider <id>` | CI service to generate for. `github` is the only value today. Skips the question |
| `--strategy <id>` | How deploys are triggered: `manual-production`, `production-on-merge`, or `staging-on-merge`. Skips the question |
| `-f, --force` | Overwrite existing workflow files without asking |

Without a terminal, `--provider` and `--strategy` are required. The generated workflows authenticate with a `TRAY_CLI_TOKEN` secret; setting that variable makes any `helix` command use the token instead of a saved login.

:::warning{title="An API user token reaches the whole workspace"}
The token isn't limited to Helix. It acts as its API user across everything in that workspace, including shared Tray iPaaS assets such as workflows and authentications. Give the API user the lowest workspace role that can still deploy, keep the token in your CI secret store, set an expiry, and delete the API user if the token is ever exposed.
:::

---

Canonical: https://helix.tray.ai/documentation/reference/cli/deploy/
Any link on this page is available as markdown by appending .md to its URL.
Full corpus: https://helix.tray.ai/documentation/llms-full.txt