14
14
use JTMcC \AtomicDeployments \Models \Enums \DeploymentStatus ;
15
15
16
16
use Illuminate \Support \Pluralizer ;
17
+ use Illuminate \Support \Facades \File ;
17
18
18
19
class AtomicDeployments
19
20
{
20
21
21
22
protected ?AtomicDeployment $ model = null ;
22
23
23
24
protected bool $ dryRun ;
25
+ protected array $ migrate ;
24
26
25
27
protected string $ buildPath ;
26
28
protected string $ deploymentLink ;
@@ -34,15 +36,22 @@ class AtomicDeployments
34
36
* @param string $deploymentLink
35
37
* @param string $deploymentsPath
36
38
* @param string $buildPath
39
+ * @param array $migrate
37
40
* @param bool $dryRun
38
41
*
39
42
* @throws ExecuteFailedException
40
43
*/
41
- public function __construct (string $ deploymentLink , string $ deploymentsPath , string $ buildPath , bool $ dryRun = false )
44
+ public function __construct (
45
+ string $ deploymentLink ,
46
+ string $ deploymentsPath ,
47
+ string $ buildPath ,
48
+ array $ migrate = [],
49
+ bool $ dryRun = false )
42
50
{
43
51
$ this ->deploymentLink = $ deploymentLink ;
44
52
$ this ->deploymentsPath = $ deploymentsPath ;
45
53
$ this ->buildPath = $ buildPath ;
54
+ $ this ->migrate = $ migrate ;
46
55
$ this ->dryRun = $ dryRun ;
47
56
48
57
register_shutdown_function ([$ this , 'shutdown ' ]);
@@ -57,7 +66,7 @@ public function __construct(string $deploymentLink, string $deploymentsPath, str
57
66
* @param Closure|null $success
58
67
* @param Closure|null $failed
59
68
*/
60
- public function deploy (?Closure $ success = null , ?Closure $ failed = null )
69
+ public function deploy (?Closure $ success = null , ?Closure $ failed = null ): void
61
70
{
62
71
try {
63
72
@@ -80,6 +89,7 @@ public function deploy(?Closure $success = null, ?Closure $failed = null)
80
89
$ this ->createDeploymentDirectory ();
81
90
$ this ->confirmRequiredDirectoriesExist ();
82
91
$ this ->copyDeploymentContents ();
92
+ $ this ->copyMigrationContents ();
83
93
$ this ->linkDeployment ($ this ->deploymentLink , $ this ->deploymentPath );
84
94
$ this ->confirmSymbolicLink ($ this ->deploymentPath );
85
95
$ this ->updateDeploymentStatus (DeploymentStatus::SUCCESS );
@@ -104,7 +114,7 @@ public function deploy(?Closure $success = null, ?Closure $failed = null)
104
114
*
105
115
* @param int $status
106
116
*/
107
- public function updateDeploymentStatus (int $ status )
117
+ public function updateDeploymentStatus (int $ status ): void
108
118
{
109
119
if ($ this ->isDryRun ()) {
110
120
Output::warn ('Dry run - Skipping deployment status update ' );
@@ -132,7 +142,7 @@ public function updateDeploymentStatus(int $status)
132
142
*
133
143
* @throws ExecuteFailedException
134
144
*/
135
- public function confirmSymbolicLink (string $ deploymentPath )
145
+ public function confirmSymbolicLink (string $ deploymentPath ): bool
136
146
{
137
147
Output::info ('Confirming deployment link is correct ' );
138
148
$ currentDeploymentPath = $ this ->getCurrentDeploymentPath ();
@@ -154,7 +164,7 @@ public function confirmSymbolicLink(string $deploymentPath)
154
164
/**
155
165
* @throws InvalidPathException
156
166
*/
157
- public function confirmRequiredDirectoriesExist ()
167
+ public function confirmRequiredDirectoriesExist (): void
158
168
{
159
169
if ($ this ->isDryRun ()) {
160
170
Output::warn ('Dry run - Skipping required directory exists check for: ' );
@@ -176,7 +186,7 @@ public function createDeploymentDirectory(): void
176
186
{
177
187
Output::info ("Creating directory at {$ this ->deploymentPath }" );
178
188
179
- if (strpos ($ this ->deploymentPath , $ this ->buildPath ) !== false ) {
189
+ if (strpos ($ this ->deploymentPath , $ this ->buildPath ) !== false ) {
180
190
throw new InvalidPathException ('Deployments folder cannot be subdirectory of build folder ' );
181
191
}
182
192
@@ -204,11 +214,63 @@ public function copyDeploymentContents(): void
204
214
return ;
205
215
}
206
216
207
- Exec::rsyncDir ("{$ this ->buildPath }/ " , "{$ this ->deploymentPath }/ " );
217
+ Exec::rsync ("{$ this ->buildPath }/ " , "{$ this ->deploymentPath }/ " );
208
218
Output::info ('Copying complete ' );
209
219
}
210
220
211
221
222
+ /**
223
+ * @throws ExecuteFailedException
224
+ */
225
+ public function copyMigrationContents (): void
226
+ {
227
+ if (!empty ($ this ->initialDeploymentPath ) && count ($ this ->migrate )) {
228
+
229
+ if ($ this ->isDryRun ()) {
230
+ Output::warn ('Dry run - skipping migrations ' );
231
+ }
232
+
233
+ collect ($ this ->migrate )->each (function ($ pattern ) {
234
+
235
+ if (!$ this ->isDryRun ()) {
236
+ Output::info ("Running migration for pattern {$ pattern }" );
237
+ }
238
+
239
+ $ rootFrom = rtrim ($ this ->initialDeploymentPath , DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR ;
240
+ $ rootTo = rtrim ($ this ->deploymentPath , DIRECTORY_SEPARATOR ) . DIRECTORY_SEPARATOR ;
241
+
242
+ foreach (File::glob ($ rootFrom . $ pattern ) as $ from ) {
243
+
244
+ $ dir = $ from ;
245
+
246
+ if (!File::isDirectory ($ dir )) {
247
+ $ dir = File::dirname ($ dir );
248
+ }
249
+
250
+ $ dir = str_replace ($ rootFrom , $ rootTo , $ dir );
251
+ $ to = str_replace ($ rootFrom , $ rootTo , $ from );
252
+
253
+ if ($ this ->isDryRun ()) {
254
+ Output::warn ("Dry run - migrate: \r\n - {$ from }\r\n - {$ to }" );
255
+ Output::line ();
256
+ continue ;
257
+ }
258
+
259
+ File::ensureDirectoryExists ($ dir , 0755 , true );
260
+
261
+ Exec::rsync ($ from , $ to );
262
+
263
+ }
264
+
265
+ if (!$ this ->isDryRun ()) {
266
+ Output::info ("Finished migration for pattern {$ pattern }" );
267
+ }
268
+
269
+ });
270
+ }
271
+ }
272
+
273
+
212
274
/**
213
275
* Create Symbolic link for live deployment
214
276
* Will overwrite previous link
@@ -249,10 +311,10 @@ public function setDeploymentDirectory(string $name): void
249
311
*
250
312
* @throws ExecuteFailedException
251
313
*/
252
- public function getCurrentDeploymentPath ()
314
+ public function getCurrentDeploymentPath (): string
253
315
{
254
316
$ result = Exec::readlink ($ this ->deploymentLink );
255
- if ($ result === $ this ->deploymentLink ) {
317
+ if ($ result === $ this ->deploymentLink ) {
256
318
return '' ;
257
319
}
258
320
return $ result ;
@@ -276,7 +338,7 @@ public function setDeploymentPath(): void
276
338
*
277
339
* @see getCurrentDeploymentPath() to get the path currently in use
278
340
*/
279
- public function getDeploymentPath ()
341
+ public function getDeploymentPath (): string
280
342
{
281
343
return $ this ->deploymentsPath ;
282
344
}
@@ -333,7 +395,7 @@ public function rollback(): void
333
395
* @throws ExecuteFailedException
334
396
* @throws InvalidPathException
335
397
*/
336
- public function cleanBuilds ($ limit )
398
+ public function cleanBuilds ($ limit ): void
337
399
{
338
400
Output::alert ('Running Build Cleanup ' );
339
401
Output::info ("Max deployment directories allowed set to {$ limit }" );
@@ -368,23 +430,30 @@ public function cleanBuilds($limit)
368
430
}
369
431
370
432
371
- public function isDryRun () {
433
+ /**
434
+ * @return bool
435
+ */
436
+ public function isDryRun (): bool
437
+ {
372
438
return $ this ->dryRun ;
373
439
}
374
-
440
+
375
441
376
442
/**
377
443
* @throws ExecuteFailedException
378
444
*/
379
- public function failed ()
445
+ public function failed (): void
380
446
{
381
447
$ this ->rollback ();
382
448
$ this ->updateDeploymentStatus (DeploymentStatus::FAILED );
383
449
DeploymentFailed::dispatch ($ this , $ this ->model );
384
450
}
385
451
386
-
387
- public function shutdown ()
452
+
453
+ /**
454
+ * @throws ExecuteFailedException
455
+ */
456
+ public function shutdown (): void
388
457
{
389
458
if ($ error = error_get_last ()) {
390
459
Output::error ("Error detected during shutdown, requesting rollback " );
0 commit comments