teqo/scripts/vercel-deploy-cooldown.mjs
Cursor Agent cbddd8c796
OPS11 — cooldown de 30 min entre deploys de produção (Vercel)
- Script vercel-deploy-cooldown consulta último deploy READY via API Vercel
- Job deploy em ci.yml adia upload quando idade < 30 min (sucesso, não falha)
- Job requeue espera o residual e re-dispara ci.yml
- vercel deploy passa --archive=tgz para reduzir pressão de upload
- Testes unitários para computeCooldownWait e fetch da API

Co-authored-by: Francisco Solla <fsolla@users.noreply.github.com>
2026-08-01 10:54:55 +00:00

71 lines
2.1 KiB
JavaScript

#!/usr/bin/env node
/**
* vercel-deploy-cooldown — CI helper for OPS11. Queries the last READY
* production deployment on Vercel and writes GitHub Actions outputs:
* active=true|false
* wait_seconds=<residual>
* last_production_deploy_at=<ms epoch or empty>
*/
import { appendFileSync } from 'node:fs'
import { dieWithLabel } from './lib/cli.mjs'
import {
DEPLOY_COOLDOWN_MS,
evaluateDeployCooldown,
} from './lib/vercel-deploy-cooldown.mjs'
const die = dieWithLabel('vercel-deploy-cooldown')
const writeGithubOutput = (pairs) => {
const outputPath = process.env.GITHUB_OUTPUT
const lines = Object.entries(pairs)
.map(([key, value]) => `${key}=${value}`)
.join('\n')
.concat('\n')
if (outputPath) {
appendFileSync(outputPath, lines)
return
}
process.stdout.write(lines)
}
const main = async () => {
const token = process.env.VERCEL_TOKEN
const projectId = process.env.VERCEL_PROJECT_ID
const teamId = process.env.VERCEL_ORG_ID
if (!token) die('VERCEL_TOKEN is required')
if (!projectId) die('VERCEL_PROJECT_ID is required')
if (!teamId) die('VERCEL_ORG_ID is required')
const result = await evaluateDeployCooldown({ token, projectId, teamId })
if (result.lastProductionDeployAt == null) {
console.log(
`[vercel-deploy-cooldown] no READY production deployment found — proceed (${DEPLOY_COOLDOWN_MS / 60_000} min cooldown N/A)`,
)
} else if (result.active) {
const ageMinutes = Math.floor((result.ageMs ?? 0) / 60_000)
console.log(
`[vercel-deploy-cooldown] defer deploy — last production deploy ${ageMinutes} min ago; wait ${result.waitSeconds}s`,
)
} else {
const ageMinutes = Math.floor((result.ageMs ?? 0) / 60_000)
console.log(
`[vercel-deploy-cooldown] cooldown clear — last production deploy ${ageMinutes} min ago`,
)
}
writeGithubOutput({
active: result.active ? 'true' : 'false',
wait_seconds: String(result.waitSeconds),
last_production_deploy_at:
result.lastProductionDeployAt == null ? '' : String(result.lastProductionDeployAt),
})
}
main().catch((error) => {
die(error instanceof Error ? error.message : String(error))
})