rangutopia
v0.0.11
Published
A CLI to manage our scripts across the organization.
Readme
rangutopia
A CLI to manage our scripts across the organization.
client deploy
Deploys private workspace packages via a provider plugin. Only the vercel provider is implemented today (--provider <name>, default vercel); passing any other name throws "not implemented" — the dispatch is in place so adding another provider is one new branch, not a rewrite. Works on nx and turborepo monorepos.
Usage
rangutopia client deploy --prod
rangutopia client deploy --next
rangutopia client deploy --preview
rangutopia client deploy --next --exclude @scope/a,@scope/b
rangutopia client deploy --next --vercel-config ./my-vercel.json
rangutopia client deploy --next --dry-run
rangutopia client deploy --next --provider vercelExactly one of --prod / --next / --preview is required:
| Flag | Vercel target | CLI args used |
| --- | --- | --- |
| --prod | production | vercel deploy --prebuilt --prod --skip-domain |
| --next | custom next environment | vercel deploy --prebuilt --target next |
| --preview | built-in preview | vercel deploy --prebuilt --target preview |
Required environment variables
| Variable | Purpose | Required for |
| --- | --- | --- |
| VERCEL_TOKEN | Vercel CLI auth token | non-dry-run only |
| VERCEL_ORG_ID | Vercel organization ID | non-dry-run only |
| VERCEL_PROJECT_ID_<NAME> | Per-package project ID | always — see "Project-ID requirement by environment" below |
--dry-run skips vercel pull and vercel deploy, so it never reads VERCEL_TOKEN / VERCEL_ORG_ID.
Project-ID convention
For each deployable package, the env var name is derived from the package name:
- Drop the npm scope (
@scope/). - Uppercase the result.
- Replace any character that is not
[A-Z0-9]with_. - Prefix with
VERCEL_PROJECT_ID_.
Examples:
| Package | Env var |
| --- | --- |
| @rango-dev/widget-app | VERCEL_PROJECT_ID_WIDGET_APP |
| @rango-dev/queue-manager-demo | VERCEL_PROJECT_ID_QUEUE_MANAGER_DEMO |
| rango-dapp | VERCEL_PROJECT_ID_RANGO_DAPP |
Per-package requirements
A package opts in by being "private": true in its package.json. The "main" field must point to a file inside the build-output directory — its directory will be uploaded to Vercel. Example:
{
"name": "@scope/widget-app",
"private": true,
"main": "dist/index.html"
}If main is missing, the deploy command throws MissingMainError naming the package.
Project-ID requirement by environment
--previewis strict. Every selected package must have a configuredVERCEL_PROJECT_ID_<NAME>. A missing ID throwsMissingVercelProjectIdErrorwith the expected env var name. Rationale: preview is the deliberate per-package test path, and silent skipping would hide misconfiguration.--prodand--nextare lenient. Packages without a project ID are silently skipped — useful for workspaces where only some private packages are deployable apps.
vercel.json
Per invocation, the deploy resolves a vercel.json for each package in this order:
--vercel-config <path>if passed — wins for every package, no per-package override.<pkg.location>/vercel.jsonif it exists — the package ships its own.templates/deploy/vercel.json— the shipped default,{ "rewrites": [{ "source": "/(.*)", "destination": "/" }] }.
Supported keys at the top level of any vercel.json: routes, rewrites, redirects, headers, cleanUrls, trailingSlash — the input shape accepted by @vercel/routing-utils.getTransformedRoutes. Anything else throws.
A fingerprint cache-control rule (s-maxage=31536000, immutable for *.<hash>.{css,js,png,jpg,webp,avif,svg}) is prepended to the route list before being written to .vercel/output/config.json.
Flags
--provider <name>— deploy provider. Defaults tovercel. Any other value throws "not implemented".--exclude <names>— comma-separated package names to skip (e.g.--exclude @scope/a,@scope/b).--vercel-config <path>— explicitvercel.jsonused for every package, overriding per-package files and the shipped template. Resolved relative to the current working directory.--dry-run— runs the filter and produces the build-output artifact at<pkg.location>/.vercel/output/{static,config.json}, but skipsvercel pullandvercel deploy. Doesn't needVERCEL_TOKEN/VERCEL_ORG_ID.
Example GitHub Actions step
- name: Deploy
env:
VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID_WIDGET_APP: ${{ secrets.VERCEL_PROJECT_ID_WIDGET_APP }}
run: |
yarn global add vercel
rangutopia client deploy --preview