Skip to content

Commit df7a62b

Browse files
committed
feat(deploy): add --verbose flag for resource name and id output
Add a -v/--verbose flag to `deploy` that shows the resource name and physical ID (UUID) for each created or updated resource. The --verbose flag implies --output, so both flags don't need to be passed together. Without --verbose, deploy output is unchanged.
1 parent 471229a commit df7a62b

File tree

6 files changed

+57
-8
lines changed

6 files changed

+57
-8
lines changed

packages/cli/e2e/__tests__/deploy.spec.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,30 @@ Skip (testOnly):
321321
Update and Unchanged:
322322
ApiCheck: not-testonly-default-check
323323
ApiCheck: not-testonly-false-check`)
324+
// --output without --verbose should not show name or id
325+
expect(stdout).not.toContain('name:')
326+
expect(stdout).not.toContain('id:')
327+
})
328+
329+
it('Should show resource name and id with --verbose', async () => {
330+
const { stdout } = await runDeploy(fixt, ['--force', '--verbose'], {
331+
env: {
332+
PROJECT_LOGICAL_ID: projectLogicalId,
333+
PRIVATE_LOCATION_SLUG_NAME: privateLocationSlugname,
334+
TEST_ONLY: 'true',
335+
CHECKLY_CLI_VERSION: '4.8.0',
336+
},
337+
})
338+
const uuid = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'
339+
expect(stdout).toMatch(new RegExp(
340+
`Update and Unchanged:\n`
341+
+ ` ApiCheck: not-testonly-default-check\n`
342+
+ ` name: TestOnly=false \\(default\\) Check\n`
343+
+ ` id: ${uuid}\n`
344+
+ ` ApiCheck: not-testonly-false-check\n`
345+
+ ` name: TestOnly=false Check\n`
346+
+ ` id: ${uuid}`,
347+
))
324348
})
325349
})
326350

packages/cli/src/ai-context/references/communicate.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Write commands (`incidents create`, `incidents update`, `incidents resolve`, `de
2424
3. This applies to **every** write command, not just the first one. Incident updates and resolutions also require confirmation.
2525
4. Use `--dry-run` to preview what a command will do without executing or prompting.
2626
5. Read-only commands (`incidents list`, `status-pages list`) execute immediately without confirmation.
27+
6. When deploying, use `--verbose` to include resource names and physical IDs (UUIDs) in the output. This is useful for programmatically referencing deployed resources (e.g. running `npx checkly checks get <id>` to inspect a deployed check).
2728

2829
## Available Commands
2930

packages/cli/src/ai-context/skill.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ Run `npx checkly skills manage` for the full reference.
3434

3535
Write commands (e.g. `incidents create`, `deploy`, `destroy`) return exit code 2 with a `confirmation_required` JSON envelope instead of executing. **Always present the `changes` to the user and wait for approval before running the `confirmCommand`.** Never auto-append `--force`. This applies to every write command individually — updates and resolutions need confirmation too, not just the initial create.
3636

37+
When deploying, use `--verbose` to include resource names and physical IDs (UUIDs) in the output. This is useful for programmatically referencing deployed resources (e.g. running `npx checkly checks get <id>` to inspect a deployed check).
38+
3739
Run `npx checkly skills communicate` for the full protocol details.
3840

3941
<!-- SKILL_COMMANDS -->

packages/cli/src/commands/__tests__/confirm-flow-deploy.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ describe('deploy confirmation flow', () => {
149149
'force': false,
150150
'preview': false,
151151
'output': false,
152+
'verbose': false,
152153
'config': undefined,
153154
'schedule-on-deploy': true,
154155
'verify-runtime-dependencies': true,

packages/cli/src/commands/deploy.ts

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ export default class Deploy extends AuthCommand {
4545
description: 'Shows the changes made after the deploy command.',
4646
default: false,
4747
}),
48+
'verbose': Flags.boolean({
49+
char: 'v',
50+
description: 'Show resource names and IDs in the deploy output.',
51+
default: false,
52+
}),
4853
'schedule-on-deploy': Flags.boolean({
4954
description: 'Enables automatic check scheduling after a deploy.',
5055
default: true,
@@ -79,12 +84,14 @@ export default class Deploy extends AuthCommand {
7984
force,
8085
preview,
8186
'schedule-on-deploy': scheduleOnDeploy,
82-
output,
87+
output: outputFlag,
88+
verbose,
8389
config: configFilename,
8490
'verify-runtime-dependencies': verifyRuntimeDependencies,
8591
'debug-bundle': debugBundle,
8692
'debug-bundle-output-file': debugBundleOutputFile,
8793
} = flags
94+
const output = outputFlag || verbose
8895
const { configDirectory, configFilenames } = splitConfigFilePath(configFilename)
8996
const {
9097
config: checklyConfig,
@@ -234,7 +241,7 @@ export default class Deploy extends AuthCommand {
234241
try {
235242
const { data } = await api.projects.deploy({ ...projectPayload, repoInfo }, { dryRun: preview, scheduleOnDeploy })
236243
if (preview || output) {
237-
this.log(this.formatPreview(data, project))
244+
this.log(this.formatPreview(data, project, verbose))
238245
}
239246
if (!preview) {
240247
await setTimeout(500)
@@ -256,15 +263,15 @@ export default class Deploy extends AuthCommand {
256263
}
257264
}
258265

259-
private formatPreview (previewData: ProjectDeployResponse, project: Project): string {
266+
private formatPreview (previewData: ProjectDeployResponse, project: Project, verbose = false): string {
260267
// Current format of the data is: { checks: { logical-id-1: 'UPDATE' }, groups: { another-logical-id: 'CREATE' } }
261268
// We convert it into update: [{ logicalId, resourceType, construct }, ...], create: [], delete: []
262269
// This makes it easier to display.
263270
const updating = []
264271
const creating = []
265272
const deleting: Array<{ resourceType: string, logicalId: string }> = []
266273
for (const change of previewData?.diff ?? []) {
267-
const { type, logicalId, action } = change
274+
const { type, logicalId, physicalId, action } = change
268275
if ([
269276
AlertChannelSubscription.__checklyType,
270277
PrivateLocationCheckAssignment.__checklyType,
@@ -276,9 +283,9 @@ export default class Deploy extends AuthCommand {
276283
}
277284
const construct = project.data[type as keyof ProjectData][logicalId]
278285
if (action === ResourceDeployStatus.UPDATE) {
279-
updating.push({ resourceType: type, logicalId, construct })
286+
updating.push({ resourceType: type, logicalId, physicalId, construct })
280287
} else if (action === ResourceDeployStatus.CREATE) {
281-
creating.push({ resourceType: type, logicalId, construct })
288+
creating.push({ resourceType: type, logicalId, physicalId, construct })
282289
} else if (action === ResourceDeployStatus.DELETE) {
283290
// Since the resource is being deleted, the construct isn't in the project.
284291
deleting.push({ resourceType: type, logicalId })
@@ -331,8 +338,14 @@ export default class Deploy extends AuthCommand {
331338

332339
if (sortedCreating.filter(({ construct }) => Boolean(construct)).length) {
333340
output.push(chalk.bold.green('Create:'))
334-
for (const { logicalId, construct } of sortedCreating) {
341+
for (const { logicalId, physicalId, construct } of sortedCreating) {
335342
output.push(` ${construct.constructor.name}: ${logicalId}`)
343+
if (verbose && (construct as any).name) {
344+
output.push(` name: ${(construct as any).name}`)
345+
}
346+
if (verbose && physicalId) {
347+
output.push(` id: ${physicalId}`)
348+
}
336349
}
337350
output.push('')
338351
}
@@ -353,8 +366,14 @@ export default class Deploy extends AuthCommand {
353366
}
354367
if (sortedUpdating.length) {
355368
output.push(chalk.bold.magenta('Update and Unchanged:'))
356-
for (const { logicalId, construct } of sortedUpdating) {
369+
for (const { logicalId, physicalId, construct } of sortedUpdating) {
357370
output.push(` ${construct.constructor.name}: ${logicalId}`)
371+
if (verbose && (construct as any).name) {
372+
output.push(` name: ${(construct as any).name}`)
373+
}
374+
if (verbose && physicalId) {
375+
output.push(` id: ${physicalId}`)
376+
}
358377
}
359378
output.push('')
360379
}

skills/checkly/SKILL.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ Run `npx checkly skills manage` for the full reference.
3434

3535
Write commands (e.g. `incidents create`, `deploy`, `destroy`) return exit code 2 with a `confirmation_required` JSON envelope instead of executing. **Always present the `changes` to the user and wait for approval before running the `confirmCommand`.** Never auto-append `--force`. This applies to every write command individually — updates and resolutions need confirmation too, not just the initial create.
3636

37+
When deploying, use `--verbose` to include resource names and physical IDs (UUIDs) in the output. This is useful for programmatically referencing deployed resources (e.g. running `npx checkly checks get <id>` to inspect a deployed check).
38+
3739
Run `npx checkly skills communicate` for the full protocol details.
3840

3941
### `npx checkly skills initialize`

0 commit comments

Comments
 (0)