@wyxos/zephyr 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -338,11 +338,43 @@ async function resolveMaintenanceModePlan({
|
|
|
338
338
|
})
|
|
339
339
|
}
|
|
340
340
|
|
|
341
|
+
export async function resolveRemoteDeploymentState({
|
|
342
|
+
snapshot,
|
|
343
|
+
executionMode = {},
|
|
344
|
+
ssh,
|
|
345
|
+
remoteCwd,
|
|
346
|
+
runPrompt,
|
|
347
|
+
logSuccess,
|
|
348
|
+
logWarning
|
|
349
|
+
} = {}) {
|
|
350
|
+
const remoteIsLaravel = await detectRemoteLaravelProject(ssh, remoteCwd)
|
|
351
|
+
|
|
352
|
+
if (remoteIsLaravel) {
|
|
353
|
+
logSuccess?.('Laravel project detected.')
|
|
354
|
+
} else {
|
|
355
|
+
logWarning?.('Laravel project not detected; skipping Laravel-specific maintenance tasks.')
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
const maintenanceModeEnabled = await resolveMaintenanceMode({
|
|
359
|
+
snapshot,
|
|
360
|
+
remoteIsLaravel,
|
|
361
|
+
runPrompt,
|
|
362
|
+
executionMode
|
|
363
|
+
})
|
|
364
|
+
|
|
365
|
+
return {
|
|
366
|
+
remoteIsLaravel,
|
|
367
|
+
maintenanceModeEnabled
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
341
371
|
export async function buildRemoteDeploymentPlan({
|
|
342
372
|
config,
|
|
343
373
|
snapshot = null,
|
|
344
374
|
requiredPhpVersion = null,
|
|
345
375
|
executionMode = {},
|
|
376
|
+
remoteIsLaravel = null,
|
|
377
|
+
maintenanceModeEnabled = null,
|
|
346
378
|
ssh,
|
|
347
379
|
remoteCwd,
|
|
348
380
|
executeRemote,
|
|
@@ -351,18 +383,26 @@ export async function buildRemoteDeploymentPlan({
|
|
|
351
383
|
logWarning,
|
|
352
384
|
runPrompt
|
|
353
385
|
} = {}) {
|
|
354
|
-
const
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
386
|
+
const remoteState = typeof remoteIsLaravel === 'boolean' &&
|
|
387
|
+
(remoteIsLaravel === false || typeof maintenanceModeEnabled === 'boolean')
|
|
388
|
+
? {
|
|
389
|
+
remoteIsLaravel,
|
|
390
|
+
maintenanceModeEnabled: remoteIsLaravel ? maintenanceModeEnabled : false
|
|
391
|
+
}
|
|
392
|
+
: await resolveRemoteDeploymentState({
|
|
393
|
+
snapshot,
|
|
394
|
+
executionMode,
|
|
395
|
+
ssh,
|
|
396
|
+
remoteCwd,
|
|
397
|
+
runPrompt,
|
|
398
|
+
logSuccess,
|
|
399
|
+
logWarning
|
|
400
|
+
})
|
|
361
401
|
|
|
362
402
|
const changedFiles = await collectChangedFiles({
|
|
363
403
|
config,
|
|
364
404
|
snapshot,
|
|
365
|
-
remoteIsLaravel,
|
|
405
|
+
remoteIsLaravel: remoteState.remoteIsLaravel,
|
|
366
406
|
executeRemote,
|
|
367
407
|
logProcessing
|
|
368
408
|
})
|
|
@@ -370,7 +410,7 @@ export async function buildRemoteDeploymentPlan({
|
|
|
370
410
|
const horizonConfigured = await detectHorizonConfiguration({
|
|
371
411
|
ssh,
|
|
372
412
|
remoteCwd,
|
|
373
|
-
remoteIsLaravel,
|
|
413
|
+
remoteIsLaravel: remoteState.remoteIsLaravel,
|
|
374
414
|
changedFiles
|
|
375
415
|
})
|
|
376
416
|
|
|
@@ -382,18 +422,11 @@ export async function buildRemoteDeploymentPlan({
|
|
|
382
422
|
logWarning
|
|
383
423
|
})
|
|
384
424
|
|
|
385
|
-
const maintenanceModeEnabled = await resolveMaintenanceMode({
|
|
386
|
-
snapshot,
|
|
387
|
-
remoteIsLaravel,
|
|
388
|
-
runPrompt,
|
|
389
|
-
executionMode
|
|
390
|
-
})
|
|
391
|
-
|
|
392
425
|
const maintenanceModePlan = await resolveMaintenanceModePlan({
|
|
393
426
|
snapshot,
|
|
394
|
-
remoteIsLaravel,
|
|
427
|
+
remoteIsLaravel: remoteState.remoteIsLaravel,
|
|
395
428
|
remoteCwd,
|
|
396
|
-
maintenanceModeEnabled,
|
|
429
|
+
maintenanceModeEnabled: remoteState.maintenanceModeEnabled,
|
|
397
430
|
phpCommand,
|
|
398
431
|
ssh,
|
|
399
432
|
executeRemote,
|
|
@@ -403,7 +436,7 @@ export async function buildRemoteDeploymentPlan({
|
|
|
403
436
|
|
|
404
437
|
const steps = planLaravelDeploymentTasks({
|
|
405
438
|
branch: config.branch,
|
|
406
|
-
isLaravel: remoteIsLaravel,
|
|
439
|
+
isLaravel: remoteState.remoteIsLaravel,
|
|
407
440
|
changedFiles,
|
|
408
441
|
horizonConfigured,
|
|
409
442
|
phpCommand,
|
|
@@ -438,7 +471,7 @@ export async function buildRemoteDeploymentPlan({
|
|
|
438
471
|
}
|
|
439
472
|
|
|
440
473
|
return {
|
|
441
|
-
remoteIsLaravel,
|
|
474
|
+
remoteIsLaravel: remoteState.remoteIsLaravel,
|
|
442
475
|
changedFiles,
|
|
443
476
|
horizonConfigured,
|
|
444
477
|
phpCommand,
|
|
@@ -12,7 +12,7 @@ import {createRemoteExecutor} from '../../deploy/remote-exec.mjs'
|
|
|
12
12
|
import {resolveSshKeyPath} from '../../ssh/keys.mjs'
|
|
13
13
|
import {cleanupOldLogs, closeLogFile, getLogFilePath, writeToLogFile} from '../../utils/log-file.mjs'
|
|
14
14
|
import {resolveRemotePath} from '../../utils/remote-path.mjs'
|
|
15
|
-
import {buildRemoteDeploymentPlan} from './build-remote-deployment-plan.mjs'
|
|
15
|
+
import {buildRemoteDeploymentPlan, resolveRemoteDeploymentState} from './build-remote-deployment-plan.mjs'
|
|
16
16
|
import {executeRemoteDeploymentPlan} from './execute-remote-deployment-plan.mjs'
|
|
17
17
|
import {prepareLocalDeployment} from './prepare-local-deployment.mjs'
|
|
18
18
|
|
|
@@ -21,6 +21,37 @@ async function resolveRemoteHome(ssh, sshUser) {
|
|
|
21
21
|
return remoteHomeResult.stdout.trim() || `/home/${sshUser}`
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
async function connectToRemoteDeploymentTarget({
|
|
25
|
+
config,
|
|
26
|
+
createSshClient,
|
|
27
|
+
sshUser,
|
|
28
|
+
privateKey,
|
|
29
|
+
remoteCwd = null,
|
|
30
|
+
logProcessing,
|
|
31
|
+
message
|
|
32
|
+
} = {}) {
|
|
33
|
+
const ssh = createSshClient()
|
|
34
|
+
|
|
35
|
+
logProcessing?.(`\n${message ?? `Connecting to ${config.serverIp} as ${sshUser}...`}`)
|
|
36
|
+
|
|
37
|
+
await ssh.connect({
|
|
38
|
+
host: config.serverIp,
|
|
39
|
+
username: sshUser,
|
|
40
|
+
privateKey
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
if (remoteCwd) {
|
|
44
|
+
return {ssh, remoteCwd}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const remoteHome = await resolveRemoteHome(ssh, sshUser)
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
ssh,
|
|
51
|
+
remoteCwd: resolveRemotePath(config.projectPath, remoteHome)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
24
55
|
async function maybeRecoverLaravelMaintenanceMode({
|
|
25
56
|
remotePlan,
|
|
26
57
|
executionState,
|
|
@@ -105,43 +136,66 @@ export async function runDeployment(config, options = {}) {
|
|
|
105
136
|
|
|
106
137
|
await cleanupOldLogs(rootDir)
|
|
107
138
|
|
|
108
|
-
const {requiredPhpVersion} = await prepareLocalDeployment(config, {
|
|
109
|
-
snapshot,
|
|
110
|
-
rootDir,
|
|
111
|
-
versionArg,
|
|
112
|
-
runPrompt,
|
|
113
|
-
runCommand,
|
|
114
|
-
runCommandCapture: context.runCommandCapture,
|
|
115
|
-
logProcessing,
|
|
116
|
-
logSuccess,
|
|
117
|
-
logWarning
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
const ssh = createSshClient()
|
|
121
139
|
const sshUser = config.sshUser || os.userInfo().username
|
|
122
140
|
const privateKeyPath = await resolveSshKeyPath(config.sshKey)
|
|
123
141
|
const privateKey = await fs.readFile(privateKeyPath, 'utf8')
|
|
142
|
+
let ssh = null
|
|
124
143
|
let remoteCwd = null
|
|
125
144
|
let executeRemote = null
|
|
126
145
|
let remotePlan = null
|
|
146
|
+
let remoteState = null
|
|
127
147
|
const executionState = {
|
|
128
148
|
enteredMaintenanceMode: false,
|
|
129
149
|
exitedMaintenanceMode: false
|
|
130
150
|
}
|
|
131
151
|
|
|
132
|
-
logProcessing(`\nConnecting to ${config.serverIp} as ${sshUser}...`)
|
|
133
|
-
|
|
134
152
|
let lockAcquired = false
|
|
135
153
|
|
|
136
154
|
try {
|
|
137
|
-
await
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
155
|
+
({ssh, remoteCwd} = await connectToRemoteDeploymentTarget({
|
|
156
|
+
config,
|
|
157
|
+
createSshClient,
|
|
158
|
+
sshUser,
|
|
159
|
+
privateKey,
|
|
160
|
+
logProcessing,
|
|
161
|
+
message: `Connecting to ${config.serverIp} as ${sshUser} to inspect remote deployment state...`
|
|
162
|
+
}))
|
|
163
|
+
|
|
164
|
+
remoteState = await resolveRemoteDeploymentState({
|
|
165
|
+
snapshot,
|
|
166
|
+
executionMode,
|
|
167
|
+
ssh,
|
|
168
|
+
remoteCwd,
|
|
169
|
+
runPrompt,
|
|
170
|
+
logSuccess,
|
|
171
|
+
logWarning
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
// Reconnect after local checks so long-running validation does not hold a stale SSH session open.
|
|
175
|
+
await ssh.dispose()
|
|
176
|
+
ssh = null
|
|
177
|
+
|
|
178
|
+
const {requiredPhpVersion} = await prepareLocalDeployment(config, {
|
|
179
|
+
snapshot,
|
|
180
|
+
rootDir,
|
|
181
|
+
versionArg,
|
|
182
|
+
runPrompt,
|
|
183
|
+
runCommand,
|
|
184
|
+
runCommandCapture: context.runCommandCapture,
|
|
185
|
+
logProcessing,
|
|
186
|
+
logSuccess,
|
|
187
|
+
logWarning
|
|
141
188
|
})
|
|
142
189
|
|
|
143
|
-
|
|
144
|
-
|
|
190
|
+
;({ssh} = await connectToRemoteDeploymentTarget({
|
|
191
|
+
config,
|
|
192
|
+
createSshClient,
|
|
193
|
+
sshUser,
|
|
194
|
+
privateKey,
|
|
195
|
+
remoteCwd,
|
|
196
|
+
logProcessing,
|
|
197
|
+
message: `Reconnecting to ${config.serverIp} as ${sshUser}...`
|
|
198
|
+
}))
|
|
145
199
|
|
|
146
200
|
logProcessing('Connection established. Acquiring deployment lock on server...')
|
|
147
201
|
await acquireRemoteLock(ssh, remoteCwd, rootDir, {
|
|
@@ -168,6 +222,8 @@ export async function runDeployment(config, options = {}) {
|
|
|
168
222
|
rootDir,
|
|
169
223
|
requiredPhpVersion,
|
|
170
224
|
executionMode,
|
|
225
|
+
remoteIsLaravel: remoteState?.remoteIsLaravel,
|
|
226
|
+
maintenanceModeEnabled: remoteState?.maintenanceModeEnabled,
|
|
171
227
|
ssh,
|
|
172
228
|
remoteCwd,
|
|
173
229
|
executeRemote,
|