@automattic/vip 2.37.0-dev.0 → 2.38.0-dev.0
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/assets/dev-env.lando.template.yml.ejs +1 -1
- package/dist/bin/vip-app-deploy.js +251 -0
- package/dist/bin/vip-app.js +1 -1
- package/dist/bin/vip-dev-env-create.js +2 -3
- package/dist/bin/vip-dev-env-destroy.js +1 -1
- package/dist/bin/vip-dev-env-exec.js +1 -1
- package/dist/bin/vip-dev-env-import-media.js +1 -1
- package/dist/bin/vip-dev-env-import-sql.js +1 -1
- package/dist/bin/vip-dev-env-info.js +1 -1
- package/dist/bin/vip-dev-env-logs.js +1 -1
- package/dist/bin/vip-dev-env-shell.js +1 -1
- package/dist/bin/vip-dev-env-start.js +1 -1
- package/dist/bin/vip-dev-env-stop.js +1 -1
- package/dist/bin/vip-dev-env-sync-sql.js +1 -1
- package/dist/bin/vip-dev-env-update.js +1 -1
- package/dist/bin/vip-import-sql.js +1 -1
- package/dist/bin/vip-wp.js +1 -1
- package/dist/commands/dev-env-import-sql.js +18 -15
- package/dist/commands/dev-env-sync-sql.js +3 -2
- package/dist/commands/phpmyadmin.js +112 -2
- package/dist/lib/cli/command.js +28 -19
- package/dist/lib/cli/exit.js +7 -2
- package/dist/lib/cli/format.js +2 -2
- package/dist/lib/client-file-uploader.js +22 -13
- package/dist/lib/constants/dev-environment.js +2 -10
- package/dist/lib/custom-deploy/custom-deploy.js +95 -0
- package/dist/lib/dev-environment/dev-environment-cli.js +13 -5
- package/dist/lib/dev-environment/dev-environment-configuration-file.js +57 -34
- package/dist/lib/dev-environment/dev-environment-core.js +20 -7
- package/dist/lib/dev-environment/docker-utils.js +1 -1
- package/dist/lib/env.js +2 -1
- package/dist/lib/user-error.js +2 -2
- package/dist/lib/validations/custom-deploy.js +39 -0
- package/dist/lib/validations/line-by-line.js +3 -1
- package/dist/lib/validations/sql.js +1 -1
- package/docs/CHANGELOG.md +44 -0
- package/npm-shrinkwrap.json +274 -628
- package/package.json +7 -5
- package/schema.gql +20174 -0
- package/tsconfig.json +2 -2
|
@@ -4,50 +4,49 @@ exports.__esModule = true;
|
|
|
4
4
|
exports.CONFIGURATION_FILE_NAME = void 0;
|
|
5
5
|
exports.getConfigurationFileOptions = getConfigurationFileOptions;
|
|
6
6
|
exports.mergeConfigurationFileOptions = mergeConfigurationFileOptions;
|
|
7
|
-
exports.printConfigurationFile = printConfigurationFile;
|
|
8
7
|
var _chalk = _interopRequireDefault(require("chalk"));
|
|
9
8
|
var _debug = _interopRequireDefault(require("debug"));
|
|
10
|
-
var _fs = require("fs");
|
|
11
9
|
var _jsYaml = _interopRequireWildcard(require("js-yaml"));
|
|
12
10
|
var _promises = require("node:fs/promises");
|
|
13
11
|
var _nodePath = _interopRequireDefault(require("node:path"));
|
|
12
|
+
var _devEnvironmentCli = require("./dev-environment-cli");
|
|
14
13
|
var exit = _interopRequireWildcard(require("../cli/exit"));
|
|
15
14
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
16
15
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
17
16
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
18
17
|
const debug = (0, _debug.default)('@automattic/vip:bin:dev-environment');
|
|
19
|
-
const CONFIGURATION_FILE_NAME = exports.CONFIGURATION_FILE_NAME = '
|
|
18
|
+
const CONFIGURATION_FILE_NAME = exports.CONFIGURATION_FILE_NAME = 'vip-dev-env.yml';
|
|
20
19
|
async function getConfigurationFileOptions() {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
const fileExists = await (0, _promises.access)(configurationFilePath, _fs.constants.R_OK).then(() => true).catch(() => false);
|
|
24
|
-
if (fileExists) {
|
|
25
|
-
debug('Reading configuration file from:', configurationFilePath);
|
|
26
|
-
configurationFileContents = await (0, _promises.readFile)(configurationFilePath, 'utf8');
|
|
27
|
-
} else {
|
|
20
|
+
const configurationFile = await findConfigurationFile();
|
|
21
|
+
if (configurationFile === false) {
|
|
28
22
|
return {};
|
|
29
23
|
}
|
|
24
|
+
const {
|
|
25
|
+
configurationPath,
|
|
26
|
+
configurationContents
|
|
27
|
+
} = configurationFile;
|
|
30
28
|
let configurationFromFile = {};
|
|
31
29
|
try {
|
|
32
|
-
configurationFromFile = _jsYaml.default.load(
|
|
30
|
+
configurationFromFile = _jsYaml.default.load(configurationContents, {
|
|
33
31
|
// Only allow strings, arrays, and objects to be parsed from configuration file
|
|
34
32
|
// This causes number-looking values like `php: 8.1` to be parsed directly into strings
|
|
35
33
|
schema: _jsYaml.FAILSAFE_SCHEMA
|
|
36
34
|
});
|
|
37
35
|
} catch (err) {
|
|
38
|
-
const messageToShow = `Configuration file ${_chalk.default.grey(
|
|
36
|
+
const messageToShow = `Configuration file ${_chalk.default.grey(configurationPath)} could not be loaded:\n` + err.toString();
|
|
39
37
|
exit.withError(messageToShow);
|
|
40
38
|
}
|
|
41
39
|
try {
|
|
42
|
-
|
|
40
|
+
let configuration = sanitizeConfiguration(configurationFromFile, configurationPath);
|
|
41
|
+
configuration = adjustRelativePaths(configuration, configurationPath);
|
|
43
42
|
debug('Sanitized configuration from file:', configuration);
|
|
44
43
|
return configuration;
|
|
45
44
|
} catch (err) {
|
|
46
45
|
exit.withError(err instanceof Error ? err : new Error('Unknown error'));
|
|
47
46
|
}
|
|
48
47
|
}
|
|
49
|
-
function sanitizeConfiguration(configuration) {
|
|
50
|
-
const genericConfigurationError = `Configuration file ${_chalk.default.grey(
|
|
48
|
+
function sanitizeConfiguration(configuration, configurationFilePath) {
|
|
49
|
+
const genericConfigurationError = `Configuration file ${_chalk.default.grey(configurationFilePath)} is available but ` + `couldn't be loaded. Ensure there is a ${_chalk.default.cyan('configuration-version')} and ${_chalk.default.cyan('slug')} ` + `configured. For example:\n\n${_chalk.default.grey(getConfigurationFileExample())}`;
|
|
51
50
|
if (Array.isArray(configuration) || typeof configuration !== 'object') {
|
|
52
51
|
throw new Error(genericConfigurationError);
|
|
53
52
|
}
|
|
@@ -57,7 +56,7 @@ function sanitizeConfiguration(configuration) {
|
|
|
57
56
|
}
|
|
58
57
|
const validVersions = getAllConfigurationFileVersions().map(ver => _chalk.default.cyan(ver)).join(', ');
|
|
59
58
|
if (!isValidConfigurationFileVersion(version.toString())) {
|
|
60
|
-
throw new Error(`Configuration file ${_chalk.default.grey(
|
|
59
|
+
throw new Error(`Configuration file ${_chalk.default.grey(configurationFilePath)} has an invalid ` + `${_chalk.default.cyan('configuration-version')} key. Update to a supported version. For example:\n\n` + _chalk.default.grey(getConfigurationFileExample()) + `\nSupported configuration versions: ${validVersions}.\n`);
|
|
61
60
|
}
|
|
62
61
|
const stringToBooleanIfDefined = value => {
|
|
63
62
|
if (typeof value !== 'string' || !['true', 'false'].includes(value)) {
|
|
@@ -65,6 +64,9 @@ function sanitizeConfiguration(configuration) {
|
|
|
65
64
|
}
|
|
66
65
|
return value === 'true';
|
|
67
66
|
};
|
|
67
|
+
const configurationMeta = {
|
|
68
|
+
'configuration-path': configurationFilePath
|
|
69
|
+
};
|
|
68
70
|
const sanitizedConfiguration = {
|
|
69
71
|
version: version.toString(),
|
|
70
72
|
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
@@ -81,7 +83,8 @@ function sanitizeConfiguration(configuration) {
|
|
|
81
83
|
xdebug: stringToBooleanIfDefined(configuration.xdebug),
|
|
82
84
|
mailpit: stringToBooleanIfDefined(configuration.mailpit ?? configuration.mailhog),
|
|
83
85
|
'media-redirect-domain': configuration['media-redirect-domain']?.toString(),
|
|
84
|
-
photon: stringToBooleanIfDefined(configuration.photon)
|
|
86
|
+
photon: stringToBooleanIfDefined(configuration.photon),
|
|
87
|
+
meta: configurationMeta
|
|
85
88
|
};
|
|
86
89
|
|
|
87
90
|
// Remove undefined values
|
|
@@ -90,6 +93,16 @@ function sanitizeConfiguration(configuration) {
|
|
|
90
93
|
key => sanitizedConfiguration[key] === undefined && delete sanitizedConfiguration[key]);
|
|
91
94
|
return sanitizedConfiguration;
|
|
92
95
|
}
|
|
96
|
+
function adjustRelativePaths(configuration, configurationFilePath) {
|
|
97
|
+
const configurationDirectory = _nodePath.default.resolve(_nodePath.default.dirname(configurationFilePath));
|
|
98
|
+
if (configuration['app-code'] && configuration['app-code'] !== 'image') {
|
|
99
|
+
configuration['app-code'] = _nodePath.default.join(configurationDirectory, configuration['app-code']);
|
|
100
|
+
}
|
|
101
|
+
if (configuration['mu-plugins'] && configuration['mu-plugins'] !== 'image') {
|
|
102
|
+
configuration['mu-plugins'] = _nodePath.default.join(configurationDirectory, configuration['mu-plugins']);
|
|
103
|
+
}
|
|
104
|
+
return configuration;
|
|
105
|
+
}
|
|
93
106
|
function mergeConfigurationFileOptions(preselectedOptions, configurationFileOptions) {
|
|
94
107
|
// configurationFileOptions holds different parameters than present in
|
|
95
108
|
// preselectedOptions like "slug", and friendly-named parameters (e.g.
|
|
@@ -121,21 +134,28 @@ function mergeConfigurationFileOptions(preselectedOptions, configurationFileOpti
|
|
|
121
134
|
});
|
|
122
135
|
return mergedOptions;
|
|
123
136
|
}
|
|
124
|
-
function
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
137
|
+
async function findConfigurationFile() {
|
|
138
|
+
let currentPath = process.cwd();
|
|
139
|
+
const rootPath = _nodePath.default.parse(currentPath).root;
|
|
140
|
+
let depth = 0;
|
|
141
|
+
const maxDepth = 64;
|
|
142
|
+
const pathPromises = [];
|
|
143
|
+
while (currentPath !== rootPath && depth < maxDepth) {
|
|
144
|
+
const configurationPath = _nodePath.default.join(currentPath, _devEnvironmentCli.CONFIGURATION_FOLDER, CONFIGURATION_FILE_NAME);
|
|
145
|
+
pathPromises.push((0, _promises.readFile)(configurationPath, 'utf8').then(configurationContents => ({
|
|
146
|
+
configurationPath,
|
|
147
|
+
configurationContents
|
|
148
|
+
})));
|
|
149
|
+
|
|
150
|
+
// Move up one directory
|
|
151
|
+
currentPath = _nodePath.default.dirname(currentPath);
|
|
129
152
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const settingLines = [];
|
|
133
|
-
for (const [key, value] of Object.entries(configurationOptions)) {
|
|
134
|
-
settingLines.push(`${_chalk.default.cyan(key)}: ${String(value)}`);
|
|
153
|
+
// Use depth as a sanity check to avoid an infitite loop
|
|
154
|
+
depth++;
|
|
135
155
|
}
|
|
136
|
-
|
|
156
|
+
return Promise.any(pathPromises).catch(() => false);
|
|
137
157
|
}
|
|
138
|
-
const CONFIGURATION_FILE_VERSIONS = ['
|
|
158
|
+
const CONFIGURATION_FILE_VERSIONS = ['1'];
|
|
139
159
|
function getAllConfigurationFileVersions() {
|
|
140
160
|
return CONFIGURATION_FILE_VERSIONS;
|
|
141
161
|
}
|
|
@@ -148,13 +168,16 @@ function isValidConfigurationFileVersion(version) {
|
|
|
148
168
|
function getConfigurationFileExample() {
|
|
149
169
|
return `configuration-version: ${getLatestConfigurationFileVersion()}
|
|
150
170
|
slug: dev-site
|
|
171
|
+
title: Dev Site
|
|
151
172
|
php: 8.0
|
|
152
|
-
wordpress: 6.
|
|
153
|
-
app-code:
|
|
173
|
+
wordpress: 6.2
|
|
174
|
+
app-code: ../
|
|
154
175
|
mu-plugins: image
|
|
155
176
|
multisite: false
|
|
156
|
-
phpmyadmin:
|
|
157
|
-
elasticsearch:
|
|
158
|
-
xdebug:
|
|
177
|
+
phpmyadmin: false
|
|
178
|
+
elasticsearch: false
|
|
179
|
+
xdebug: false
|
|
180
|
+
mailpit: false
|
|
181
|
+
photon: false
|
|
159
182
|
`;
|
|
160
183
|
}
|
|
@@ -29,7 +29,6 @@ var _ejs = _interopRequireDefault(require("ejs"));
|
|
|
29
29
|
var _enquirer = require("enquirer");
|
|
30
30
|
var _nodeFetch = _interopRequireDefault(require("node-fetch"));
|
|
31
31
|
var _nodeFs = _interopRequireDefault(require("node:fs"));
|
|
32
|
-
var _nodeOs = _interopRequireDefault(require("node:os"));
|
|
33
32
|
var _nodePath = _interopRequireDefault(require("node:path"));
|
|
34
33
|
var _semver = _interopRequireDefault(require("semver"));
|
|
35
34
|
var _uuid = require("uuid");
|
|
@@ -53,7 +52,13 @@ const instanceDataFileName = 'instance_data.json';
|
|
|
53
52
|
const uploadPathString = 'uploads';
|
|
54
53
|
const nginxPathString = 'nginx';
|
|
55
54
|
function xdgDataDirectory() {
|
|
56
|
-
|
|
55
|
+
if (_xdgBasedir.default.data) {
|
|
56
|
+
return _xdgBasedir.default.data;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// This should not happen. If it does, this means that the system was unable to find user's home directory.
|
|
60
|
+
// If so, this does not leave us many options as to where to store the data.
|
|
61
|
+
throw new Error('Unable to determine data directory.');
|
|
57
62
|
}
|
|
58
63
|
async function startEnvironment(lando, slug, options) {
|
|
59
64
|
debug('Will start an environment', slug);
|
|
@@ -273,13 +278,17 @@ function readEnvironmentData(slug) {
|
|
|
273
278
|
instanceDataString = _nodeFs.default.readFileSync(instanceDataTargetPath, 'utf8');
|
|
274
279
|
} catch (error) {
|
|
275
280
|
const err = error;
|
|
276
|
-
throw new _userError.default(`There was an error reading file "${instanceDataTargetPath}": ${err.message}
|
|
281
|
+
throw new _userError.default(`There was an error reading file "${instanceDataTargetPath}": ${err.message}.`, {
|
|
282
|
+
cause: error
|
|
283
|
+
});
|
|
277
284
|
}
|
|
278
285
|
try {
|
|
279
286
|
instanceData = JSON.parse(instanceDataString);
|
|
280
287
|
} catch (error) {
|
|
281
288
|
const err = error;
|
|
282
|
-
throw new _userError.default(`There was an error parsing file "${instanceDataTargetPath}": ${err.message}. You may need to recreate the environment
|
|
289
|
+
throw new _userError.default(`There was an error parsing file "${instanceDataTargetPath}": ${err.message}. You may need to recreate the environment.`, {
|
|
290
|
+
cause: error
|
|
291
|
+
});
|
|
283
292
|
}
|
|
284
293
|
|
|
285
294
|
/**
|
|
@@ -334,10 +343,14 @@ async function prepareLandoEnv(instanceData, instancePath) {
|
|
|
334
343
|
await _nodeFs.default.promises.mkdir(nginxFolderPath, {
|
|
335
344
|
recursive: true
|
|
336
345
|
});
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
await _nodeFs.default.promises.copyFile(landoFileTargetPath, landoBackupFileTargetPath);
|
|
346
|
+
try {
|
|
347
|
+
await _nodeFs.default.promises.rename(landoFileTargetPath, landoBackupFileTargetPath);
|
|
340
348
|
console.log(`Backup of ${landoFileName} was created in ${landoBackupFileTargetPath}`);
|
|
349
|
+
} catch (err) {
|
|
350
|
+
// If the file doesn't exist, that's fine. Otherwise, throw the error.
|
|
351
|
+
if ('ENOENT' !== err.code) {
|
|
352
|
+
throw err;
|
|
353
|
+
}
|
|
341
354
|
}
|
|
342
355
|
await Promise.all([_nodeFs.default.promises.writeFile(landoFileTargetPath, landoFile), _nodeFs.default.promises.writeFile(nginxFileTargetPath, nginxFile), _nodeFs.default.promises.writeFile(instanceDataTargetPath, instanceDataFile)]);
|
|
343
356
|
debug(`Lando file created in ${landoFileTargetPath}`);
|
|
@@ -79,7 +79,7 @@ async function getDockerSocket() {
|
|
|
79
79
|
async function getEngineConfig(dockerHost) {
|
|
80
80
|
const opts = {};
|
|
81
81
|
if (dockerHost.startsWith('tcp://')) {
|
|
82
|
-
const split =
|
|
82
|
+
const split = /^(?:tcp:\/\/)([^:]+):(\d+)/g.exec(dockerHost);
|
|
83
83
|
if (split && split.length === 3) {
|
|
84
84
|
opts.host = split[1];
|
|
85
85
|
opts.port = split[2];
|
package/dist/lib/env.js
CHANGED
package/dist/lib/user-error.js
CHANGED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.validateDeployFileExt = validateDeployFileExt;
|
|
5
|
+
exports.validateFilename = validateFilename;
|
|
6
|
+
var _path = _interopRequireDefault(require("path"));
|
|
7
|
+
var exit = _interopRequireWildcard(require("../../lib/cli/exit"));
|
|
8
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
9
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
10
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
+
/**
|
|
12
|
+
* Check if a file has a valid extension
|
|
13
|
+
*
|
|
14
|
+
* @param {string} filename The file extension
|
|
15
|
+
* @returns {boolean} True if the extension is valid
|
|
16
|
+
*/
|
|
17
|
+
function validateDeployFileExt(filename) {
|
|
18
|
+
let ext = _path.default.extname(filename).toLowerCase();
|
|
19
|
+
if (ext === '.gz' && _path.default.extname(_path.default.basename(filename, ext)) === '.tar') {
|
|
20
|
+
ext = '.tar.gz';
|
|
21
|
+
}
|
|
22
|
+
if (!['.zip', '.tar.gz', '.tgz'].includes(ext)) {
|
|
23
|
+
exit.withError('Invalid file extension. Please provide a .zip, .tar.gz, or a .tgz file.');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Check if a file has a valid name
|
|
29
|
+
* @param {string} filename The file name
|
|
30
|
+
* @returns {boolean} True if the filename is valid
|
|
31
|
+
*/
|
|
32
|
+
function validateFilename(filename) {
|
|
33
|
+
const re = /^[a-z0-9\-_.]+$/i;
|
|
34
|
+
|
|
35
|
+
// Exits if filename contains anything outside a-z A-Z - _ .
|
|
36
|
+
if (!re.test(filename)) {
|
|
37
|
+
exit.withError('Error: The characters used in the name of a file for custom deploys are limited to [0-9,a-z,A-Z,-,_,.]');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -36,7 +36,9 @@ async function fileLineValidations(appId, envId, fileName, validations, searchRe
|
|
|
36
36
|
});
|
|
37
37
|
});
|
|
38
38
|
readInterface.on('error', err => {
|
|
39
|
-
throw new Error(`
|
|
39
|
+
throw new Error(`Error validating input file: ${err.toString()}`, {
|
|
40
|
+
cause: err
|
|
41
|
+
});
|
|
40
42
|
});
|
|
41
43
|
|
|
42
44
|
// Block until the processing completes
|
|
@@ -262,7 +262,7 @@ const checks = {
|
|
|
262
262
|
siteHomeUrl: {
|
|
263
263
|
matcher: "'(siteurl|home)',\\s?'(.*?)'",
|
|
264
264
|
matchHandler: (lineNumber, results) => ({
|
|
265
|
-
text: results[1]
|
|
265
|
+
text: results[1] + ' ' + results[2]
|
|
266
266
|
}),
|
|
267
267
|
outputFormatter: infoCheckFormatter,
|
|
268
268
|
results: [],
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,49 @@
|
|
|
1
1
|
## Changelog
|
|
2
2
|
|
|
3
|
+
### 2.37.0
|
|
4
|
+
|
|
5
|
+
- build(deps-dev): bump the babel group with 2 updates
|
|
6
|
+
- build(deps): bump @automattic/vip-search-replace from 1.1.1 to 1.1.2
|
|
7
|
+
- build(deps): bump Automattic/vip-actions from 0.2.0 to 0.3.0
|
|
8
|
+
- build(deps): bump github/codeql-action from 2 to 3
|
|
9
|
+
- BYOR: Add `vip app deploy`
|
|
10
|
+
- build(deps-dev): bump eslint from 8.55.0 to 8.56.0
|
|
11
|
+
- Dev-env: Remove 8.0 & 7.4 from available PHP versions
|
|
12
|
+
- build(deps): bump open from 9.1.0 to 10.0.0
|
|
13
|
+
- fix(dev-env): use the latest nginx image
|
|
14
|
+
- build(deps-dev): bump dockerode from 4.0.0 to 4.0.1
|
|
15
|
+
- build(deps): bump open from 10.0.0 to 10.0.1
|
|
16
|
+
- build(deps-dev): bump dockerode from 4.0.1 to 4.0.2
|
|
17
|
+
- build(deps): bump open from 10.0.1 to 10.0.2
|
|
18
|
+
- fix(validate-sql): Display matched site-urls
|
|
19
|
+
- build(deps): bump socket.io-client from 4.7.2 to 4.7.3
|
|
20
|
+
- build(deps-dev): bump the babel group with 2 updates
|
|
21
|
+
- build(deps): bump open from 10.0.2 to 10.0.3
|
|
22
|
+
- feat: show detailed error information in debug mode
|
|
23
|
+
- build(deps-dev): bump the babel group with 1 update
|
|
24
|
+
- fix: issues found by SonarCloud
|
|
25
|
+
- build(deps-dev): bump @types/node from 18.19.5 to 18.19.6
|
|
26
|
+
- chore(deps): fix CVE-2023-26159 in follow-redirects
|
|
27
|
+
- build(deps): bump Automattic/vip-actions from 0.3.0 to 0.5.0
|
|
28
|
+
- build(deps): bump @automattic/vip-search-replace from 1.1.2 to 1.1.3
|
|
29
|
+
- fix: Properly propagate quotes
|
|
30
|
+
- fix(--format=json): Do not print header if specified format is json
|
|
31
|
+
- feat(dev-env): add quiet mode for "import sql"
|
|
32
|
+
- build(deps): bump socket.io-client from 4.7.3 to 4.7.4
|
|
33
|
+
- fix: regex vulnerable to super-linear runtime
|
|
34
|
+
- ci: add CodeQL workflow
|
|
35
|
+
- ci: remove outdated CodeQL workflow
|
|
36
|
+
- BYOR: Change manual-deploy to custom-deploy
|
|
37
|
+
- build(deps-dev): bump @types/node from 18.19.6 to 18.19.8
|
|
38
|
+
- build(deps-dev): bump nock from 13.4.0 to 13.5.0
|
|
39
|
+
- fix(dev-env): CWE-367 in `prepareLandoEnv()`
|
|
40
|
+
- fix(dev-env): CWE-367 in `getConfigurationFileOptions()`
|
|
41
|
+
- fix(dev-env): CWE-377, CWE-378 originating from `xdgDataDirectory()`
|
|
42
|
+
- build(deps): bump Automattic/vip-actions from 0.5.0 to 0.6.0
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
**Full Changelog**: https://github.com/Automattic/vip-cli/compare/2.36.3...v2.37.0
|
|
46
|
+
|
|
3
47
|
### 2.36.3
|
|
4
48
|
|
|
5
49
|
- build(deps): bump @json2csv/plainjs from 7.0.3 to 7.0.4
|