diff --git a/packages/cli/e2e/__tests__/deploy.spec.ts b/packages/cli/e2e/__tests__/deploy.spec.ts index 4c2bee1cd..11a4eb9ab 100644 --- a/packages/cli/e2e/__tests__/deploy.spec.ts +++ b/packages/cli/e2e/__tests__/deploy.spec.ts @@ -321,6 +321,30 @@ Skip (testOnly): Update and Unchanged: ApiCheck: not-testonly-default-check ApiCheck: not-testonly-false-check`) + // --output without --verbose should not show name or id + expect(stdout).not.toContain('name:') + expect(stdout).not.toContain('id:') + }) + + it('Should show resource name and id with --verbose', async () => { + const { stdout } = await runDeploy(fixt, ['--force', '--verbose'], { + env: { + PROJECT_LOGICAL_ID: projectLogicalId, + PRIVATE_LOCATION_SLUG_NAME: privateLocationSlugname, + TEST_ONLY: 'true', + CHECKLY_CLI_VERSION: '4.8.0', + }, + }) + const uuid = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}' + expect(stdout).toMatch(new RegExp( + `Update and Unchanged:\n` + + ` ApiCheck: not-testonly-default-check\n` + + ` name: TestOnly=false \\(default\\) Check\n` + + ` id: ${uuid}\n` + + ` ApiCheck: not-testonly-false-check\n` + + ` name: TestOnly=false Check\n` + + ` id: ${uuid}`, + )) }) }) diff --git a/packages/cli/src/ai-context/references/communicate.md b/packages/cli/src/ai-context/references/communicate.md index 745cd505b..46ec5b776 100644 --- a/packages/cli/src/ai-context/references/communicate.md +++ b/packages/cli/src/ai-context/references/communicate.md @@ -24,6 +24,7 @@ Write commands (`incidents create`, `incidents update`, `incidents resolve`, `de 3. This applies to **every** write command, not just the first one. Incident updates and resolutions also require confirmation. 4. Use `--dry-run` to preview what a command will do without executing or prompting. 5. Read-only commands (`incidents list`, `status-pages list`) execute immediately without confirmation. +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 ` to inspect a deployed check). ## Available Commands diff --git a/packages/cli/src/ai-context/skill.md b/packages/cli/src/ai-context/skill.md index 0ea8205f1..129bfa9dd 100644 --- a/packages/cli/src/ai-context/skill.md +++ b/packages/cli/src/ai-context/skill.md @@ -34,6 +34,8 @@ Run `npx checkly skills manage` for the full reference. 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. +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 ` to inspect a deployed check). + Run `npx checkly skills communicate` for the full protocol details. diff --git a/packages/cli/src/commands/__tests__/confirm-flow-deploy.spec.ts b/packages/cli/src/commands/__tests__/confirm-flow-deploy.spec.ts index 15115db0d..a8d9b3e0b 100644 --- a/packages/cli/src/commands/__tests__/confirm-flow-deploy.spec.ts +++ b/packages/cli/src/commands/__tests__/confirm-flow-deploy.spec.ts @@ -149,6 +149,7 @@ describe('deploy confirmation flow', () => { 'force': false, 'preview': false, 'output': false, + 'verbose': false, 'config': undefined, 'schedule-on-deploy': true, 'verify-runtime-dependencies': true, diff --git a/packages/cli/src/commands/deploy.ts b/packages/cli/src/commands/deploy.ts index d44cea99e..aca18dd27 100644 --- a/packages/cli/src/commands/deploy.ts +++ b/packages/cli/src/commands/deploy.ts @@ -45,6 +45,11 @@ export default class Deploy extends AuthCommand { description: 'Shows the changes made after the deploy command.', default: false, }), + 'verbose': Flags.boolean({ + char: 'v', + description: 'Show resource names and IDs in the deploy output.', + default: false, + }), 'schedule-on-deploy': Flags.boolean({ description: 'Enables automatic check scheduling after a deploy.', default: true, @@ -79,12 +84,14 @@ export default class Deploy extends AuthCommand { force, preview, 'schedule-on-deploy': scheduleOnDeploy, - output, + output: outputFlag, + verbose, config: configFilename, 'verify-runtime-dependencies': verifyRuntimeDependencies, 'debug-bundle': debugBundle, 'debug-bundle-output-file': debugBundleOutputFile, } = flags + const output = outputFlag || verbose const { configDirectory, configFilenames } = splitConfigFilePath(configFilename) const { config: checklyConfig, @@ -234,7 +241,7 @@ export default class Deploy extends AuthCommand { try { const { data } = await api.projects.deploy({ ...projectPayload, repoInfo }, { dryRun: preview, scheduleOnDeploy }) if (preview || output) { - this.log(this.formatPreview(data, project)) + this.log(this.formatPreview(data, project, verbose)) } if (!preview) { await setTimeout(500) @@ -256,7 +263,7 @@ export default class Deploy extends AuthCommand { } } - private formatPreview (previewData: ProjectDeployResponse, project: Project): string { + private formatPreview (previewData: ProjectDeployResponse, project: Project, verbose = false): string { // Current format of the data is: { checks: { logical-id-1: 'UPDATE' }, groups: { another-logical-id: 'CREATE' } } // We convert it into update: [{ logicalId, resourceType, construct }, ...], create: [], delete: [] // This makes it easier to display. @@ -264,7 +271,7 @@ export default class Deploy extends AuthCommand { const creating = [] const deleting: Array<{ resourceType: string, logicalId: string }> = [] for (const change of previewData?.diff ?? []) { - const { type, logicalId, action } = change + const { type, logicalId, physicalId, action } = change if ([ AlertChannelSubscription.__checklyType, PrivateLocationCheckAssignment.__checklyType, @@ -276,9 +283,9 @@ export default class Deploy extends AuthCommand { } const construct = project.data[type as keyof ProjectData][logicalId] if (action === ResourceDeployStatus.UPDATE) { - updating.push({ resourceType: type, logicalId, construct }) + updating.push({ resourceType: type, logicalId, physicalId, construct }) } else if (action === ResourceDeployStatus.CREATE) { - creating.push({ resourceType: type, logicalId, construct }) + creating.push({ resourceType: type, logicalId, physicalId, construct }) } else if (action === ResourceDeployStatus.DELETE) { // Since the resource is being deleted, the construct isn't in the project. deleting.push({ resourceType: type, logicalId }) @@ -331,8 +338,14 @@ export default class Deploy extends AuthCommand { if (sortedCreating.filter(({ construct }) => Boolean(construct)).length) { output.push(chalk.bold.green('Create:')) - for (const { logicalId, construct } of sortedCreating) { + for (const { logicalId, physicalId, construct } of sortedCreating) { output.push(` ${construct.constructor.name}: ${logicalId}`) + if (verbose && (construct as any).name) { + output.push(` name: ${(construct as any).name}`) + } + if (verbose && physicalId) { + output.push(` id: ${physicalId}`) + } } output.push('') } @@ -353,8 +366,14 @@ export default class Deploy extends AuthCommand { } if (sortedUpdating.length) { output.push(chalk.bold.magenta('Update and Unchanged:')) - for (const { logicalId, construct } of sortedUpdating) { + for (const { logicalId, physicalId, construct } of sortedUpdating) { output.push(` ${construct.constructor.name}: ${logicalId}`) + if (verbose && (construct as any).name) { + output.push(` name: ${(construct as any).name}`) + } + if (verbose && physicalId) { + output.push(` id: ${physicalId}`) + } } output.push('') } diff --git a/skills/checkly/SKILL.md b/skills/checkly/SKILL.md index 2cd7494d2..6978cdb9a 100644 --- a/skills/checkly/SKILL.md +++ b/skills/checkly/SKILL.md @@ -34,6 +34,8 @@ Run `npx checkly skills manage` for the full reference. 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. +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 ` to inspect a deployed check). + Run `npx checkly skills communicate` for the full protocol details. ### `npx checkly skills initialize`