@@ -4,9 +4,9 @@ import { DeployService } from '../../services/deploy.service.js';
44import { LoggingExecutor } from '../../infrastructure/ssh/logging-executor.js' ;
55import { runRemoteCommand } from '../runner.js' ;
66import { ui } from '../ui.js' ;
7- import type { ShipnodeConfig } from '../../shared/types.js' ;
7+ import type { ShipnodeConfig , ShipnodeApp } from '../../shared/types.js' ;
88import { getActiveApp } from '../../domain/workspace.js' ;
9- import { getDeploymentName , getWebApp } from '../../domain/pm2/apps.js' ;
9+ import { getPm2Name } from '../../domain/pm2/apps.js' ;
1010
1111export async function cmdDeploy ( cwd : string , options : { dryRun ?: boolean ; skipBuild ?: boolean ; app ?: string ; config ?: string } ) : Promise < void > {
1212 const config = await loadConfig ( cwd , options . config ) ;
@@ -45,25 +45,31 @@ export async function cmdDeploy(cwd: string, options: { dryRun?: boolean; skipBu
4545 ) ;
4646}
4747
48- function printDryRun ( config : ShipnodeConfig , skipBuild : boolean ) : void {
49- ui . banner ( ) ;
50-
51- const app = getActiveApp ( config ) ;
48+ function renderAppPlan ( app : ShipnodeApp , skipBuild : boolean ) : string {
49+ const namespace = app . pm2 ?. apps [ 0 ] ?. name ;
50+ const web = app . pm2 ?. apps . find ( ( a ) => a . port !== undefined ) ;
5251
5352 const serverRows : [ string , string ] [ ] = [
5453 [ 'App type' , app . appType ] ,
55- [ 'Host' , `${ config . ssh . user } @${ config . ssh . host } :${ config . ssh . port } ` ] ,
56- [ 'Remote path' , config . remotePath ] ,
54+ [ 'App root' , app . appRoot ?? '(repo root)' ] ,
5755 [ 'Keep releases' , String ( app . keepReleases ) ] ,
5856 ] ;
5957
6058 if ( app . appType === 'backend' ) {
61- const apps = app . pm2 ?. apps ?? [ ] ;
62- if ( apps . length ) {
63- serverRows . push ( [ 'PM2 deployment' , getDeploymentName ( config ) ?? '' ] ) ;
64- serverRows . push ( [ 'PM2 apps' , apps . map ( ( a ) => a . port !== undefined ? `${ a . name } (web:${ a . port } )` : a . name ) . join ( ', ' ) ] ) ;
59+ const pm2Apps = app . pm2 ?. apps ?? [ ] ;
60+ if ( pm2Apps . length && namespace ) {
61+ serverRows . push ( [ 'PM2 deployment' , namespace ] ) ;
62+ serverRows . push ( [
63+ 'PM2 apps' ,
64+ pm2Apps
65+ . map ( ( a ) =>
66+ a . port !== undefined
67+ ? `${ getPm2Name ( namespace , a . name ) } (web:${ a . port } )`
68+ : getPm2Name ( namespace , a . name ) ,
69+ )
70+ . join ( ', ' ) ,
71+ ] ) ;
6572 }
66- const web = getWebApp ( config ) ;
6773 if ( web ) serverRows . push ( [ 'Port' , String ( web . port ) ] ) ;
6874 }
6975
@@ -96,17 +102,30 @@ function printDryRun(config: ShipnodeConfig, skipBuild: boolean): void {
96102
97103 const flowRows : [ string , string ] [ ] = steps . map ( ( s , i ) => [ `${ i + 1 } .` , s as string ] ) ;
98104
99- ui . note (
100- [
101- chalk . bold ( 'Server' ) ,
102- ...serverRows . map ( ( [ k , v ] ) => ` ${ chalk . dim ( k . padEnd ( 12 ) ) } ${ v } ` ) ,
103- '' ,
104- chalk . bold ( 'Build' ) ,
105- ...buildRows . map ( ( [ k , v ] ) => ` ${ chalk . dim ( k . padEnd ( 12 ) ) } ${ v } ` ) ,
106- '' ,
107- chalk . bold ( 'Deploy flow' ) ,
108- ...flowRows . map ( ( [ k , v ] ) => ` ${ chalk . dim ( k . padEnd ( 4 ) ) } ${ v } ` ) ,
109- ] . join ( '\n' ) ,
110- 'Dry run — no changes will be made' ,
111- ) ;
105+ return [
106+ chalk . bold ( `App: ${ app . name } ` ) ,
107+ ...serverRows . map ( ( [ k , v ] ) => ` ${ chalk . dim ( k . padEnd ( 14 ) ) } ${ v } ` ) ,
108+ '' ,
109+ chalk . bold ( ' Build' ) ,
110+ ...buildRows . map ( ( [ k , v ] ) => ` ${ chalk . dim ( k . padEnd ( 14 ) ) } ${ v } ` ) ,
111+ '' ,
112+ chalk . bold ( ' Deploy flow' ) ,
113+ ...flowRows . map ( ( [ k , v ] ) => ` ${ chalk . dim ( k . padEnd ( 4 ) ) } ${ v } ` ) ,
114+ ] . join ( '\n' ) ;
115+ }
116+
117+ function printDryRun ( config : ShipnodeConfig , skipBuild : boolean ) : void {
118+ ui . banner ( ) ;
119+
120+ const header = [
121+ chalk . bold ( 'Workspace' ) ,
122+ ` ${ chalk . dim ( 'Host' . padEnd ( 14 ) ) } ${ config . ssh . user } @${ config . ssh . host } :${ config . ssh . port } ` ,
123+ ` ${ chalk . dim ( 'Remote path' . padEnd ( 14 ) ) } ${ config . remotePath } ` ,
124+ ` ${ chalk . dim ( 'Node' . padEnd ( 14 ) ) } ${ config . nodeVersion } ` ,
125+ ` ${ chalk . dim ( 'Apps' . padEnd ( 14 ) ) } ${ config . apps . map ( ( a ) => a . name ) . join ( ', ' ) } ` ,
126+ ] . join ( '\n' ) ;
127+
128+ const perApp = config . apps . map ( ( app ) => renderAppPlan ( app , skipBuild ) ) . join ( '\n\n' ) ;
129+
130+ ui . note ( [ header , '' , perApp ] . join ( '\n' ) , 'Dry run — no changes will be made' ) ;
112131}
0 commit comments