Skip to content

Commit 2b93f0f

Browse files
committed
refactor(deploy): report --json problems as an errors map and warnings list
Replace the flat `checks` array with `errors` (a map of blocking problem → fix) and `warnings` (messages), dropping informational pass/skip lines. A consumer acts on the fixes directly instead of filtering checks by status.
1 parent ae2bab7 commit 2b93f0f

3 files changed

Lines changed: 27 additions & 13 deletions

File tree

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,13 @@ const studioPlan = (checks: DeployCheck[], files: DeploymentFile[] = []): Deploy
5151
})
5252

5353
describe('deploymentPlanToJson', () => {
54-
test('projects the plan into a machine-readable shape with a derived verdict and total', () => {
54+
test('maps failing checks to fixes and warnings to messages, dropping pass/skip', () => {
5555
const json = deploymentPlanToJson(
5656
studioPlan(
5757
[
5858
{message: 'Project: p1', status: 'pass'},
59-
{message: 'No studio hostname configured', status: 'fail'},
59+
{message: 'No studio hostname configured', solution: 'Set `studioHost`', status: 'fail'},
60+
{message: 'The autoUpdates config has moved', status: 'warn'},
6061
],
6162
[{path: 'dist/index.html', size: 1_048_576}],
6263
),
@@ -65,16 +66,20 @@ describe('deploymentPlanToJson', () => {
6566
expect(json).toEqual({
6667
applicationType: 'studio',
6768
applicationVersion: '3.99.0',
68-
checks: [
69-
{message: 'Project: p1', status: 'pass'},
70-
{message: 'No studio hostname configured', status: 'fail'},
71-
],
7269
deployable: false,
70+
errors: {'No studio hostname configured': 'Set `studioHost`'},
7371
files: [{path: 'dist/index.html', size: 1_048_576}],
7472
totalBytes: 1_048_576,
73+
warnings: ['The autoUpdates config has moved'],
7574
})
7675
})
7776

77+
test('an error without a solution maps to null', () => {
78+
const json = deploymentPlanToJson(studioPlan([{message: 'boom', status: 'fail'}]))
79+
expect(json.errors).toEqual({boom: null})
80+
expect(json.deployable).toBe(false)
81+
})
82+
7883
test('deployable is true when no check failed', () => {
7984
expect(deploymentPlanToJson(studioPlan([{message: 'ok', status: 'pass'}])).deployable).toBe(
8085
true,

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,24 +66,34 @@ function totalBytes(files: DeploymentFile[]): number {
6666
}
6767

6868
/**
69-
* The machine-readable form of the report `renderDeploymentPlan` prints. Both
70-
* derive from the plan, so the two can't drift.
69+
* A problem-focused, machine-readable projection of the plan: blocking problems
70+
* mapped to their fix, warnings as messages. Derived from the same checks the
71+
* human report renders (its pass/skip lines are informational and omitted here).
7172
*/
7273
export function deploymentPlanToJson(plan: DeploymentPlan): {
7374
applicationType: DeploymentPlan['type']
7475
applicationVersion: string | null
75-
checks: DeployCheck[]
7676
deployable: boolean
77+
errors: Record<string, string | null>
7778
files: DeploymentFile[]
7879
totalBytes: number
80+
warnings: string[]
7981
} {
82+
const errors: Record<string, string | null> = {}
83+
const warnings: string[] = []
84+
for (const check of plan.checks) {
85+
if (check.status === 'fail') errors[check.message] = check.solution ?? null
86+
else if (check.status === 'warn') warnings.push(check.message)
87+
}
88+
8089
return {
8190
applicationType: plan.type,
8291
applicationVersion: plan.version,
83-
checks: plan.checks,
8492
deployable: isDeployable(plan),
93+
errors,
8594
files: plan.files,
8695
totalBytes: totalBytes(plan.files),
96+
warnings,
8797
}
8898
}
8999

packages/@sanity/cli/test/integration/commands/deploy.studio.test.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -316,10 +316,9 @@ describe('#deploy studio', () => {
316316
expect(plan.applicationType).toBe('studio')
317317
expect(typeof plan.applicationVersion).toBe('string')
318318
expect(plan.deployable).toBe(true)
319+
expect(plan.errors).toEqual({})
320+
expect(Array.isArray(plan.warnings)).toBe(true)
319321
expect(plan.files).toContainEqual(expect.objectContaining({path: 'dist/index.html'}))
320-
expect(
321-
plan.checks.some((check: {message: string}) => check.message.includes('existing studio')),
322-
).toBe(true)
323322
})
324323

325324
test('should output the deploy result as JSON with --json', async () => {

0 commit comments

Comments
 (0)