11import { setTimeout } from 'node:timers/promises'
22import * as fs from 'fs/promises'
33import * as api from '../rest/api'
4+ import prompts from 'prompts'
45import { Flags } from '@oclif/core'
56import { AuthCommand } from './authCommand'
67import { parseProject } from '../services/project-parser'
@@ -14,7 +15,6 @@ import {
1415import chalk from 'chalk'
1516import { splitConfigFilePath , getGitInformation } from '../services/util'
1617import commonMessages from '../messages/common-messages'
17- import { forceFlag } from '../helpers/flags'
1818import { ProjectDeployResponse } from '../rest/projects'
1919import { uploadSnapshots } from '../services/snapshot-service'
2020import { BrowserCheckBundle } from '../constructs/browser-check-bundle'
@@ -45,12 +45,21 @@ 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 ,
5156 allowNo : true ,
5257 } ) ,
53- 'force' : forceFlag ( ) ,
58+ 'force' : Flags . boolean ( {
59+ char : 'f' ,
60+ description : commonMessages . forceMode ,
61+ default : false ,
62+ } ) ,
5463 'config' : Flags . string ( {
5564 char : 'c' ,
5665 description : commonMessages . configFile ,
@@ -74,45 +83,26 @@ export default class Deploy extends AuthCommand {
7483 }
7584
7685 async run ( ) : Promise < void > {
86+ this . style . actionStart ( 'Parsing your project' )
7787 const { flags } = await this . parse ( Deploy )
7888 const {
7989 force,
8090 preview,
8191 'schedule-on-deploy' : scheduleOnDeploy ,
82- output,
92+ output : outputFlag ,
93+ verbose,
8394 config : configFilename ,
8495 'verify-runtime-dependencies' : verifyRuntimeDependencies ,
8596 'debug-bundle' : debugBundle ,
8697 'debug-bundle-output-file' : debugBundleOutputFile ,
8798 } = flags
99+ const output = outputFlag || verbose
88100 const { configDirectory, configFilenames } = splitConfigFilePath ( configFilename )
89101 const {
90102 config : checklyConfig ,
91103 constructs : checklyConfigConstructs ,
92104 } = await loadChecklyConfig ( configDirectory , configFilenames )
93105 const account = this . account
94-
95- if ( ! preview ) {
96- await this . confirmOrAbort ( {
97- command : 'deploy' ,
98- description : 'Deploy project to Checkly' ,
99- changes : [
100- `Deploy project "${ checklyConfig . projectName } " to account "${ account . name } "` ,
101- scheduleOnDeploy
102- ? 'Schedule checks after deploy'
103- : 'Checks will NOT be scheduled after deploy' ,
104- ] ,
105- flags,
106- classification : {
107- readOnly : Deploy . readOnly ,
108- destructive : Deploy . destructive ,
109- idempotent : Deploy . idempotent ,
110- } ,
111- } , { force } )
112- }
113-
114- this . style . actionStart ( 'Parsing your project' )
115-
116106 const availableRuntimes = await api . runtimes . getAll ( )
117107 const project = await parseProject ( {
118108 directory : configDirectory ,
@@ -231,10 +221,21 @@ export default class Deploy extends AuthCommand {
231221 return
232222 }
233223
224+ if ( ! force && ! preview ) {
225+ const { confirm } = await prompts ( {
226+ name : 'confirm' ,
227+ type : 'confirm' ,
228+ message : `You are about to deploy your project "${ project . name } " to account "${ account . name } ". Do you want to continue?` ,
229+ } )
230+ if ( ! confirm ) {
231+ return
232+ }
233+ }
234+
234235 try {
235236 const { data } = await api . projects . deploy ( { ...projectPayload , repoInfo } , { dryRun : preview , scheduleOnDeploy } )
236237 if ( preview || output ) {
237- this . log ( this . formatPreview ( data , project ) )
238+ this . log ( this . formatPreview ( data , project , verbose ) )
238239 }
239240 if ( ! preview ) {
240241 await setTimeout ( 500 )
@@ -256,15 +257,15 @@ export default class Deploy extends AuthCommand {
256257 }
257258 }
258259
259- private formatPreview ( previewData : ProjectDeployResponse , project : Project ) : string {
260+ private formatPreview ( previewData : ProjectDeployResponse , project : Project , verbose = false ) : string {
260261 // Current format of the data is: { checks: { logical-id-1: 'UPDATE' }, groups: { another-logical-id: 'CREATE' } }
261262 // We convert it into update: [{ logicalId, resourceType, construct }, ...], create: [], delete: []
262263 // This makes it easier to display.
263264 const updating = [ ]
264265 const creating = [ ]
265266 const deleting : Array < { resourceType : string , logicalId : string } > = [ ]
266267 for ( const change of previewData ?. diff ?? [ ] ) {
267- const { type, logicalId, action } = change
268+ const { type, logicalId, physicalId , action } = change
268269 if ( [
269270 AlertChannelSubscription . __checklyType ,
270271 PrivateLocationCheckAssignment . __checklyType ,
@@ -276,9 +277,9 @@ export default class Deploy extends AuthCommand {
276277 }
277278 const construct = project . data [ type as keyof ProjectData ] [ logicalId ]
278279 if ( action === ResourceDeployStatus . UPDATE ) {
279- updating . push ( { resourceType : type , logicalId, construct } )
280+ updating . push ( { resourceType : type , logicalId, physicalId , construct } )
280281 } else if ( action === ResourceDeployStatus . CREATE ) {
281- creating . push ( { resourceType : type , logicalId, construct } )
282+ creating . push ( { resourceType : type , logicalId, physicalId , construct } )
282283 } else if ( action === ResourceDeployStatus . DELETE ) {
283284 // Since the resource is being deleted, the construct isn't in the project.
284285 deleting . push ( { resourceType : type , logicalId } )
@@ -331,8 +332,14 @@ export default class Deploy extends AuthCommand {
331332
332333 if ( sortedCreating . filter ( ( { construct } ) => Boolean ( construct ) ) . length ) {
333334 output . push ( chalk . bold . green ( 'Create:' ) )
334- for ( const { logicalId, construct } of sortedCreating ) {
335+ for ( const { logicalId, physicalId , construct } of sortedCreating ) {
335336 output . push ( ` ${ construct . constructor . name } : ${ logicalId } ` )
337+ if ( verbose && ( construct as any ) . name ) {
338+ output . push ( ` name: ${ ( construct as any ) . name } ` )
339+ }
340+ if ( verbose && physicalId ) {
341+ output . push ( ` id: ${ physicalId } ` )
342+ }
336343 }
337344 output . push ( '' )
338345 }
@@ -353,8 +360,14 @@ export default class Deploy extends AuthCommand {
353360 }
354361 if ( sortedUpdating . length ) {
355362 output . push ( chalk . bold . magenta ( 'Update and Unchanged:' ) )
356- for ( const { logicalId, construct } of sortedUpdating ) {
363+ for ( const { logicalId, physicalId , construct } of sortedUpdating ) {
357364 output . push ( ` ${ construct . constructor . name } : ${ logicalId } ` )
365+ if ( verbose && ( construct as any ) . name ) {
366+ output . push ( ` name: ${ ( construct as any ) . name } ` )
367+ }
368+ if ( verbose && physicalId ) {
369+ output . push ( ` id: ${ physicalId } ` )
370+ }
358371 }
359372 output . push ( '' )
360373 }
0 commit comments