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
26 changes: 26 additions & 0 deletions packages/cli/e2e/__tests__/deploy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,32 @@ 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}'
// Each test uses a fresh projectLogicalId (see beforeEach), so the
// first deploy in this test renders as Create, not Update.
expect(stdout).toMatch(new RegExp(
`Create:\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}`,
))
})
})

Expand Down
4 changes: 4 additions & 0 deletions packages/cli/src/ai-context/references/configure.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,7 @@ Run `npx checkly skills manage plan` for the full reference.
## Testing and Debugging

- Test checks using the `npx checkly test` command. Pass environment variables with the `-e` flag, use `--record` to persist results, and use `--verbose` to see all errors.

## Deploying

- Deploy checks using the `npx checkly deploy` command. Use `--output` to see the created, updated, and deleted resources. Use `--verbose` to also include each resource's name and physical ID (UUID), which is useful for programmatically referencing deployed resources (e.g. `npx checkly checks get <id>`).
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
35 changes: 27 additions & 8 deletions packages/cli/src/commands/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand All @@ -256,15 +263,15 @@ 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.
const updating = []
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,
Expand All @@ -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 })
Expand Down Expand Up @@ -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('')
}
Expand All @@ -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('')
}
Expand Down
Loading