|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Deployer; |
|
4
|
|
|
|
|
5
|
|
|
require_once __DIR__ . '/common.php'; |
|
6
|
|
|
require_once __DIR__ . '/../contrib/cachetool.php'; |
|
7
|
|
|
|
|
8
|
|
|
use Deployer\Exception\ConfigurationException; |
|
9
|
|
|
use Deployer\Exception\GracefulShutdownException; |
|
10
|
|
|
use Deployer\Exception\RunException; |
|
11
|
|
|
use Deployer\Host\Host; |
|
12
|
|
|
|
|
13
|
|
|
const CONFIG_IMPORT_NEEDED_EXIT_CODE = 2; |
|
14
|
|
|
const DB_UPDATE_NEEDED_EXIT_CODE = 2; |
|
15
|
|
|
const MAINTENANCE_MODE_ACTIVE_OUTPUT_MSG = 'maintenance mode is active'; |
|
16
|
|
|
const ENV_CONFIG_FILE_PATH = 'app/etc/env.php'; |
|
17
|
|
|
const TMP_ENV_CONFIG_FILE_PATH = 'app/etc/env_tmp.php'; |
|
18
|
|
|
|
|
19
|
|
|
add('recipes', ['magento2']); |
|
20
|
|
|
|
|
21
|
|
|
// Configuration |
|
22
|
|
|
|
|
23
|
|
|
// By default setup:static-content:deploy uses `en_US`. |
|
24
|
|
|
// To change that, simply put `set('static_content_locales', 'en_US de_DE');` |
|
25
|
|
|
// in you deployer script. |
|
26
|
|
|
set('static_content_locales', 'en_US'); |
|
27
|
|
|
|
|
28
|
|
|
// Configuration |
|
29
|
|
|
|
|
30
|
|
|
// You can also set the themes to run against. By default it'll deploy |
|
31
|
|
|
// all themes - `add('magento_themes', ['Magento/luma', 'Magento/backend']);` |
|
32
|
|
|
// If the themes are set as a simple list of strings, then all languages defined in {{static_content_locales}} are |
|
33
|
|
|
// compiled for the given themes. |
|
34
|
|
|
// Alternatively The themes can be defined as an associative array, where the key represents the theme name and |
|
35
|
|
|
// the key contains the languages for the compilation (for this specific theme) |
|
36
|
|
|
// Example: |
|
37
|
|
|
// set('magento_themes', ['Magento/luma']); - Will compile this theme with every language from {{static_content_locales}} |
|
38
|
|
|
// set('magento_themes', [ |
|
39
|
|
|
// 'Magento/luma' => null, - Will compile all languages from {{static_content_locales}} for Magento/luma |
|
40
|
|
|
// 'Custom/theme' => 'en_US fr_FR' - Will compile only en_US and fr_FR for Custom/theme |
|
41
|
|
|
// 'Custom/another' => '{{static_content_locales}} it_IT' - Will compile all languages from {{static_content_locales}} + it_IT for Custom/another |
|
42
|
|
|
// ]); - Will compile this theme with every language |
|
43
|
|
|
set('magento_themes', [ |
|
44
|
|
|
|
|
45
|
|
|
]); |
|
46
|
|
|
|
|
47
|
|
|
// Static content deployment options, e.g. '--no-parent' |
|
48
|
|
|
set('static_deploy_options', ''); |
|
49
|
|
|
|
|
50
|
|
|
// Deploy frontend and adminhtml together as default |
|
51
|
|
|
set('split_static_deployment', false); |
|
52
|
|
|
|
|
53
|
|
|
// Use the default languages for the backend as default |
|
54
|
|
|
set('static_content_locales_backend', '{{static_content_locales}}'); |
|
55
|
|
|
|
|
56
|
|
|
// backend themes to deploy. Only used if split_static_deployment=true |
|
57
|
|
|
// This setting supports the same options/structure as {{magento_themes}} |
|
58
|
|
|
set('magento_themes_backend', ['Magento/backend' => null]); |
|
59
|
|
|
|
|
60
|
|
|
// Configuration |
|
61
|
|
|
|
|
62
|
|
|
// Also set the number of concurrent jobs to run. The default is 1 |
|
63
|
|
|
// Update using: `set('static_content_jobs', '1');` |
|
64
|
|
|
set('static_content_jobs', '1'); |
|
65
|
|
|
|
|
66
|
|
|
set('content_version', function () { |
|
67
|
|
|
return time(); |
|
68
|
|
|
}); |
|
69
|
|
|
|
|
70
|
|
|
// Magento directory relative to repository root. Use "." (default) if it is not located in a subdirectory |
|
71
|
|
|
set('magento_dir', '.'); |
|
72
|
|
|
|
|
73
|
|
|
|
|
74
|
|
|
set('shared_files', [ |
|
75
|
|
|
'{{magento_dir}}/app/etc/env.php', |
|
76
|
|
|
'{{magento_dir}}/var/.maintenance.ip', |
|
77
|
|
|
]); |
|
78
|
|
|
set('shared_dirs', [ |
|
79
|
|
|
'{{magento_dir}}/var/composer_home', |
|
80
|
|
|
'{{magento_dir}}/var/log', |
|
81
|
|
|
'{{magento_dir}}/var/export', |
|
82
|
|
|
'{{magento_dir}}/var/report', |
|
83
|
|
|
'{{magento_dir}}/var/import', |
|
84
|
|
|
'{{magento_dir}}/var/import_history', |
|
85
|
|
|
'{{magento_dir}}/var/session', |
|
86
|
|
|
'{{magento_dir}}/var/importexport', |
|
87
|
|
|
'{{magento_dir}}/var/backups', |
|
88
|
|
|
'{{magento_dir}}/var/tmp', |
|
89
|
|
|
'{{magento_dir}}/pub/sitemap', |
|
90
|
|
|
'{{magento_dir}}/pub/media', |
|
91
|
|
|
'{{magento_dir}}/pub/static/_cache', |
|
92
|
|
|
]); |
|
93
|
|
|
set('writable_dirs', [ |
|
94
|
|
|
'{{magento_dir}}/var', |
|
95
|
|
|
'{{magento_dir}}/pub/static', |
|
96
|
|
|
'{{magento_dir}}/pub/media', |
|
97
|
|
|
'{{magento_dir}}/generated', |
|
98
|
|
|
'{{magento_dir}}/var/page_cache', |
|
99
|
|
|
]); |
|
100
|
|
|
set('clear_paths', [ |
|
101
|
|
|
'{{magento_dir}}/generated/*', |
|
102
|
|
|
'{{magento_dir}}/pub/static/_cache/*', |
|
103
|
|
|
'{{magento_dir}}/var/generation/*', |
|
104
|
|
|
'{{magento_dir}}/var/cache/*', |
|
105
|
|
|
'{{magento_dir}}/var/page_cache/*', |
|
106
|
|
|
'{{magento_dir}}/var/view_preprocessed/*', |
|
107
|
|
|
]); |
|
108
|
|
|
|
|
109
|
|
|
set('bin/magento', '{{release_or_current_path}}/{{magento_dir}}/bin/magento'); |
|
110
|
|
|
|
|
111
|
|
|
set('magento_version', function () { |
|
112
|
|
|
// detect version |
|
113
|
|
|
$versionOutput = run('{{bin/php}} {{bin/magento}} --version'); |
|
114
|
|
|
preg_match('/(\d+\.?)+(-p\d+)?$/', $versionOutput, $matches); |
|
115
|
|
|
return $matches[0] ?? '2.0'; |
|
116
|
|
|
}); |
|
117
|
|
|
|
|
118
|
|
|
set('config_import_needed', function () { |
|
119
|
|
|
// detect if app:config:import is needed |
|
120
|
|
|
try { |
|
121
|
|
|
run('{{bin/php}} {{bin/magento}} app:config:status'); |
|
122
|
|
|
} catch (RunException $e) { |
|
123
|
|
|
if ($e->getExitCode() == CONFIG_IMPORT_NEEDED_EXIT_CODE) { |
|
124
|
|
|
return true; |
|
125
|
|
|
} |
|
126
|
|
|
|
|
127
|
|
|
throw $e; |
|
128
|
|
|
} |
|
129
|
|
|
return false; |
|
130
|
|
|
}); |
|
131
|
|
|
|
|
132
|
|
|
set('database_upgrade_needed', function () { |
|
133
|
|
|
// detect if setup:upgrade is needed |
|
134
|
|
|
try { |
|
135
|
|
|
run('{{bin/php}} {{bin/magento}} setup:db:status'); |
|
136
|
|
|
} catch (RunException $e) { |
|
137
|
|
|
if ($e->getExitCode() == DB_UPDATE_NEEDED_EXIT_CODE) { |
|
138
|
|
|
return true; |
|
139
|
|
|
} |
|
140
|
|
|
|
|
141
|
|
|
throw $e; |
|
142
|
|
|
} |
|
143
|
|
|
|
|
144
|
|
|
return false; |
|
145
|
|
|
}); |
|
146
|
|
|
|
|
147
|
|
|
// Deploy without setting maintenance mode if possible |
|
148
|
|
|
set('enable_zerodowntime', true); |
|
149
|
|
|
|
|
150
|
|
|
// Tasks |
|
151
|
|
|
|
|
152
|
|
|
// To work correctly with artifact deployment, it is necessary to set the MAGE_MODE correctly in `app/etc/config.php` |
|
153
|
|
|
// e.g. |
|
154
|
|
|
// ```php |
|
155
|
|
|
// 'MAGE_MODE' => 'production' |
|
156
|
|
|
// ``` |
|
157
|
|
|
desc('Compiles magento di'); |
|
158
|
|
|
task('magento:compile', function () { |
|
159
|
|
|
run("{{bin/php}} {{bin/magento}} setup:di:compile"); |
|
160
|
|
|
run('cd {{release_or_current_path}}/{{magento_dir}} && {{bin/composer}} dump-autoload -o'); |
|
161
|
|
|
}); |
|
162
|
|
|
|
|
163
|
|
|
// To work correctly with artifact deployment it is necessary to set `system/dev/js` , `system/dev/css` and `system/dev/template` |
|
164
|
|
|
// in `app/etc/config.php`, e.g.: |
|
165
|
|
|
// ```php |
|
166
|
|
|
// 'system' => [ |
|
167
|
|
|
// 'default' => [ |
|
168
|
|
|
// 'dev' => [ |
|
169
|
|
|
// 'js' => [ |
|
170
|
|
|
// 'merge_files' => '1', |
|
171
|
|
|
// 'minify_files' => '1' |
|
172
|
|
|
// ], |
|
173
|
|
|
// 'css' => [ |
|
174
|
|
|
// 'merge_files' => '1', |
|
175
|
|
|
// 'minify_files' => '1' |
|
176
|
|
|
// ], |
|
177
|
|
|
// 'template' => [ |
|
178
|
|
|
// 'minify_html' => '1' |
|
179
|
|
|
// ] |
|
180
|
|
|
// ] |
|
181
|
|
|
// ] |
|
182
|
|
|
// ``` |
|
183
|
|
|
desc('Deploys assets'); |
|
184
|
|
|
task('magento:deploy:assets', function () { |
|
185
|
|
|
$themesToCompile = ''; |
|
186
|
|
|
if (get('split_static_deployment')) { |
|
187
|
|
|
invoke('magento:deploy:assets:adminhtml'); |
|
188
|
|
|
invoke('magento:deploy:assets:frontend'); |
|
189
|
|
|
} else { |
|
190
|
|
|
if (count(get('magento_themes')) > 0) { |
|
191
|
|
|
$themes = array_is_list(get('magento_themes')) ? get('magento_themes') : array_keys(get('magento_themes')); |
|
192
|
|
|
foreach ($themes as $theme) { |
|
193
|
|
|
$themesToCompile .= ' -t ' . $theme; |
|
194
|
|
|
} |
|
195
|
|
|
} |
|
196
|
|
|
run("{{bin/php}} {{release_or_current_path}}/bin/magento setup:static-content:deploy -f --content-version={{content_version}} {{static_deploy_options}} {{static_content_locales}} $themesToCompile -j {{static_content_jobs}}"); |
|
197
|
|
|
} |
|
198
|
|
|
}); |
|
199
|
|
|
|
|
200
|
|
|
desc('Deploys assets for backend only'); |
|
201
|
|
|
task('magento:deploy:assets:adminhtml', function () { |
|
202
|
|
|
magentoDeployAssetsSplit('backend'); |
|
203
|
|
|
}); |
|
204
|
|
|
|
|
205
|
|
|
desc('Deploys assets for frontend only'); |
|
206
|
|
|
task('magento:deploy:assets:frontend', function () { |
|
207
|
|
|
magentoDeployAssetsSplit('frontend'); |
|
208
|
|
|
}); |
|
209
|
|
|
|
|
210
|
|
|
/** |
|
211
|
|
|
* @phpstan-param 'frontend'|'backend' $area |
|
212
|
|
|
* |
|
213
|
|
|
* @throws ConfigurationException |
|
214
|
|
|
*/ |
|
215
|
|
|
function magentoDeployAssetsSplit(string $area) |
|
216
|
|
|
{ |
|
217
|
|
|
if (!in_array($area, ['frontend', 'backend'], true)) { |
|
218
|
|
|
throw new ConfigurationException("\$area must be either 'frontend' or 'backend', '$area' given"); |
|
219
|
|
|
} |
|
220
|
|
|
|
|
221
|
|
|
$isFrontend = $area === 'frontend'; |
|
222
|
|
|
$suffix = $isFrontend |
|
223
|
|
|
? '' |
|
224
|
|
|
: '_backend'; |
|
225
|
|
|
|
|
226
|
|
|
$themesConfig = get("magento_themes$suffix"); |
|
227
|
|
|
$defaultLanguages = get("static_content_locales$suffix"); |
|
228
|
|
|
$useDefaultLanguages = array_is_list($themesConfig); |
|
229
|
|
|
|
|
230
|
|
|
/** @var list<string> $themes */ |
|
231
|
|
|
$themes = $useDefaultLanguages |
|
232
|
|
|
? array_values($themesConfig) |
|
233
|
|
|
: array_keys($themesConfig); |
|
234
|
|
|
|
|
235
|
|
|
$staticContentArea = $isFrontend |
|
236
|
|
|
? 'frontend' |
|
237
|
|
|
: 'adminhtml'; |
|
238
|
|
|
|
|
239
|
|
|
if ($useDefaultLanguages) { |
|
240
|
|
|
$themes = '-t ' . implode(' -t ', $themes); |
|
|
|
|
|
|
241
|
|
|
|
|
242
|
|
|
run("{{bin/php}} {{bin/magento}} setup:static-content:deploy -f --area=$staticContentArea --content-version={{content_version}} {{static_deploy_options}} $defaultLanguages $themes -j {{static_content_jobs}}"); |
|
243
|
|
|
return; |
|
244
|
|
|
} |
|
245
|
|
|
|
|
246
|
|
|
foreach ($themes as $theme) { |
|
247
|
|
|
$languages = parse($themesConfig[$theme] ?? $defaultLanguages); |
|
248
|
|
|
|
|
249
|
|
|
run("{{bin/php}} {{bin/magento}} setup:static-content:deploy -f --area=$staticContentArea --content-version={{content_version}} {{static_deploy_options}} $languages -t $theme -j {{static_content_jobs}}"); |
|
250
|
|
|
} |
|
251
|
|
|
} |
|
252
|
|
|
|
|
253
|
|
|
desc('Syncs content version'); |
|
254
|
|
|
task('magento:sync:content_version', function () { |
|
255
|
|
|
$timestamp = time(); |
|
256
|
|
|
on(select('all'), function (Host $host) use ($timestamp) { |
|
257
|
|
|
$host->set('content_version', $timestamp); |
|
258
|
|
|
}); |
|
259
|
|
|
})->once(); |
|
260
|
|
|
|
|
261
|
|
|
before('magento:deploy:assets', 'magento:sync:content_version'); |
|
262
|
|
|
|
|
263
|
|
|
desc('Enables maintenance mode'); |
|
264
|
|
|
task('magento:maintenance:enable', function () { |
|
265
|
|
|
// do not use {{bin/magento}} because it would be in "release" but the maintenance mode must be set in "current" |
|
266
|
|
|
run("if [ -d $(echo {{current_path}}) ]; then {{bin/php}} {{current_path}}/{{magento_dir}}/bin/magento maintenance:enable; fi"); |
|
267
|
|
|
}); |
|
268
|
|
|
|
|
269
|
|
|
desc('Disables maintenance mode'); |
|
270
|
|
|
task('magento:maintenance:disable', function () { |
|
271
|
|
|
// do not use {{bin/magento}} because it would be in "release" but the maintenance mode must be set in "current" |
|
272
|
|
|
run("if [ -d $(echo {{current_path}}) ]; then {{bin/php}} {{current_path}}/{{magento_dir}}/bin/magento maintenance:disable; fi"); |
|
273
|
|
|
}); |
|
274
|
|
|
|
|
275
|
|
|
desc('Set maintenance mode if needed'); |
|
276
|
|
|
task('magento:maintenance:enable-if-needed', function () { |
|
277
|
|
|
! get('enable_zerodowntime') || get('database_upgrade_needed') || get('config_import_needed') ? |
|
278
|
|
|
invoke('magento:maintenance:enable') : |
|
279
|
|
|
writeln('Config and database up to date => no maintenance mode'); |
|
280
|
|
|
}); |
|
281
|
|
|
|
|
282
|
|
|
desc('Config Import'); |
|
283
|
|
|
task('magento:config:import', function () { |
|
284
|
|
|
if (get('config_import_needed')) { |
|
285
|
|
|
run('{{bin/php}} {{bin/magento}} app:config:import --no-interaction'); |
|
286
|
|
|
} else { |
|
287
|
|
|
writeln('App config is up to date => import skipped'); |
|
288
|
|
|
} |
|
289
|
|
|
}); |
|
290
|
|
|
|
|
291
|
|
|
desc('Upgrades magento database'); |
|
292
|
|
|
task('magento:upgrade:db', function () { |
|
293
|
|
|
if (get('database_upgrade_needed')) { |
|
294
|
|
|
run("{{bin/php}} {{bin/magento}} setup:db-schema:upgrade --no-interaction"); |
|
295
|
|
|
run("{{bin/php}} {{bin/magento}} setup:db-data:upgrade --no-interaction"); |
|
296
|
|
|
} else { |
|
297
|
|
|
writeln('Database schema is up to date => upgrade skipped'); |
|
298
|
|
|
} |
|
299
|
|
|
})->once(); |
|
300
|
|
|
|
|
301
|
|
|
desc('Flushes Magento Cache'); |
|
302
|
|
|
task('magento:cache:flush', function () { |
|
303
|
|
|
run("{{bin/php}} {{bin/magento}} cache:flush"); |
|
304
|
|
|
}); |
|
305
|
|
|
|
|
306
|
|
|
desc('Magento2 deployment operations'); |
|
307
|
|
|
task('deploy:magento', [ |
|
308
|
|
|
'magento:build', |
|
309
|
|
|
'magento:maintenance:enable-if-needed', |
|
310
|
|
|
'magento:config:import', |
|
311
|
|
|
'magento:upgrade:db', |
|
312
|
|
|
'magento:maintenance:disable', |
|
313
|
|
|
]); |
|
314
|
|
|
|
|
315
|
|
|
desc('Magento2 build operations'); |
|
316
|
|
|
task('magento:build', [ |
|
317
|
|
|
'magento:compile', |
|
318
|
|
|
'magento:deploy:assets', |
|
319
|
|
|
]); |
|
320
|
|
|
|
|
321
|
|
|
desc('Deploys your project'); |
|
322
|
|
|
task('deploy', [ |
|
323
|
|
|
'deploy:prepare', |
|
324
|
|
|
'deploy:vendors', |
|
325
|
|
|
'deploy:clear_paths', |
|
326
|
|
|
'deploy:magento', |
|
327
|
|
|
'deploy:publish', |
|
328
|
|
|
]); |
|
329
|
|
|
|
|
330
|
|
|
after('deploy:symlink', 'magento:cache:flush'); |
|
331
|
|
|
|
|
332
|
|
|
after('deploy:failed', 'magento:maintenance:disable'); |
|
333
|
|
|
|
|
334
|
|
|
// Artifact deployment section |
|
335
|
|
|
|
|
336
|
|
|
// The file the artifact is saved to |
|
337
|
|
|
set('artifact_file', 'artifact.tar.gz'); |
|
338
|
|
|
|
|
339
|
|
|
// The directory the artifact is saved in |
|
340
|
|
|
set('artifact_dir', 'artifacts'); |
|
341
|
|
|
|
|
342
|
|
|
// Points to a file with a list of files to exclude from packaging. |
|
343
|
|
|
// The format is as with the `tar --exclude-from=[file]` option |
|
344
|
|
|
set('artifact_excludes_file', 'artifacts/excludes'); |
|
345
|
|
|
|
|
346
|
|
|
// If set to true, the artifact is built from a clean copy of the project repository instead of the current working directory |
|
347
|
|
|
set('build_from_repo', false); |
|
348
|
|
|
|
|
349
|
|
|
// Set this value if "build_from_repo" is set to true. The target to deploy must also be set with "--branch", "--tag" or "--revision" |
|
350
|
|
|
set('repository', null); |
|
351
|
|
|
|
|
352
|
|
|
// The relative path to the artifact file. If the directory does not exist, it will be created |
|
353
|
|
|
set('artifact_path', function () { |
|
354
|
|
|
if (!testLocally('[ -d {{artifact_dir}} ]')) { |
|
355
|
|
|
runLocally('mkdir -p {{artifact_dir}}'); |
|
356
|
|
|
} |
|
357
|
|
|
return get('artifact_dir') . '/' . get('artifact_file'); |
|
358
|
|
|
}); |
|
359
|
|
|
|
|
360
|
|
|
// The location of the tar command. On MacOS you should have installed gtar, as it supports the required settings |
|
361
|
|
|
set('bin/tar', function () { |
|
362
|
|
|
if (commandExist('gtar')) { |
|
363
|
|
|
return which('gtar'); |
|
364
|
|
|
} else { |
|
365
|
|
|
return which('tar'); |
|
366
|
|
|
} |
|
367
|
|
|
}); |
|
368
|
|
|
|
|
369
|
|
|
// tasks section |
|
370
|
|
|
|
|
371
|
|
|
desc('Packages all relevant files in an artifact.'); |
|
372
|
|
|
task('artifact:package', function () { |
|
373
|
|
|
if (!test('[ -f {{artifact_excludes_file}} ]')) { |
|
374
|
|
|
throw new GracefulShutdownException( |
|
375
|
|
|
"No artifact excludes file provided, provide one at artifacts/excludes or change location", |
|
376
|
|
|
); |
|
377
|
|
|
} |
|
378
|
|
|
run('{{bin/tar}} --exclude-from={{artifact_excludes_file}} -czf {{artifact_path}} -C {{release_or_current_path}} .'); |
|
379
|
|
|
}); |
|
380
|
|
|
|
|
381
|
|
|
desc('Uploads artifact in release folder for extraction.'); |
|
382
|
|
|
task('artifact:upload', function () { |
|
383
|
|
|
upload(get('artifact_path'), '{{release_path}}'); |
|
384
|
|
|
}); |
|
385
|
|
|
|
|
386
|
|
|
desc('Extracts artifact in release path.'); |
|
387
|
|
|
task('artifact:extract', function () { |
|
388
|
|
|
run('{{bin/tar}} -xzpf {{release_path}}/{{artifact_file}} -C {{release_path}}'); |
|
389
|
|
|
run('rm -rf {{release_path}}/{{artifact_file}}'); |
|
390
|
|
|
}); |
|
391
|
|
|
|
|
392
|
|
|
desc('Clears generated files prior to building.'); |
|
393
|
|
|
task('build:remove-generated', function () { |
|
394
|
|
|
run('rm -rf generated/*'); |
|
395
|
|
|
}); |
|
396
|
|
|
|
|
397
|
|
|
desc('Prepare local artifact build'); |
|
398
|
|
|
task('build:prepare', function () { |
|
399
|
|
|
if (!currentHost()->get('local')) { |
|
400
|
|
|
throw new GracefulShutdownException('Artifact can only be built locally, you provided a non local host'); |
|
401
|
|
|
} |
|
402
|
|
|
|
|
403
|
|
|
$buildDir = get('build_from_repo') ? get('artifact_dir') . '/repo' : '.'; |
|
404
|
|
|
set('deploy_path', $buildDir); |
|
405
|
|
|
set('release_path', $buildDir); |
|
406
|
|
|
set('current_path', $buildDir); |
|
407
|
|
|
|
|
408
|
|
|
if (!get('build_from_repo')) { |
|
409
|
|
|
return; |
|
410
|
|
|
} |
|
411
|
|
|
|
|
412
|
|
|
$repository = (string) get('repository'); |
|
413
|
|
|
if ($repository === '') { |
|
414
|
|
|
throw new GracefulShutdownException('You must specify the "repository" option.'); |
|
415
|
|
|
} |
|
416
|
|
|
|
|
417
|
|
|
run('rm -rf {{release_or_current_path}}'); |
|
418
|
|
|
run('git clone {{repository}} {{release_or_current_path}}'); |
|
419
|
|
|
run('git -C {{release_or_current_path}} checkout --force {{target}}'); |
|
420
|
|
|
}); |
|
421
|
|
|
|
|
422
|
|
|
desc('Builds an artifact.'); |
|
423
|
|
|
task('artifact:build', [ |
|
424
|
|
|
'build:prepare', |
|
425
|
|
|
'build:remove-generated', |
|
426
|
|
|
'deploy:vendors', |
|
427
|
|
|
'magento:compile', |
|
428
|
|
|
'magento:deploy:assets', |
|
429
|
|
|
'artifact:package', |
|
430
|
|
|
]); |
|
431
|
|
|
|
|
432
|
|
|
// Array of shared files that will be added to the default shared_files without overriding |
|
433
|
|
|
set('additional_shared_files', []); |
|
434
|
|
|
// Array of shared directories that will be added to the default shared_dirs without overriding |
|
435
|
|
|
set('additional_shared_dirs', []); |
|
436
|
|
|
|
|
437
|
|
|
|
|
438
|
|
|
desc('Adds additional files and dirs to the list of shared files and dirs'); |
|
439
|
|
|
task('deploy:additional-shared', function () { |
|
440
|
|
|
add('shared_files', get('additional_shared_files')); |
|
441
|
|
|
add('shared_dirs', get('additional_shared_dirs')); |
|
442
|
|
|
}); |
|
443
|
|
|
|
|
444
|
|
|
/** |
|
445
|
|
|
* Update cache id_prefix on deploy so that you are compiling against a fresh cache |
|
446
|
|
|
* Reference Issue: https://github.com/davidalger/capistrano-magento2/issues/151 |
|
447
|
|
|
* To use this feature, add the following to your deployer scripts: |
|
448
|
|
|
* ```php |
|
449
|
|
|
* after('deploy:shared', 'magento:set_cache_prefix'); |
|
450
|
|
|
* after('deploy:magento', 'magento:cleanup_cache_prefix'); |
|
451
|
|
|
* ``` |
|
452
|
|
|
**/ |
|
453
|
|
|
desc('Update cache id_prefix'); |
|
454
|
|
|
task('magento:set_cache_prefix', function () { |
|
455
|
|
|
//download current env config |
|
456
|
|
|
$tmpConfigFile = tempnam(sys_get_temp_dir(), 'deployer_config'); |
|
457
|
|
|
download('{{deploy_path}}/shared/' . ENV_CONFIG_FILE_PATH, $tmpConfigFile); |
|
458
|
|
|
$envConfigArray = include($tmpConfigFile); |
|
459
|
|
|
//set prefix to `alias_releasename_` |
|
460
|
|
|
$prefixUpdate = get('alias') . '_' . get('release_name') . '_'; |
|
461
|
|
|
|
|
462
|
|
|
//check for preload keys and update |
|
463
|
|
|
if (isset($envConfigArray['cache']['frontend']['default']['backend_options']['preload_keys'])) { |
|
464
|
|
|
$oldPrefix = $envConfigArray['cache']['frontend']['default']['id_prefix']; |
|
465
|
|
|
$preloadKeys = $envConfigArray['cache']['frontend']['default']['backend_options']['preload_keys']; |
|
466
|
|
|
$newPreloadKeys = []; |
|
467
|
|
|
foreach ($preloadKeys as $preloadKey) { |
|
468
|
|
|
$newPreloadKeys[] = preg_replace('/^' . $oldPrefix . '/', $prefixUpdate, $preloadKey); |
|
469
|
|
|
} |
|
470
|
|
|
$envConfigArray['cache']['frontend']['default']['backend_options']['preload_keys'] = $newPreloadKeys; |
|
471
|
|
|
} |
|
472
|
|
|
|
|
473
|
|
|
//update id_prefix to include release name |
|
474
|
|
|
$envConfigArray['cache']['frontend']['default']['id_prefix'] = $prefixUpdate; |
|
475
|
|
|
$envConfigArray['cache']['frontend']['page_cache']['id_prefix'] = $prefixUpdate; |
|
476
|
|
|
|
|
477
|
|
|
//Generate configuration array as string |
|
478
|
|
|
$envConfigStr = '<?php return ' . var_export($envConfigArray, true) . ';'; |
|
479
|
|
|
file_put_contents($tmpConfigFile, $envConfigStr); |
|
480
|
|
|
//upload updated config to server |
|
481
|
|
|
upload($tmpConfigFile, '{{deploy_path}}/shared/' . TMP_ENV_CONFIG_FILE_PATH); |
|
482
|
|
|
//cleanup tmp file |
|
483
|
|
|
unlink($tmpConfigFile); |
|
484
|
|
|
//delete the symlink for env.php |
|
485
|
|
|
run('rm {{release_or_current_path}}/' . ENV_CONFIG_FILE_PATH); |
|
486
|
|
|
//link the env to the tmp version |
|
487
|
|
|
run('{{bin/symlink}} {{deploy_path}}/shared/' . TMP_ENV_CONFIG_FILE_PATH . ' {{release_path}}/' . ENV_CONFIG_FILE_PATH); |
|
488
|
|
|
}); |
|
489
|
|
|
|
|
490
|
|
|
/** |
|
491
|
|
|
* After successful deployment, move the tmp_env.php file to env.php ready for next deployment |
|
492
|
|
|
*/ |
|
493
|
|
|
desc('Cleanup cache id_prefix env files'); |
|
494
|
|
|
task('magento:cleanup_cache_prefix', function () { |
|
495
|
|
|
run('rm {{deploy_path}}/shared/' . ENV_CONFIG_FILE_PATH); |
|
496
|
|
|
run('rm {{release_or_current_path}}/' . ENV_CONFIG_FILE_PATH); |
|
497
|
|
|
run('mv {{deploy_path}}/shared/' . TMP_ENV_CONFIG_FILE_PATH . ' {{deploy_path}}/shared/' . ENV_CONFIG_FILE_PATH); |
|
498
|
|
|
// Symlink shared dir to release dir |
|
499
|
|
|
run('{{bin/symlink}} {{deploy_path}}/shared/' . ENV_CONFIG_FILE_PATH . ' {{release_path}}/' . ENV_CONFIG_FILE_PATH); |
|
500
|
|
|
}); |
|
501
|
|
|
|
|
502
|
|
|
/** |
|
503
|
|
|
* Remove cron from crontab and kill running cron jobs |
|
504
|
|
|
* To use this feature, add the following to your deployer scripts: |
|
505
|
|
|
* ```php |
|
506
|
|
|
* after('magento:maintenance:enable-if-needed', 'magento:cron:stop'); |
|
507
|
|
|
* ``` |
|
508
|
|
|
*/ |
|
509
|
|
|
desc('Remove cron from crontab and kill running cron jobs'); |
|
510
|
|
|
task('magento:cron:stop', function () { |
|
511
|
|
|
if (has('previous_release')) { |
|
512
|
|
|
run('{{bin/php}} {{previous_release}}/{{magento_dir}}/bin/magento cron:remove'); |
|
513
|
|
|
} |
|
514
|
|
|
|
|
515
|
|
|
run('pgrep -U "$(id -u)" -f "bin/magento +(cron:run|queue:consumers:start)" | xargs -r kill'); |
|
516
|
|
|
}); |
|
517
|
|
|
|
|
518
|
|
|
/** |
|
519
|
|
|
* Install cron in crontab |
|
520
|
|
|
* To use this feature, add the following to your deployer scripts: |
|
521
|
|
|
* ```php |
|
522
|
|
|
* after('magento:upgrade:db', 'magento:cron:install'); |
|
523
|
|
|
* ``` |
|
524
|
|
|
*/ |
|
525
|
|
|
desc('Install cron in crontab'); |
|
526
|
|
|
task('magento:cron:install', function () { |
|
527
|
|
|
run('cd {{release_or_current_path}}'); |
|
528
|
|
|
run('{{bin/php}} {{bin/magento}} cron:install'); |
|
529
|
|
|
}); |
|
530
|
|
|
|
|
531
|
|
|
desc('Prepares an artifact on the target server'); |
|
532
|
|
|
task('artifact:prepare', [ |
|
533
|
|
|
'deploy:info', |
|
534
|
|
|
'deploy:setup', |
|
535
|
|
|
'deploy:lock', |
|
536
|
|
|
'deploy:release', |
|
537
|
|
|
'artifact:upload', |
|
538
|
|
|
'artifact:extract', |
|
539
|
|
|
'deploy:additional-shared', |
|
540
|
|
|
'deploy:shared', |
|
541
|
|
|
'deploy:writable', |
|
542
|
|
|
]); |
|
543
|
|
|
|
|
544
|
|
|
desc('Executes the tasks after artifact is released'); |
|
545
|
|
|
task('artifact:finish', [ |
|
546
|
|
|
'magento:cache:flush', |
|
547
|
|
|
'cachetool:clear:opcache', |
|
548
|
|
|
'deploy:cleanup', |
|
549
|
|
|
'deploy:unlock', |
|
550
|
|
|
'deploy:success', |
|
551
|
|
|
]); |
|
552
|
|
|
|
|
553
|
|
|
desc('Actually releases the artifact deployment'); |
|
554
|
|
|
task('artifact:deploy', [ |
|
555
|
|
|
'artifact:prepare', |
|
556
|
|
|
'magento:maintenance:enable-if-needed', |
|
557
|
|
|
'magento:config:import', |
|
558
|
|
|
'magento:upgrade:db', |
|
559
|
|
|
'magento:maintenance:disable', |
|
560
|
|
|
'deploy:symlink', |
|
561
|
|
|
'artifact:finish', |
|
562
|
|
|
]); |
|
563
|
|
|
|
|
564
|
|
|
fail('artifact:deploy', 'deploy:failed'); |
|
565
|
|
|
|