Deploy
Run helix ci init and Helix writes a GitHub Actions workflow into your repo. Merge to your default branch, or start it by hand, and the job deploys your project and waits until the new version is live.
Your pipeline
Waiting for a mergeMerged to main
Tray Helix
Deploy
Run
Govern
In short
Tray Helix can deploy from CI. In Helix CLI 1.3.0, helix ci init writes a GitHub Actions workflow that deploys the project on demand, on every merge to the default branch, or to staging on merge with production waiting for a reviewer in GitHub. CI signs in as a Tray API user through a TRAY_CLI_TOKEN secret, the job waits for the rollout and passes only when the new version is ready. Any other CI service can run the same deploy command.
Until now a Helix deploy ran from someone’s machine, signed in as them. With Helix CLI 1.3.0 it can run from your CI pipeline instead. helix ci init writes the GitHub Actions workflow for you, CI signs in as a Tray API user, and helix deploy --wait keeps the job open until the new version is live, so the check on your commit tells you whether it shipped.
A team has a Helix project with a staging target and a production target, each deployed once by hand from a laptop. They want staging to follow main and production to ship only when someone signs it off. Here is the setup, start to finish.
From the project root, pick the CI service and how deploys should start:
helix ci init --provider github --strategy staging-on-merge
There are three setups. manual-production, the default, deploys production only when you start it. production-on-merge deploys production on every push to the default branch, and on demand. staging-on-merge deploys staging on every push and production on demand, behind an approval. Run helix ci init with no flags to choose in a prompt.
This team gets two files, deploy-staging.yml and deploy-production.yml. Before writing them, the command checks three things: that helix.staging.config.ts and helix.production.config.ts both exist, that each already has a projectId and workspaceId, and that the repo has a package-lock.json or pnpm-lock.yaml. It also pins the CLI in the workflow to the version of @trayai/helix-sdk the project uses, since the two are released together.
CI needs a Tray API user, not a person’s session. In Tray, go to Account Settings, then Tokens, then Create API user. Pick the workspace the project deploys to and the lowest workspace role that can deploy, then create a token with an expiry and copy it, because it is shown once. Check it works before you store it:
TRAY_CLI_TOKEN=<token> helix whoami
In GitHub, the staging-on-merge setup reads the secret from two environments, Staging and Production. Save the token as TRAY_CLI_TOKEN in each, and add required reviewers to Production.
The next push to the default branch runs deploy-staging.yml. Every generated workflow does the same four things: checks out the repo, sets up Node.js 24 and installs dependencies from the lockfile, installs the pinned Helix CLI, and runs:
helix deploy --config helix.staging.config.ts --wait
--wait keeps polling after the upload until Helix has finished rolling out. The job passes when the deployment is ready.
Start deploy-production.yml from the Actions tab, or from a terminal:
gh workflow run deploy-production.yml
GitHub holds the job until a reviewer on the Production environment approves it, then runs the same steps against helix.production.config.ts.
helix deployment wait <id> picks up a deploy that is still going.TRAY_CLI_TOKEN is set, every helix command uses it and never writes a session to disk, so the same variable works on any machine.The token opens the whole workspace. A Tray API user token is scoped to one workspace but reaches everything in it across Tray, including workflows and authentications. Treat it as a production credential: keep it in your CI secret store only, give the API user the lowest role that deploys, set an expiry, use a separate token per workspace, and delete the API user if the token leaks.
Deploy by hand once first. helix ci init refuses to write a workflow for a target with no projectId and workspaceId in its config. Deploy it once from your machine, or set both with helix project set and helix workspace set.
Staging needs both config files. The staging setup checks for helix.staging.config.ts and helix.production.config.ts before it writes anything, so a staging pipeline can never fall back to deploying production.
helix ci init writes GitHub Actions workflows only. Any other CI service needs two commands, with TRAY_CLI_TOKEN supplied from its secret store:
npm install -g @trayai/helix-cli@<your @trayai/helix-sdk version>
helix deploy --config helix.production.config.ts --wait
helix ci init writes GitHub Actions workflows. Any other CI service can deploy by installing the Helix CLI at your Helix SDK version and running helix deploy with the wait option, with TRAY_CLI_TOKEN supplied from its secret store.
No. CI signs in as a Tray API user through the TRAY_CLI_TOKEN secret, so the deploy is attributed to CI rather than to a person. When the variable is set, the CLI uses it for every command and saves nothing to disk.
The deploy step exits with an error and prints the build errors, so the job fails. A red check means the new version did not ship.
Yes, through GitHub. The staging-on-merge setup puts production in a GitHub environment, and adding required reviewers to it holds each production deploy until someone approves it in GitHub.
Deploy an app you built with your AI assistant, and see what Helix does with it.
Thanks, keep an eye on your inbox for an invite.
Want to talk to someone first? Contact us