Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/commands/cron.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,11 +229,11 @@ export function jobShowLines(j: CronJob, serviceName?: string): string[] {
// decrypts it. Saying so beats an empty "value" column that reads as "this header is set to
// nothing". Secret-backed headers get a row each, because the secret NAME is readable and is the
// thing an operator needs when a rotation or a missing secret is the question.
const refs = Object.entries(refsOf(j.request))
const literal = j.request.headerNames.filter((n) => findHeader(refsOf(j.request), n) === undefined)
const refs = refsOf(j.request)
const literal = j.request.headerNames.filter((n) => findHeader(refs, n) === undefined)
const rows = [
...(literal.length ? [`${literal.join(', ')} (names only — values are encrypted at rest and never returned)`] : []),
...refs.map(([h, s]) => `${h} ← secret ${s} (resolved at send time)`),
...Object.entries(refs).map(([h, s]) => `${h} ← secret ${s} (resolved at send time)`),
]
if (!rows.length) lines.push(' headers (none)')
rows.forEach((r, i) => lines.push(` ${i ? ' ' : 'headers '} ${r}`))
Expand Down
21 changes: 12 additions & 9 deletions src/commands/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,11 @@ export type TemplateDeployDeps = {
fetchGitHub?: (t: GitHubTarget) => Promise<FetchedTemplate>
}

// The poll route is keyed by deployment id, not project: name the project so agent mode signs
// with the project-bound session (a bootstrap session is rejected as "for a different project").
const readDeployment = (api: TemplateApi, projectId: string) => (id: string) =>
api.request('GET', `/template-deployments/${id}`, undefined, { projectId })

export async function templateDeploy(target: string, opts: TemplateDeployOpts = {}, deps: TemplateDeployDeps = {}): Promise<void> {
const given = parseSetFlags(opts.set ?? []) // a typo'd --set fails before any network access
// --json asked for parseable output: every human progress line is suppressed so stdout carries
Expand Down Expand Up @@ -463,9 +468,7 @@ export async function templateDeploy(target: string, opts: TemplateDeployOpts =
info(`deploying template ${codeLabel} to branch ${branchName}${acceptedRegion ? ` in ${acceptedRegion}` : ''} (${deploymentId})`)
for (const line of publicBucketLines(services)) info(line)
}
// The poll route is keyed by deployment id, not project: name the project so agent mode signs
// with the project-bound session (a bootstrap session is rejected as "for a different project").
const dep = await watchDeployment((id) => api.request('GET', `/template-deployments/${id}`, undefined, { projectId: p.projectId }), deploymentId, quiet ? () => {} : info, deps.wait)
const dep = await watchDeployment(readDeployment(api, p.projectId), deploymentId, quiet ? () => {} : info, deps.wait)
if (opts.json) return printJson(source ? { source, ...dep } : dep)
info(`template ${codeLabel} deployed to branch ${branchName}`)
for (const u of deploymentUrls(dep)) info(` ${u}`)
Expand Down Expand Up @@ -570,10 +573,10 @@ export async function templateUpgrade(service: string, opts: TemplateUpgradeOpts
const ask = deps.ask ?? promptVariable

const target = await deploymentOfService(api, p.projectId, branchName, service, 'upgrade')
// The poll and preview routes are keyed by deployment id, not project: name the project so agent
// mode signs with the project-bound session, exactly as templateDeploy does.
// The preview is a GET and raises coded 409s of its own (template_superseded among them), so it
// gets the same reading as the POST rather than the raw "<sentence> (HTTP 409)" the guard prints.
// The preview route is keyed by deployment id, not project, so it names the project as
// readDeployment does. It is a GET and raises coded 409s of its own (template_superseded among
// them), so it gets the same reading as the POST rather than the raw "<sentence> (HTTP 409)" the
// guard prints.
let plan
try {
;({ plan } = await api.request('GET', `/template-deployments/${target.deploymentId}/upgrade`, undefined, { projectId: p.projectId }))
Expand Down Expand Up @@ -613,7 +616,7 @@ export async function templateUpgrade(service: string, opts: TemplateUpgradeOpts

const deploymentId = res.body.deploymentId ?? (res.body.deployment ?? res.body).id
if (!quiet) info(`upgrading ${service} to ${plan.to_version} (${deploymentId})`)
const dep = await watchDeployment((id) => api.request('GET', `/template-deployments/${id}`, undefined, { projectId: p.projectId }), deploymentId, quiet ? () => {} : info, deps.wait)
const dep = await watchDeployment(readDeployment(api, p.projectId), deploymentId, quiet ? () => {} : info, deps.wait)
if (quiet) return printJson(dep)
info(`${service} is on ${plan.to_version}`)
info(`next: \`insta template rollback ${service}\` returns it to ${plan.from_version}`)
Expand Down Expand Up @@ -668,7 +671,7 @@ export async function templateRollback(service: string, opts: TemplateRollbackOp
if (handleApproval(res, opts.json)) return
const deploymentId = res.body.deploymentId ?? (res.body.deployment ?? res.body).id
out(`rolling ${service} back (${deploymentId})`)
const dep = await watchDeployment((id) => api.request('GET', `/template-deployments/${id}`, undefined, { projectId: p.projectId }), deploymentId, out, deps.wait)
const dep = await watchDeployment(readDeployment(api, p.projectId), deploymentId, out, deps.wait)
if (quiet) return printJson(dep)
info(`${service} is back on ${(dep.deployment ?? dep).template_version ?? 'its previous version'}`)
renderNextActions(dep.nextActions)
Expand Down
Loading