@automattic/vip 3.17.1 → 3.19.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-config-envvar-delete.js +1 -0
- package/dist/bin/vip-config-envvar-get-all.js +2 -1
- package/dist/bin/vip-config-envvar-get.js +1 -0
- package/dist/bin/vip-config-envvar-list.js +2 -1
- package/dist/bin/vip-config-envvar-set.js +1 -0
- package/dist/bin/vip-dev-env-envvar-delete.js +55 -0
- package/dist/bin/vip-dev-env-envvar-get-all.js +51 -0
- package/dist/bin/vip-dev-env-envvar-get.js +43 -0
- package/dist/bin/vip-dev-env-envvar-list.js +46 -0
- package/dist/bin/vip-dev-env-envvar-set.js +78 -0
- package/dist/bin/vip-dev-env-envvar.js +27 -0
- package/dist/bin/vip-dev-env.js +1 -1
- package/dist/bin/vip-import-media.js +1 -1
- package/dist/bin/vip-import-sql.js +5 -20
- package/dist/bin/vip-logs.js +1 -0
- package/dist/bin/vip-slowlogs.js +1 -0
- package/dist/bin/vip.js +1 -1
- package/dist/commands/backup-db.js +2 -5
- package/dist/commands/dev-env-sync-sql.js +13 -4
- package/dist/commands/phpmyadmin.js +2 -5
- package/dist/commands/wp-ssh.js +3 -5
- package/dist/lib/analytics/clients/pendo.js +3 -1
- package/dist/lib/analytics/clients/tracks.js +0 -1
- package/dist/lib/analytics/index.js +0 -1
- package/dist/lib/api/http.js +2 -0
- package/dist/lib/api/user.js +1 -0
- package/dist/lib/backup-storage-availability/backup-storage-availability.js +0 -1
- package/dist/lib/cli/format.js +1 -22
- package/dist/lib/custom-deploy/custom-deploy.js +2 -2
- package/dist/lib/database.js +6 -6
- package/dist/lib/dev-environment/dev-environment-cli.js +7 -5
- package/dist/lib/dev-environment/dev-environment-core.js +9 -4
- package/dist/lib/dev-environment/dev-environment-database.js +4 -0
- package/dist/lib/dev-environment/dev-environment-lando.js +37 -17
- package/dist/lib/dev-environment/env-vars.js +75 -0
- package/dist/lib/keychain/insecure.js +0 -1
- package/dist/lib/media-import/config.js +1 -1
- package/dist/lib/site-import/status.js +2 -7
- package/dist/lib/validations/is-multisite-domain-mapped.js +3 -2
- package/dist/lib/validations/line-by-line.js +1 -1
- package/docs/CHANGELOG.md +55 -0
- package/npm-shrinkwrap.json +3623 -3854
- package/package.json +18 -15
- package/dist/bin/vip-validate-preflight.js +0 -481
- package/dist/bin/vip-validate.js +0 -11
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automattic/vip",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.19.0",
|
|
4
4
|
"description": "The VIP Javascript library & CLI",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -29,6 +29,12 @@
|
|
|
29
29
|
"vip-dev-env-create": "dist/bin/vip-dev-env-create.js",
|
|
30
30
|
"vip-dev-env-update": "dist/bin/vip-dev-env-update.js",
|
|
31
31
|
"vip-dev-env-destroy": "dist/bin/vip-dev-env-destroy.js",
|
|
32
|
+
"vip-dev-env-envvar": "dist/bin/vip-dev-env-envvar.js",
|
|
33
|
+
"vip-dev-env-envvar-delete": "dist/bin/vip-dev-env-envvar-delete.js",
|
|
34
|
+
"vip-dev-env-envvar-get": "dist/bin/vip-dev-env-envvar-get.js",
|
|
35
|
+
"vip-dev-env-envvar-get-all": "dist/bin/vip-dev-env-envvar-get-all.js",
|
|
36
|
+
"vip-dev-env-envvar-list": "dist/bin/vip-dev-env-envvar-list.js",
|
|
37
|
+
"vip-dev-env-envvar-set": "dist/bin/vip-dev-env-envvar-set.js",
|
|
32
38
|
"vip-dev-env-exec": "dist/bin/vip-dev-env-exec.js",
|
|
33
39
|
"vip-dev-env-import": "dist/bin/vip-dev-env-import.js",
|
|
34
40
|
"vip-dev-env-import-media": "dist/bin/vip-dev-env-import-media.js",
|
|
@@ -56,8 +62,6 @@
|
|
|
56
62
|
"vip-search-replace": "dist/bin/vip-search-replace.js",
|
|
57
63
|
"vip-slowlogs": "dist/bin/vip-slowlogs.js",
|
|
58
64
|
"vip-sync": "dist/bin/vip-sync.js",
|
|
59
|
-
"vip-validate": "dist/bin/vip-validate.js",
|
|
60
|
-
"vip-validate-preflight": "dist/bin/vip-validate-preflight.js",
|
|
61
65
|
"vip-whoami": "dist/bin/vip-whoami.js",
|
|
62
66
|
"vip-wp": "dist/bin/vip-wp.js",
|
|
63
67
|
"vip-logout": "dist/bin/vip-logout.js"
|
|
@@ -108,21 +112,21 @@
|
|
|
108
112
|
"homepage": "https://github.com/Automattic/vip#readme",
|
|
109
113
|
"devDependencies": {
|
|
110
114
|
"@automattic/eslint-plugin-wpvip": "0.13.1",
|
|
111
|
-
"@babel/cli": "7.
|
|
112
|
-
"@babel/core": "7.
|
|
113
|
-
"@babel/preset-env": "7.
|
|
115
|
+
"@babel/cli": "7.28.0",
|
|
116
|
+
"@babel/core": "7.28.0",
|
|
117
|
+
"@babel/preset-env": "7.28.0",
|
|
114
118
|
"@babel/preset-typescript": "7.27.1",
|
|
115
|
-
"@jest/globals": "^
|
|
116
|
-
"@jest/test-sequencer": "^
|
|
119
|
+
"@jest/globals": "^30.0.0",
|
|
120
|
+
"@jest/test-sequencer": "^30.0.0",
|
|
117
121
|
"@types/args": "^5.0.3",
|
|
118
122
|
"@types/cli-table": "^0.3.4",
|
|
119
123
|
"@types/configstore": "5.0.1",
|
|
120
124
|
"@types/debug": "^4.1.12",
|
|
121
125
|
"@types/dockerode": "^3.3.23",
|
|
122
126
|
"@types/ejs": "^3.1.5",
|
|
123
|
-
"@types/jest": "^
|
|
127
|
+
"@types/jest": "^30.0.0",
|
|
124
128
|
"@types/js-yaml": "^4.0.9",
|
|
125
|
-
"@types/node": "^
|
|
129
|
+
"@types/node": "^24.0.0",
|
|
126
130
|
"@types/node-fetch": "^2.6.9",
|
|
127
131
|
"@types/proxy-from-env": "^1.0.4",
|
|
128
132
|
"@types/semver": "^7.5.5",
|
|
@@ -133,7 +137,7 @@
|
|
|
133
137
|
"@types/xml2js": "^0.4.14",
|
|
134
138
|
"dockerode": "^4.0.0",
|
|
135
139
|
"eslint": "^8.35.0",
|
|
136
|
-
"jest": "^
|
|
140
|
+
"jest": "^30.0.0",
|
|
137
141
|
"nock": "13.5.6",
|
|
138
142
|
"prettier": "npm:wp-prettier@2.8.5",
|
|
139
143
|
"rimraf": "6.0.1",
|
|
@@ -141,7 +145,6 @@
|
|
|
141
145
|
},
|
|
142
146
|
"dependencies": {
|
|
143
147
|
"@apollo/client": "3.3.6",
|
|
144
|
-
"@automattic/vip-go-preflight-checks": "^2.0.16",
|
|
145
148
|
"@automattic/vip-search-replace": "^1.1.1",
|
|
146
149
|
"@json2csv/plainjs": "^7.0.3",
|
|
147
150
|
"@wwa/single-line-log": "^1.1.4",
|
|
@@ -157,11 +160,11 @@
|
|
|
157
160
|
"fetch-retry": "^6.0.0",
|
|
158
161
|
"graphql": "15.5.1",
|
|
159
162
|
"graphql-tag": "2.12.6",
|
|
160
|
-
"https-proxy-agent": "^
|
|
163
|
+
"https-proxy-agent": "^7.0.6",
|
|
161
164
|
"ini": "5.0.0",
|
|
162
165
|
"js-yaml": "^4.1.0",
|
|
163
166
|
"jwt-decode": "4.0.0",
|
|
164
|
-
"lando": "github:automattic/lando-cli#
|
|
167
|
+
"lando": "github:automattic/lando-cli#25136fb80684743276239e2ee155080f3056790c",
|
|
165
168
|
"node-fetch": "^2.6.1",
|
|
166
169
|
"node-stream-zip": "1.15.0",
|
|
167
170
|
"open": "^10.0.0",
|
|
@@ -170,7 +173,7 @@
|
|
|
170
173
|
"shelljs": "^0.10.0",
|
|
171
174
|
"socket.io-client": "^4.5.3",
|
|
172
175
|
"socket.io-stream": "npm:@wearemothership/socket.io-stream@^0.9.1",
|
|
173
|
-
"socks-proxy-agent": "^
|
|
176
|
+
"socks-proxy-agent": "^8.0.5",
|
|
174
177
|
"ssh2": "1.16.0",
|
|
175
178
|
"tar": "^7.4.0",
|
|
176
179
|
"update-notifier": "7.3.1",
|
|
@@ -1,481 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
|
|
4
|
-
exports.__esModule = true;
|
|
5
|
-
exports.appQuery = void 0;
|
|
6
|
-
exports.vipValidatePreflightCommand = vipValidatePreflightCommand;
|
|
7
|
-
var _vipGoPreflightChecks = require("@automattic/vip-go-preflight-checks");
|
|
8
|
-
var _chalk = _interopRequireDefault(require("chalk"));
|
|
9
|
-
var _enquirer = require("enquirer");
|
|
10
|
-
var _fs = require("fs");
|
|
11
|
-
var _graphqlTag = _interopRequireDefault(require("graphql-tag"));
|
|
12
|
-
var _ini = _interopRequireDefault(require("ini"));
|
|
13
|
-
var _path = _interopRequireDefault(require("path"));
|
|
14
|
-
var _api = _interopRequireWildcard(require("../lib/api"));
|
|
15
|
-
var _command = _interopRequireDefault(require("../lib/cli/command"));
|
|
16
|
-
var _envAlias = require("../lib/cli/envAlias");
|
|
17
|
-
var exit = _interopRequireWildcard(require("../lib/cli/exit"));
|
|
18
|
-
var _tracker = require("../lib/tracker");
|
|
19
|
-
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
20
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
21
|
-
const ALLOWED_NODEJS_VERSIONS = ['18', '20', '22'];
|
|
22
|
-
const appQuery = exports.appQuery = `
|
|
23
|
-
id
|
|
24
|
-
name
|
|
25
|
-
repo
|
|
26
|
-
environments {
|
|
27
|
-
id
|
|
28
|
-
appId
|
|
29
|
-
name
|
|
30
|
-
type
|
|
31
|
-
environmentVariables {
|
|
32
|
-
nodes {
|
|
33
|
-
name,
|
|
34
|
-
value
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
organization {
|
|
39
|
-
id
|
|
40
|
-
name
|
|
41
|
-
}
|
|
42
|
-
`;
|
|
43
|
-
let suppressOutput = false;
|
|
44
|
-
let outputFormat = 'table';
|
|
45
|
-
let harmoniaArgs = [];
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* @param {string[]} messages
|
|
49
|
-
*/
|
|
50
|
-
function logToConsole(...messages) {
|
|
51
|
-
if (suppressOutput) {
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
if (messages.length === 0) {
|
|
55
|
-
messages = [''];
|
|
56
|
-
}
|
|
57
|
-
messages.forEach(message => console.log(message));
|
|
58
|
-
}
|
|
59
|
-
async function getBuildConfiguration(application, environment) {
|
|
60
|
-
const api = (0, _api.default)();
|
|
61
|
-
|
|
62
|
-
// Disable the global GraphQL error handling, so we can catch Unauthorized errors and recommend next steps.
|
|
63
|
-
(0, _api.disableGlobalGraphQLErrorHandling)();
|
|
64
|
-
const buildConfigQuery = (0, _graphqlTag.default)`
|
|
65
|
-
query BuildConfig($appId: Int, $envId: Int) {
|
|
66
|
-
app(id: $appId) {
|
|
67
|
-
environments(id: $envId) {
|
|
68
|
-
id
|
|
69
|
-
buildConfiguration {
|
|
70
|
-
buildType
|
|
71
|
-
nodeBuildDockerEnv
|
|
72
|
-
nodeJSVersion
|
|
73
|
-
npmToken
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
`;
|
|
79
|
-
try {
|
|
80
|
-
const result = await api.query({
|
|
81
|
-
query: buildConfigQuery,
|
|
82
|
-
fetchPolicy: 'network-only',
|
|
83
|
-
variables: {
|
|
84
|
-
appId: environment.appId,
|
|
85
|
-
envId: environment.id
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
// Reenable GraphQL error handling
|
|
90
|
-
(0, _api.enableGlobalGraphQLErrorHandling)();
|
|
91
|
-
return result.data.app.environments[0].buildConfiguration;
|
|
92
|
-
} catch (error) {
|
|
93
|
-
if (error.graphQLErrors && error.graphQLErrors.find(gqlError => gqlError.message === 'Unauthorized')) {
|
|
94
|
-
console.log(`${_chalk.default.red('Error:')} You do not have sufficient permissions to run validations for this environment.\n` + `You must be either be an admin of the ${_chalk.default.bold.underline(application.organization.name)} organization, or, alternatively,\n` + `a guest of that organization and an admin of the ${_chalk.default.bold.underline(application.name)} application.\n\n` + 'Read more about organization and application roles in our documentation:\n' + _chalk.default.underline('https://docs.wpvip.com/manage-user-access/vip-dashboard/'));
|
|
95
|
-
await (0, _tracker.trackEvent)('validate_preflight_command_error', {
|
|
96
|
-
env_id: environment.id,
|
|
97
|
-
app_id: environment.appId,
|
|
98
|
-
error: 'unauthorized'
|
|
99
|
-
});
|
|
100
|
-
process.exit(1);
|
|
101
|
-
} else {
|
|
102
|
-
// Handle it elsewhere
|
|
103
|
-
throw error;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* @param {string} argv
|
|
110
|
-
*/
|
|
111
|
-
async function vipValidatePreflightCommand(arg, opt) {
|
|
112
|
-
harmoniaArgs = await validateArgs(opt);
|
|
113
|
-
const appId = opt.env?.appId ?? 0;
|
|
114
|
-
const envId = opt.env?.id ?? 0;
|
|
115
|
-
const baseTrackingParams = {
|
|
116
|
-
env_id: envId,
|
|
117
|
-
app_id: appId,
|
|
118
|
-
command: 'vip validate preflight',
|
|
119
|
-
...sanitizeArgsForTracking(harmoniaArgs)
|
|
120
|
-
};
|
|
121
|
-
await (0, _tracker.trackEvent)('validate_preflight_command_execute', baseTrackingParams);
|
|
122
|
-
logToConsole(' /\\ /\\__ _ _ __ _ __ ___ ___ _ __ (_) __ _ ');
|
|
123
|
-
logToConsole(" / /_/ / _` | '__| '_ ` _ \\ / _ \\| '_ \\| |/ _` |");
|
|
124
|
-
logToConsole('/ __ / (_| | | | | | | | | (_) | | | | | (_| |');
|
|
125
|
-
logToConsole('\\/ /_/ \\__,_|_| |_| |_| |_|\\___/|_| |_|_|\\__,_|');
|
|
126
|
-
logToConsole('VIP Harmonia - Application testing made easy\n');
|
|
127
|
-
const harmonia = new _vipGoPreflightChecks.Harmonia();
|
|
128
|
-
harmonia.setSource('vip-cli');
|
|
129
|
-
if (harmoniaArgs.buildType !== 'nodejs') {
|
|
130
|
-
await (0, _tracker.trackEvent)('validate_preflight_command_error', {
|
|
131
|
-
...baseTrackingParams,
|
|
132
|
-
error: 'not-nodejs'
|
|
133
|
-
});
|
|
134
|
-
exit.withError('Currently, only Node.js applications are supported.');
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Register the default tests.
|
|
138
|
-
harmonia.registerDefaultTests();
|
|
139
|
-
|
|
140
|
-
// Create the Site Config objects
|
|
141
|
-
const siteOptions = new _vipGoPreflightChecks.SiteConfig({
|
|
142
|
-
siteID: envId,
|
|
143
|
-
nodejsVersion: harmoniaArgs.nodejsVersion,
|
|
144
|
-
repository: opt.app?.repo ?? 'no-repo',
|
|
145
|
-
baseURL: 'http://localhost:' + harmoniaArgs.port,
|
|
146
|
-
dockerBuildEnvs: harmoniaArgs.nodeBuildDockerEnv,
|
|
147
|
-
topRequests: [],
|
|
148
|
-
// TODO: get top 10 of most requested URLs
|
|
149
|
-
wait: harmoniaArgs.wait
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
// Get package.json
|
|
153
|
-
const packageJSONfile = _path.default.resolve(opt.path, 'package.json');
|
|
154
|
-
let packageJSON;
|
|
155
|
-
try {
|
|
156
|
-
// eslint-disable-next-line security/detect-non-literal-require
|
|
157
|
-
packageJSON = require(packageJSONfile);
|
|
158
|
-
siteOptions.setPackageJSON(packageJSON);
|
|
159
|
-
} catch (error) {
|
|
160
|
-
await (0, _tracker.trackEvent)('validate_preflight_command_error', {
|
|
161
|
-
...baseTrackingParams,
|
|
162
|
-
error: 'missing-package-json'
|
|
163
|
-
});
|
|
164
|
-
return exit.withError(`Could not find a 'package.json' in the current directory (${opt.path}).`);
|
|
165
|
-
}
|
|
166
|
-
const customEnvVars = {};
|
|
167
|
-
if (opt.env?.environmentVariables?.nodes.length > 0) {
|
|
168
|
-
opt.env.environmentVariables.nodes.forEach(envVar => {
|
|
169
|
-
customEnvVars[envVar.name] = envVar.value;
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Create the EnviornmentVariables object
|
|
174
|
-
const envVars = new _vipGoPreflightChecks.EnvironmentVariables({
|
|
175
|
-
PORT: harmoniaArgs.port,
|
|
176
|
-
...customEnvVars
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
// Add NPM_TOKEN environment variable, if present
|
|
180
|
-
if (harmoniaArgs.npmToken) {
|
|
181
|
-
envVars.set('NPM_TOKEN', harmoniaArgs.npmToken);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// Get from .env, if exists
|
|
185
|
-
let dotenvOptions = {};
|
|
186
|
-
try {
|
|
187
|
-
const dotenvPath = _path.default.resolve(opt.path, '.env');
|
|
188
|
-
const dotenvContent = (0, _fs.readFileSync)(dotenvPath);
|
|
189
|
-
dotenvOptions = _ini.default.parse(dotenvContent);
|
|
190
|
-
} catch (error) {
|
|
191
|
-
// nothing
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// Save dotenv in the site config
|
|
195
|
-
siteOptions.set('dotenv', dotenvOptions);
|
|
196
|
-
|
|
197
|
-
// Bootstrap
|
|
198
|
-
try {
|
|
199
|
-
harmonia.bootstrap(siteOptions, envVars);
|
|
200
|
-
} catch (error) {
|
|
201
|
-
await (0, _tracker.trackEvent)('validate_preflight_command_error', {
|
|
202
|
-
...baseTrackingParams,
|
|
203
|
-
error: error.message
|
|
204
|
-
});
|
|
205
|
-
return exit.withError(error.message);
|
|
206
|
-
}
|
|
207
|
-
setupEvents(harmonia);
|
|
208
|
-
runHarmonia(harmonia);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* @param {Harmonia} harmonia
|
|
213
|
-
*/
|
|
214
|
-
function setupEvents(harmonia) {
|
|
215
|
-
// Register some events handlers
|
|
216
|
-
harmonia.on('ready', () => {
|
|
217
|
-
logToConsole('Harmonia is ready! ');
|
|
218
|
-
});
|
|
219
|
-
|
|
220
|
-
// Register the event handlers to output some information during the execution
|
|
221
|
-
harmonia.on('beforeTestSuite', suite => {
|
|
222
|
-
const description = suite.description ? `- ${_chalk.default.italic(suite.description)}` : '';
|
|
223
|
-
logToConsole(` >> Running test suite ${_chalk.default.bold(suite.name)} ${description} `);
|
|
224
|
-
logToConsole();
|
|
225
|
-
});
|
|
226
|
-
harmonia.on('beforeTest', test => {
|
|
227
|
-
logToConsole(` [ ${_chalk.default.bold(test.name)} ] - ${test.description}`);
|
|
228
|
-
});
|
|
229
|
-
harmonia.on('afterTest', (test, result) => {
|
|
230
|
-
switch (result.getType()) {
|
|
231
|
-
case _vipGoPreflightChecks.TestResultType.Success:
|
|
232
|
-
logToConsole(` ✅ ${_chalk.default.bgGreen(' Test passed with no errors. ')}`);
|
|
233
|
-
break;
|
|
234
|
-
case _vipGoPreflightChecks.TestResultType.Failed:
|
|
235
|
-
logToConsole(` ❌ ${_chalk.default.bgRed(` Test failed with ${result.getErrors().length} errors. `)}`);
|
|
236
|
-
break;
|
|
237
|
-
case _vipGoPreflightChecks.TestResultType.PartialSuccess:
|
|
238
|
-
logToConsole(` ✅ ${_chalk.default.bgYellow(' Test partially succeeded. ')}`);
|
|
239
|
-
break;
|
|
240
|
-
case _vipGoPreflightChecks.TestResultType.Aborted:
|
|
241
|
-
logToConsole(` ❌ ${_chalk.default.bgRedBright.underline(' Test aborted! ')} - There was a critical error that makes`, 'the application incompatible with the VIP Platform.');
|
|
242
|
-
break;
|
|
243
|
-
case _vipGoPreflightChecks.TestResultType.Skipped:
|
|
244
|
-
logToConsole(` ${_chalk.default.bgGrey.bold(' Skipped ')}\t${result.getLastNotice().message}`);
|
|
245
|
-
}
|
|
246
|
-
logToConsole();
|
|
247
|
-
});
|
|
248
|
-
harmonia.on('afterTestSuite', (test, result) => {
|
|
249
|
-
// Create a badge
|
|
250
|
-
let badge;
|
|
251
|
-
switch (result.getType()) {
|
|
252
|
-
case _vipGoPreflightChecks.TestResultType.Failed:
|
|
253
|
-
badge = _chalk.default.bgRed.bold(' FAILED ');
|
|
254
|
-
break;
|
|
255
|
-
case _vipGoPreflightChecks.TestResultType.Aborted:
|
|
256
|
-
badge = _chalk.default.bgRedBright.underline.bold(' ABORTED ');
|
|
257
|
-
break;
|
|
258
|
-
case _vipGoPreflightChecks.TestResultType.PartialSuccess:
|
|
259
|
-
badge = _chalk.default.bgYellow.bold(' PASS ');
|
|
260
|
-
break;
|
|
261
|
-
default:
|
|
262
|
-
badge = _chalk.default.bgGreen.bold(' PASS ');
|
|
263
|
-
break;
|
|
264
|
-
}
|
|
265
|
-
logToConsole(` >> ${badge} Finished running ${_chalk.default.bold(test.name)} suite`);
|
|
266
|
-
logToConsole();
|
|
267
|
-
});
|
|
268
|
-
harmonia.on('issue', issue => {
|
|
269
|
-
let issueTypeString = issue.getTypeString();
|
|
270
|
-
switch (issue.type) {
|
|
271
|
-
case _vipGoPreflightChecks.IssueType.Blocker:
|
|
272
|
-
issueTypeString = _chalk.default.bgRedBright.underline.bold(issueTypeString);
|
|
273
|
-
break;
|
|
274
|
-
case _vipGoPreflightChecks.IssueType.Error:
|
|
275
|
-
issueTypeString = _chalk.default.bgRed.bold(issueTypeString);
|
|
276
|
-
break;
|
|
277
|
-
case _vipGoPreflightChecks.IssueType.Warning:
|
|
278
|
-
issueTypeString = _chalk.default.bgYellow.bold(issueTypeString);
|
|
279
|
-
break;
|
|
280
|
-
case _vipGoPreflightChecks.IssueType.Notice:
|
|
281
|
-
issueTypeString = _chalk.default.bgGray.bold(issueTypeString);
|
|
282
|
-
break;
|
|
283
|
-
}
|
|
284
|
-
const documentation = issue.documentation ? `(${issue.documentation})` : '';
|
|
285
|
-
|
|
286
|
-
// Replace \n with \n\t\t to keep new lines aligned
|
|
287
|
-
const message = issue.message.replace(/\n/g, '\n\t\t');
|
|
288
|
-
logToConsole(` ${issueTypeString} \t${message} ${documentation}`);
|
|
289
|
-
|
|
290
|
-
// If it's a Blocker or Error, and the issue includes a stdout, print it out.
|
|
291
|
-
const issueData = issue.getData();
|
|
292
|
-
if (issueData && [_vipGoPreflightChecks.IssueType.Blocker, _vipGoPreflightChecks.IssueType.Error].includes(issue.type)) {
|
|
293
|
-
if (issueData.all) {
|
|
294
|
-
logToConsole(issueData.all);
|
|
295
|
-
logToConsole();
|
|
296
|
-
} else if (typeof issueData === 'string') {
|
|
297
|
-
logToConsole(issueData);
|
|
298
|
-
logToConsole();
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
function runHarmonia(harmonia) {
|
|
304
|
-
harmonia.run().then(async results => await handleResults(harmonia, results));
|
|
305
|
-
}
|
|
306
|
-
async function handleResults(harmonia, results) {
|
|
307
|
-
// Calculate the results
|
|
308
|
-
const resultCounter = harmonia.countResults(false);
|
|
309
|
-
const testSuiteResults = results.filter(result => result instanceof _vipGoPreflightChecks.TestSuiteResult);
|
|
310
|
-
|
|
311
|
-
// Send success event
|
|
312
|
-
await (0, _tracker.trackEvent)('validate_preflight_command_success', {
|
|
313
|
-
command: 'vip validate preflight',
|
|
314
|
-
...sanitizeArgsForTracking(harmoniaArgs),
|
|
315
|
-
skipped: resultCounter[_vipGoPreflightChecks.TestResultType.Skipped],
|
|
316
|
-
success: resultCounter[_vipGoPreflightChecks.TestResultType.Success],
|
|
317
|
-
partial_success: resultCounter[_vipGoPreflightChecks.TestResultType.PartialSuccess],
|
|
318
|
-
failed: resultCounter[_vipGoPreflightChecks.TestResultType.Failed],
|
|
319
|
-
aborted: resultCounter[_vipGoPreflightChecks.TestResultType.Aborted]
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
// If the output is JSON, reenable the logToConsole output and print-out the json format.
|
|
323
|
-
if (outputFormat === 'json') {
|
|
324
|
-
suppressOutput = false;
|
|
325
|
-
logToConsole(harmonia.resultsJSON());
|
|
326
|
-
process.exit(0);
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// Print the results
|
|
330
|
-
logToConsole('\n' + _chalk.default.bgGray(' HARMONIA RESULTS \n'));
|
|
331
|
-
if (resultCounter[_vipGoPreflightChecks.TestResultType.Skipped]) {
|
|
332
|
-
logToConsole(` ${_chalk.default.bold.bgGrey(' SKIPPED ')} - ${_chalk.default.bold(resultCounter[_vipGoPreflightChecks.TestResultType.Skipped])} tests`);
|
|
333
|
-
}
|
|
334
|
-
if (resultCounter[_vipGoPreflightChecks.TestResultType.Success]) {
|
|
335
|
-
logToConsole(` ${_chalk.default.bold.bgGreen(' PASSED ')} - ${_chalk.default.bold(resultCounter[_vipGoPreflightChecks.TestResultType.Success])} tests`);
|
|
336
|
-
}
|
|
337
|
-
if (resultCounter[_vipGoPreflightChecks.TestResultType.PartialSuccess]) {
|
|
338
|
-
logToConsole(` ${_chalk.default.bold.bgYellow(' PARTIAL SUCCESS ')} - ${_chalk.default.bold(resultCounter[_vipGoPreflightChecks.TestResultType.PartialSuccess])} tests`);
|
|
339
|
-
}
|
|
340
|
-
if (resultCounter[_vipGoPreflightChecks.TestResultType.Failed]) {
|
|
341
|
-
logToConsole(` ${_chalk.default.bold.bgRed(' FAILED ')} - ${_chalk.default.bold(resultCounter[_vipGoPreflightChecks.TestResultType.Failed])} tests`);
|
|
342
|
-
}
|
|
343
|
-
if (resultCounter[_vipGoPreflightChecks.TestResultType.Aborted]) {
|
|
344
|
-
logToConsole(` ${_chalk.default.bold.bgRedBright(' ABORTED ')} - ${_chalk.default.bold(resultCounter[_vipGoPreflightChecks.TestResultType.Aborted])} tests`);
|
|
345
|
-
}
|
|
346
|
-
logToConsole();
|
|
347
|
-
logToConsole(` > Total of ${_chalk.default.bold(results.length - testSuiteResults.length)} tests have been executed.`);
|
|
348
|
-
logToConsole();
|
|
349
|
-
|
|
350
|
-
// If there is a Aborted test result
|
|
351
|
-
if (resultCounter[_vipGoPreflightChecks.TestResultType.Aborted]) {
|
|
352
|
-
logToConsole(`${_chalk.default.bold.bgRedBright(' NOT PASS ')} There was a critical failure that makes the application ` + 'incompatible with the VIP Platform. Please review the results and re-run the tests.');
|
|
353
|
-
process.exit(1);
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
// If there is only a partial success, but no failures
|
|
357
|
-
if (resultCounter[_vipGoPreflightChecks.TestResultType.PartialSuccess] && !resultCounter[_vipGoPreflightChecks.TestResultType.Failed]) {
|
|
358
|
-
logToConsole(`${_chalk.default.bold.bgYellow(' PASS ')} The application has passed the required tests, but it does not follow all of the recommendations.`);
|
|
359
|
-
logToConsole('Please review the results.');
|
|
360
|
-
process.exit(0);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// If there is a failure
|
|
364
|
-
if (resultCounter[_vipGoPreflightChecks.TestResultType.Failed]) {
|
|
365
|
-
logToConsole(`${_chalk.default.bold.bgRed(' NOT PASS ')} The application has failed some tests, and will very likely have problems on a production ` + 'environment. Please review all of the errors found in the results.');
|
|
366
|
-
process.exit(1);
|
|
367
|
-
}
|
|
368
|
-
logToConsole(`${_chalk.default.bold.bgGreen(' PASS ')} Congratulations! The application passes all of the tests.`);
|
|
369
|
-
process.exit(0);
|
|
370
|
-
}
|
|
371
|
-
async function validateArgs(opt) {
|
|
372
|
-
const args = {};
|
|
373
|
-
|
|
374
|
-
// Verbose
|
|
375
|
-
if (opt.verbose) {
|
|
376
|
-
_vipGoPreflightChecks.Harmonia.setVerbosity(true);
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
// Set path
|
|
380
|
-
if (opt.path) {
|
|
381
|
-
_vipGoPreflightChecks.Harmonia.setCwd(opt.path);
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
// If the JSON option is enabled, all the stdout should be suppressed to prevent polluting the output.
|
|
385
|
-
if (opt.format === 'json') {
|
|
386
|
-
suppressOutput = true;
|
|
387
|
-
outputFormat = 'json';
|
|
388
|
-
}
|
|
389
|
-
if (opt.app) {
|
|
390
|
-
// Get build information from API and store it in the env object
|
|
391
|
-
const buildConfig = await getBuildConfiguration(opt.app, opt.env);
|
|
392
|
-
args.app_id = opt.app.id;
|
|
393
|
-
args.env_id = opt.env.id;
|
|
394
|
-
args.nodejsVersion = opt.nodeVersion ?? buildConfig.nodeJSVersion;
|
|
395
|
-
args.buildType = buildConfig.buildType;
|
|
396
|
-
args.npmToken = buildConfig.npmToken;
|
|
397
|
-
args.nodeBuildDockerEnv = buildConfig.nodeBuildDockerEnv;
|
|
398
|
-
} else {
|
|
399
|
-
args.app_id = 0;
|
|
400
|
-
args.env_id = 0;
|
|
401
|
-
args.buildType = 'nodejs';
|
|
402
|
-
|
|
403
|
-
// If no node.js version is specified, prompt the user to select one
|
|
404
|
-
if (!opt.nodeVersion) {
|
|
405
|
-
// Ask for a node.js version
|
|
406
|
-
try {
|
|
407
|
-
const selection = await (0, _enquirer.prompt)({
|
|
408
|
-
type: 'select',
|
|
409
|
-
name: 'nodejsVersion',
|
|
410
|
-
message: 'Which Node.js version do you want to use?',
|
|
411
|
-
choices: ALLOWED_NODEJS_VERSIONS
|
|
412
|
-
});
|
|
413
|
-
args.nodejsVersion = selection.nodejsVersion;
|
|
414
|
-
} catch (err) {
|
|
415
|
-
exit.withError('No Node.js version selected. Aborting.');
|
|
416
|
-
}
|
|
417
|
-
} else {
|
|
418
|
-
args.nodejsVersion = opt.nodeVersion;
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
args.wait = opt.wait ?? 3000;
|
|
422
|
-
args.port = opt.port ?? Math.floor(Math.random() * 1000) + 3001; // Get a PORT from 3001 and 3999
|
|
423
|
-
|
|
424
|
-
return args;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
/**
|
|
428
|
-
* Remove sensitive information from the tracked events and snake_case the keys.
|
|
429
|
-
*
|
|
430
|
-
* @param {Object} args The arguments passed to the command.
|
|
431
|
-
* @return {Object} Copy of the arguments without sensitive information.
|
|
432
|
-
*/
|
|
433
|
-
function sanitizeArgsForTracking(args) {
|
|
434
|
-
const protectedKeys = ['npmToken', 'nodeBuildDockerEnv'];
|
|
435
|
-
const sanitizedArgs = {};
|
|
436
|
-
Object.entries(args).forEach(([key, value]) => {
|
|
437
|
-
if (protectedKeys.includes(key)) {
|
|
438
|
-
return;
|
|
439
|
-
}
|
|
440
|
-
// snake_case the key, as required by Tracks
|
|
441
|
-
sanitizedArgs[key.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`)] = value;
|
|
442
|
-
});
|
|
443
|
-
return sanitizedArgs;
|
|
444
|
-
}
|
|
445
|
-
let commandOpts = {
|
|
446
|
-
module: 'harmonia',
|
|
447
|
-
format: true
|
|
448
|
-
};
|
|
449
|
-
|
|
450
|
-
// The @app.env selector is optional, so we need to check if it was passed
|
|
451
|
-
const parsedAlias = (0, _envAlias.parseEnvAliasFromArgv)(process.argv);
|
|
452
|
-
if (parsedAlias.app) {
|
|
453
|
-
commandOpts = {
|
|
454
|
-
...commandOpts,
|
|
455
|
-
appQuery,
|
|
456
|
-
envContext: true,
|
|
457
|
-
appContext: true
|
|
458
|
-
};
|
|
459
|
-
} else {
|
|
460
|
-
logToConsole(_chalk.default.bold.yellow('Warning: ') + 'The preflight tests are running without a provided application and/or environment.\n' + 'Some app-dependent configurations, such as environment variables, might not be defined.');
|
|
461
|
-
}
|
|
462
|
-
const usage = 'vip validate preflight';
|
|
463
|
-
(0, _command.default)({
|
|
464
|
-
commandOpts,
|
|
465
|
-
usage
|
|
466
|
-
}).option('verbose', 'Increase logging level to include app build and server boot up messages.', false).option('node-version', `Set a version of Node.js for the tests. Accepts semver format (MAJOR.MINOR.PATCH) or a MAJOR (${ALLOWED_NODEJS_VERSIONS.join(', ')}).`).option('wait', 'Set the number of milliseconds to delay the start of the tests. Only necessary if an application requires a greater amount of time to start.', 3000).option(['p', 'port'], 'Set a port for the application. (Defaults to a random value between 3001 and 3999)').option(['P', 'path'], 'Path to the app to be tested', process.cwd()).examples([{
|
|
467
|
-
usage: 'vip validate preflight',
|
|
468
|
-
description: 'Run the validate command from within the root of the local Node.js codebase directory.'
|
|
469
|
-
}, {
|
|
470
|
-
usage: 'vip validate preflight --path=/Users/example/Desktop/example-node-repo',
|
|
471
|
-
description: 'Run the validate command against a Node.js application directory at a specific local path.'
|
|
472
|
-
}, {
|
|
473
|
-
usage: 'vip @example-node-app.production validate preflight --node-version=20',
|
|
474
|
-
description: 'Run the validation tests with a specific version of Node.js.'
|
|
475
|
-
}, {
|
|
476
|
-
usage: 'vip validate preflight --format=json > results.json',
|
|
477
|
-
description: 'Output the results of the validation tests to a local file in JSON format.'
|
|
478
|
-
}, {
|
|
479
|
-
usage: 'vip @example-node-app.production validate preflight',
|
|
480
|
-
description: 'Run the validation tests with settings based on a targeted VIP Platform environment.'
|
|
481
|
-
}]).argv(process.argv, vipValidatePreflightCommand);
|
package/dist/bin/vip-validate.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
|
|
4
|
-
var _command = _interopRequireDefault(require("../lib/cli/command"));
|
|
5
|
-
var _tracker = require("../lib/tracker");
|
|
6
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
-
(0, _command.default)({
|
|
8
|
-
requiredArgs: 0
|
|
9
|
-
}).command('preflight', 'Run a full suite of validation tests against a local Node.js codebase to identify potential issues that could prevent successful building or deploying.').argv(process.argv, async () => {
|
|
10
|
-
await (0, _tracker.trackEvent)('vip_validate_command_execute');
|
|
11
|
-
});
|