Skip to content

Commit 0222427

Browse files
committed
feat(deploy): list problems with fixes and surface warnings in the dry-run report
When a dry run can't deploy, the report now groups the failing checks under "Problems to fix" — each with its solution — and lists warnings in their own section, instead of a flat mixed list.
1 parent 07bb0e3 commit 0222427

2 files changed

Lines changed: 50 additions & 7 deletions

File tree

packages/@sanity/cli/src/actions/deploy/__tests__/deploymentPlan.test.ts

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,38 @@ describe('renderDeploymentPlan', () => {
7373
expect(text).toContain('dist/index.html (1.50 MB)')
7474
})
7575

76-
test('reports non-deployable when a check failed', () => {
77-
renderDeploymentPlan(studioPlan([{message: 'Missing project id', status: 'fail'}]), output)
76+
test('lists problems with their solutions when a check failed', () => {
77+
renderDeploymentPlan(
78+
studioPlan([
79+
{message: 'No project ID configured', solution: 'Add `api.projectId`', status: 'fail'},
80+
]),
81+
output,
82+
)
7883

7984
const text = lines.join('\n')
80-
expect(text).toContain('cannot be deployed')
85+
expect(text).toContain("This studio can't be deployed.")
86+
expect(text).toContain('Problems to fix:')
87+
expect(text).toContain('No project ID configured')
88+
expect(text).toContain('→ Add `api.projectId`')
8189
expect(text).toContain('Files to deploy (0.00 MB):')
8290
})
8391

92+
test('surfaces warnings in their own section', () => {
93+
renderDeploymentPlan(
94+
studioPlan([
95+
{message: 'Project: p1', status: 'pass'},
96+
{message: 'The `autoUpdates` config has moved', solution: 'Move it', status: 'warn'},
97+
]),
98+
output,
99+
)
100+
101+
const text = lines.join('\n')
102+
expect(text).toContain('This studio can be deployed.')
103+
expect(text).toContain('Warnings:')
104+
expect(text).toContain('The `autoUpdates` config has moved')
105+
expect(text).toContain('→ Move it')
106+
})
107+
84108
test('labels a core app deploy as an application', () => {
85109
renderDeploymentPlan({checks: [], files: [], type: 'coreApp'}, output)
86110

packages/@sanity/cli/src/actions/deploy/deploymentPlan.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,27 +67,46 @@ export async function listDeploymentFiles(
6767
/** Renders a deployment plan as a minimal, human-readable report. */
6868
export function renderDeploymentPlan(plan: DeploymentPlan, output: Output): void {
6969
const label = plan.type === 'coreApp' ? 'application' : 'studio'
70-
const deployable = plan.checks.every((check) => check.status !== 'fail')
70+
const problems = plan.checks.filter((check) => check.status === 'fail')
71+
const warnings = plan.checks.filter((check) => check.status === 'warn')
7172
const totalBytes = plan.files.reduce((sum, file) => sum + file.size, 0)
7273

7374
output.log('\nDry run — no changes made.\n')
7475

76+
// Checks that passed or were skipped; problems and warnings get their own
77+
// sections below so each fix sits next to the thing it fixes.
7578
for (const check of plan.checks) {
76-
output.log(` ${statusIcon(check.status)} ${check.message}`)
79+
if (check.status === 'pass' || check.status === 'skip') {
80+
output.log(` ${statusIcon(check.status)} ${check.message}`)
81+
}
7782
}
7883

7984
output.log(
80-
deployable
85+
problems.length === 0
8186
? styleText('green', `\nThis ${label} can be deployed.`)
82-
: styleText('red', `\nThis ${label} cannot be deployed — resolve the issues above.`),
87+
: styleText('red', `\nThis ${label} can't be deployed.`),
8388
)
8489

90+
renderIssues(output, 'Problems to fix:', problems)
91+
renderIssues(output, 'Warnings:', warnings)
92+
8593
output.log(`\nFiles to deploy (${formatMB(totalBytes)}):`)
8694
for (const file of plan.files) {
8795
output.log(` ${file.path} (${formatMB(file.size)})`)
8896
}
8997
}
9098

99+
/** Renders a titled list of checks, each with its fix indented beneath. */
100+
function renderIssues(output: Output, title: string, checks: DeployCheck[]): void {
101+
if (checks.length === 0) return
102+
103+
output.log(`\n${title}`)
104+
for (const check of checks) {
105+
output.log(` ${statusIcon(check.status)} ${check.message}`)
106+
if (check.solution) output.log(` → ${check.solution}`)
107+
}
108+
}
109+
91110
/** Bytes as megabytes with two decimals, e.g. `1.50 MB`. */
92111
function formatMB(bytes: number): string {
93112
return `${(bytes / 1024 / 1024).toFixed(2)} MB`

0 commit comments

Comments
 (0)