4
4
* Licensed under the BSD 3-Clause license.
5
5
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
6
*/
7
-
8
- import ansis from 'ansis' ;
9
7
import { EnvironmentVariable , Lifecycle , Messages , OrgConfigProperties , SfError } from '@salesforce/core' ;
10
8
import { type DeployVersionData , DeployZipData } from '@salesforce/source-deploy-retrieve' ;
11
9
import { Duration } from '@salesforce/kit' ;
12
10
import { SfCommand , toHelpSection , Flags } from '@salesforce/sf-plugins-core' ;
13
11
import { SourceConflictError } from '@salesforce/source-tracking' ;
12
+ import { DeployStages } from '../../../utils/deployStages.js' ;
14
13
import { AsyncDeployResultFormatter } from '../../../formatters/asyncDeployResultFormatter.js' ;
15
14
import { DeployResultFormatter } from '../../../formatters/deployResultFormatter.js' ;
16
15
import { AsyncDeployResultJson , DeployResultJson , TestLevel } from '../../../utils/types.js' ;
17
- import { DeployProgress } from '../../../utils/progressBar.js' ;
18
16
import { executeDeploy , resolveApi , validateTests , determineExitCode } from '../../../utils/deploy.js' ;
19
17
import { DeployCache } from '../../../utils/deployCache.js' ;
20
18
import { DEPLOY_STATUS_CODES_DESCRIPTIONS } from '../../../utils/errorCodes.js' ;
@@ -177,6 +175,8 @@ export default class DeployMetadata extends SfCommand<DeployResultJson> {
177
175
178
176
public static errorCodes = toHelpSection ( 'ERROR CODES' , DEPLOY_STATUS_CODES_DESCRIPTIONS ) ;
179
177
178
+ protected stages ! : DeployStages ;
179
+
180
180
private zipSize ?: number ;
181
181
private zipFileCount ?: number ;
182
182
@@ -201,33 +201,47 @@ export default class DeployMetadata extends SfCommand<DeployResultJson> {
201
201
202
202
const api = await resolveApi ( this . configAggregator ) ;
203
203
const username = flags [ 'target-org' ] . getUsername ( ) ;
204
- const action = flags [ 'dry-run' ] ? 'Deploying (dry-run)' : 'Deploying' ;
204
+ const title = flags [ 'dry-run' ] ? 'Deploying Metadata (dry-run)' : 'Deploying Metadata ' ;
205
205
206
- // eslint-disable-next-line @typescript-eslint/require-await
207
- Lifecycle . getInstance ( ) . on ( 'apiVersionDeploy' , async ( apiData : DeployVersionData ) => {
208
- this . log (
209
- messages . getMessage ( 'apiVersionMsgDetailed' , [
210
- action ,
211
- // technically manifestVersion can be undefined, but only on raw mdapi deployments.
212
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
213
- flags [ 'metadata-dir' ] ? '<version specified in manifest>' : `v${ apiData . manifestVersion } ` ,
214
- username ,
215
- apiData . apiVersion ,
216
- apiData . webService ,
217
- ] )
218
- ) ;
206
+ this . stages = new DeployStages ( {
207
+ title,
208
+ jsonEnabled : this . jsonEnabled ( ) ,
219
209
} ) ;
220
-
210
+ const lifecycle = Lifecycle . getInstance ( ) ;
221
211
// eslint-disable-next-line @typescript-eslint/require-await
222
- Lifecycle . getInstance ( ) . on ( 'deployZipData' , async ( zipData : DeployZipData ) => {
212
+ lifecycle . on ( 'deployZipData' , async ( zipData : DeployZipData ) => {
223
213
this . zipSize = zipData . zipSize ;
224
- if ( flags . verbose && this . zipSize ) this . log ( `Deploy size: ${ getZipFileSize ( this . zipSize ) } of ~39 MB limit` ) ;
214
+ if ( flags . verbose && this . zipSize ) {
215
+ this . stages . update ( {
216
+ deploySize : `${ getZipFileSize ( this . zipSize ) } of ~39 MB limit` ,
217
+ } ) ;
218
+ }
225
219
if ( zipData . zipFileCount ) {
226
220
this . zipFileCount = zipData . zipFileCount ;
227
- if ( flags . verbose && this . zipSize ) this . log ( `Deployed files count: ${ this . zipFileCount } of 10,000 limit` ) ;
221
+ if ( flags . verbose && this . zipSize ) {
222
+ this . stages . update ( {
223
+ deployFileCount : `${ this . zipFileCount } of 10,000 limit` ,
224
+ } ) ;
225
+ }
228
226
}
229
227
} ) ;
230
228
229
+ lifecycle . on ( 'apiVersionDeploy' , async ( apiData : DeployVersionData ) =>
230
+ Promise . resolve (
231
+ this . stages . update ( {
232
+ message : messages . getMessage ( 'apiVersionMsgDetailed' , [
233
+ flags [ 'dry-run' ] ? 'Deploying (dry-run)' : 'Deploying' ,
234
+ // technically manifestVersion can be undefined, but only on raw mdapi deployments.
235
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
236
+ flags [ 'metadata-dir' ] ? '<version specified in manifest>' : `v${ apiData . manifestVersion } ` ,
237
+ username ,
238
+ apiData . apiVersion ,
239
+ apiData . webService ,
240
+ ] ) ,
241
+ } )
242
+ )
243
+ ) ;
244
+
231
245
const { deploy } = await executeDeploy (
232
246
{
233
247
...flags ,
@@ -238,16 +252,20 @@ export default class DeployMetadata extends SfCommand<DeployResultJson> {
238
252
) ;
239
253
240
254
if ( ! deploy ) {
255
+ this . stages . stop ( ) ;
241
256
this . log ( 'No changes to deploy' ) ;
242
257
return { status : 'Nothing to deploy' , files : [ ] } ;
243
258
}
244
259
245
260
if ( ! deploy . id ) {
246
261
throw new SfError ( 'The deploy id is not available.' ) ;
247
262
}
248
- this . log ( `Deploy ID: ${ ansis . bold ( deploy . id ) } ` ) ;
263
+
264
+ this . stages . start ( { username, deploy } ) ;
249
265
250
266
if ( flags . async ) {
267
+ this . stages . done ( { status : 'Queued' , username } ) ;
268
+ this . stages . stop ( ) ;
251
269
if ( flags [ 'coverage-formatters' ] ) {
252
270
this . warn ( messages . getMessage ( 'asyncCoverageJunitWarning' ) ) ;
253
271
}
@@ -257,8 +275,6 @@ export default class DeployMetadata extends SfCommand<DeployResultJson> {
257
275
return this . mixinZipMeta ( await asyncFormatter . getJson ( ) ) ;
258
276
}
259
277
260
- new DeployProgress ( deploy , this . jsonEnabled ( ) ) . start ( ) ;
261
-
262
278
const result = await deploy . pollStatus ( { timeout : flags . wait } ) ;
263
279
process . exitCode = determineExitCode ( result ) ;
264
280
const formatter = new DeployResultFormatter ( result , flags ) ;
@@ -276,6 +292,8 @@ export default class DeployMetadata extends SfCommand<DeployResultJson> {
276
292
protected catch ( error : Error | SfError ) : Promise < never > {
277
293
if ( error instanceof SourceConflictError && error . data ) {
278
294
if ( ! this . jsonEnabled ( ) ) {
295
+ this . stages . update ( { status : 'Failed' } ) ;
296
+ this . stages . stop ( error ) ;
279
297
writeConflictTable ( error . data ) ;
280
298
// set the message and add plugin-specific actions
281
299
return super . catch ( {
0 commit comments