@destinedai/deploy
v1.0.3
Published
CLI tool for versioned Vercel deployments with git integration
Downloads
50
Maintainers
Readme
@destinedai/deploy
CLI tool for versioned Vercel deployments with git integration. Bumps semver, updates Vercel environment variables, and pushes to git — triggering auto-deploy.
Install
npm install -D @destinedai/deployUsage
# Bump patch version and deploy (0.1.0 → 0.1.1)
npx destined-deploy
# Bump minor version (0.1.0 → 0.2.0)
npx destined-deploy minor
# Bump major version (0.1.0 → 1.0.0)
npx destined-deploy major
# Preview what would happen
npx destined-deploy minor --dry-run
# Skip Vercel env var updates
npx destined-deploy --skip-vercel
# Skip git operations
npx destined-deploy --skip-gitnpm scripts
Add to your package.json:
{
"scripts": {
"deploy": "destined-deploy",
"deploy:minor": "destined-deploy minor",
"deploy:major": "destined-deploy major"
}
}What it does
- Bumps version in
package.json(patch/minor/major) - Updates
.env.localwithNEXT_PUBLIC_APP_VERSIONandBUILD_TIME - Updates Vercel env vars (
NEXT_PUBLIC_APP_VERSION,BUILD_TIME) on production - Git commit, tag, and push — triggering Vercel auto-deploy
CLI Options
| Option | Description | Default |
|--------|-------------|---------|
| --dry-run | Show what would happen without executing | false |
| --skip-git | Skip git commit/tag/push | false |
| --skip-vercel | Skip Vercel env var updates | false |
| --branch <b> | Git branch to push to | "main" |
| --no-tag | Skip git tag creation | false |
| --config <path> | Path to config file | auto-detected |
| --verbose | Show detailed command output | false |
Configuration
Zero config works out of the box. To customize, create a deploy.config.js in your project root:
/** @type {import('@destinedai/deploy').DeployConfig} */
export default {
// Files to git add before committing
gitAddFiles: ['package.json', '.vercelignore', 'vercel.json'],
// Git branch to push to
gitBranch: 'main',
// Commit message template (supports {{version}})
commitMessage: 'Release v{{version}}',
// Tag template (set to false to disable)
tagTemplate: 'v{{version}}',
// Vercel env vars to set (supports {{version}} and {{buildTime}})
vercelEnvVars: [
{ name: 'NEXT_PUBLIC_APP_VERSION', value: '{{version}}' },
{ name: 'BUILD_TIME', value: '{{buildTime}}' },
],
// Vercel environment scope
vercelEnvScope: 'production',
// Local env file to update (set to false to disable)
envLocalFile: '.env.local',
};You can also use the "deploy" key in package.json:
{
"deploy": {
"gitAddFiles": ["package.json", "vercel.json"],
"gitBranch": "main"
}
}Config reference
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| vercelEnvScope | string | "production" | Vercel environment scope |
| vercelEnvVars | EnvVar[] | [APP_VERSION, BUILD_TIME] | Env vars to set in Vercel |
| gitAddFiles | string[] | ["package.json"] | Files to stage before commit |
| gitBranch | string | "main" | Branch to push to |
| gitRemote | string | "origin" | Git remote name |
| commitMessage | string | "Release v{{version}}" | Commit message template |
| tagTemplate | string \| false | "v{{version}}" | Tag template, false to disable |
| envLocalFile | string \| false | ".env.local" | Local env file path, false to disable |
| envLocalVars | EnvVar[] | [APP_VERSION, BUILD_TIME] | Vars to write to local env file |
| vercelEnvStrict | boolean | false | Fail on Vercel env update errors |
Programmatic API
import { deploy, loadConfig } from '@destinedai/deploy';
const config = await loadConfig();
await deploy({
...config,
bumpType: 'minor',
dryRun: true,
});React — Version Toast Notifications
The package ships a @destinedai/deploy/react subpath with a drop-in version checker for Next.js / React apps. When a new version is deployed, users see a toast notification prompting them to refresh.
Quick setup (3 steps)
1. Add the API route — app/api/version/route.ts:
export { versionRouteHandler as GET } from '@destinedai/deploy/react';2. Make sure you have a <Toaster /> from sonner in your root layout:
import { Toaster } from 'sonner';
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<Toaster />
</body>
</html>
);
}3. Drop in <VersionToast /> anywhere (e.g. your layout):
import { VersionToast } from '@destinedai/deploy/react';
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<VersionToast />
<Toaster />
</body>
</html>
);
}That's it. It polls /api/version every 60 seconds and shows a sonner toast when a new version is detected.
Customization
<VersionToast
interval={30000} // Check every 30s
endpoint="/api/health" // Custom endpoint
title="Update available" // Toast title
description="Refresh to get the latest features."
updateLabel="Refresh" // Button labels
dismissLabel="Not now"
/>Headless hook
If you want full control over the UI, use the hook directly:
'use client';
import { useVersionCheck } from '@destinedai/deploy/react';
export function MyCustomBanner() {
const { updateAvailable, refresh, dismiss, isRefreshing } = useVersionCheck({
interval: 60000,
});
if (!updateAvailable) return null;
return (
<div>
<p>New version available!</p>
<button onClick={refresh} disabled={isRefreshing}>
{isRefreshing ? 'Updating...' : 'Update'}
</button>
<button onClick={dismiss}>Later</button>
</div>
);
}Exports from @destinedai/deploy/react
| Export | Type | Description |
|--------|------|-------------|
| VersionToast | Component | Drop-in sonner toast notification |
| useVersionCheck | Hook | Headless hook returning { updateAvailable, refresh, dismiss, isRefreshing } |
| VersionChecker | Class | Low-level checker with start(), stop(), refresh() |
| versionRouteHandler | Function | Next.js API route handler for /api/version |
Prerequisites
- Node.js >= 18
- Vercel CLI installed and authenticated (unless using
--skip-vercel) - A git repository with a remote configured
- For
@destinedai/deploy/react:react(18+) andsonner(1+ or 2+) as peer deps
License
MIT
