wp-blank-scripts 4.0.0-alpha.2 → 4.0.0-alpha.4
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/lib/deployProject.js +70 -107
- package/package.json +1 -2
- package/webpack.base.config.js +3 -2
- package/utils/tunnelSsh.js +0 -134
package/lib/deployProject.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
const
|
|
3
|
+
const ora = require('ora');
|
|
4
4
|
const Rsync = require('rsync');
|
|
5
5
|
const { rimraf } = require('rimraf');
|
|
6
6
|
|
|
7
7
|
const exportSql = require('./exportSQL');
|
|
8
8
|
const cleanShellPath = require('../utils/cleanShellPath');
|
|
9
|
-
const tunnel = require('../utils/tunnelSsh');
|
|
10
9
|
const git = require('../utils/git');
|
|
10
|
+
const _ssh2 = require('ssh2');
|
|
11
|
+
const SSH2Client = _ssh2.Client || _ssh2;
|
|
11
12
|
const runProjectBuildTask = require('../utils/runProjectBuildTask');
|
|
12
13
|
const bumpVersion = require('../utils/bumpVersion');
|
|
13
14
|
const execAsync = require('../utils/execAsync');
|
|
@@ -15,7 +16,6 @@ const { DEPLOY_MODES } = require('../constants');
|
|
|
15
16
|
const getProjectPath = require('../utils/getProjectPath');
|
|
16
17
|
const getSettings = require('../utils/projectSettings');
|
|
17
18
|
const logger = require('../logger');
|
|
18
|
-
const replaceSQL = require('../utils/replaceSQL');
|
|
19
19
|
|
|
20
20
|
// Default options
|
|
21
21
|
const defaultOptions = {
|
|
@@ -24,9 +24,6 @@ const defaultOptions = {
|
|
|
24
24
|
mySQLPort: 3306,
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
let m;
|
|
28
|
-
let t;
|
|
29
|
-
|
|
30
27
|
let options;
|
|
31
28
|
let settings;
|
|
32
29
|
let deployModeOptions;
|
|
@@ -61,44 +58,86 @@ function setDeployModeOptions(deployBuildDir) {
|
|
|
61
58
|
};
|
|
62
59
|
}
|
|
63
60
|
|
|
64
|
-
async function
|
|
65
|
-
// Get server access info
|
|
61
|
+
async function deployMySQLviaSSH(file) {
|
|
66
62
|
const server = settings.server[options.environment];
|
|
67
63
|
const serverPassword = options.serverPassword;
|
|
68
|
-
|
|
69
|
-
const { tunnelHost, tunnelPort, mySQLPort } = options;
|
|
64
|
+
const { user: dbUser, password: dbPassword, database } = settings.mysql[options.environment];
|
|
70
65
|
|
|
71
66
|
let serverPrivateKey;
|
|
72
67
|
if (options.serverPrivateKey) {
|
|
73
68
|
serverPrivateKey = fs.readFileSync(cleanShellPath(options.serverPrivateKey));
|
|
74
69
|
}
|
|
75
70
|
|
|
76
|
-
|
|
77
|
-
const tunnelConfig = {
|
|
78
|
-
username: server.user,
|
|
79
|
-
host: server.host,
|
|
80
|
-
password: serverPassword,
|
|
81
|
-
dstHost: server.host,
|
|
82
|
-
dstPort: mySQLPort,
|
|
83
|
-
localHost: tunnelHost,
|
|
84
|
-
localPort: tunnelPort,
|
|
85
|
-
privateKey: serverPrivateKey,
|
|
86
|
-
};
|
|
71
|
+
const spinner = ora(`Connecting to ${server.host} for MySQL import...`).start();
|
|
87
72
|
|
|
88
73
|
return new Promise((resolve, reject) => {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
74
|
+
const conn = new SSH2Client();
|
|
75
|
+
|
|
76
|
+
conn.on('ready', () => {
|
|
77
|
+
spinner.text = `Importing SQL into ${database}...`;
|
|
78
|
+
|
|
79
|
+
// Wrap password in single quotes, escaping any single quotes within it
|
|
80
|
+
const escapedPassword = dbPassword.replace(/'/g, "'\\''");
|
|
81
|
+
const cmd = `mysql -u ${dbUser} -p'${escapedPassword}' ${database}`;
|
|
94
82
|
|
|
95
|
-
|
|
96
|
-
|
|
83
|
+
conn.exec(cmd, (err, stream) => {
|
|
84
|
+
if (err) {
|
|
85
|
+
conn.end();
|
|
86
|
+
spinner.fail('MySQL import failed');
|
|
87
|
+
reject(new Error(`SSH exec error: ${err.message}`));
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
let stderr = '';
|
|
92
|
+
stream.resume(); // drain stdout so the stream can close
|
|
93
|
+
stream.stderr.on('data', (data) => {
|
|
94
|
+
stderr += data.toString();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
stream.on('close', (code) => {
|
|
98
|
+
conn.end();
|
|
99
|
+
// Filter the harmless password-on-cli warning from stderr
|
|
100
|
+
const errorOutput = stderr
|
|
101
|
+
.replace(/.*Using a password on the command line.*\n?/g, '')
|
|
102
|
+
.trim();
|
|
103
|
+
if (code !== 0) {
|
|
104
|
+
spinner.fail('MySQL import failed');
|
|
105
|
+
reject(new Error(`MySQL import failed (exit ${code}): ${errorOutput}`));
|
|
106
|
+
} else {
|
|
107
|
+
spinner.succeed('SQL deployment was successful');
|
|
108
|
+
resolve();
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
// Pipe SQL file and explicitly end stdin when done
|
|
113
|
+
const sqlStream = fs.createReadStream(file);
|
|
114
|
+
sqlStream.on('end', () => stream.stdin.end());
|
|
115
|
+
sqlStream.on('error', (err) => {
|
|
116
|
+
spinner.fail('Failed to read SQL file');
|
|
117
|
+
reject(new Error(`SQL file read error: ${err.message}`));
|
|
118
|
+
});
|
|
119
|
+
sqlStream.pipe(stream.stdin, { end: false });
|
|
120
|
+
});
|
|
97
121
|
});
|
|
98
122
|
|
|
99
|
-
|
|
100
|
-
|
|
123
|
+
conn.on('error', (err) => {
|
|
124
|
+
spinner.fail('SSH connection error');
|
|
125
|
+
reject(new Error(`SSH connection error: ${err.message}`));
|
|
101
126
|
});
|
|
127
|
+
|
|
128
|
+
const connectConfig = {
|
|
129
|
+
host: server.host,
|
|
130
|
+
port: server.sshPort || 22,
|
|
131
|
+
username: server.user,
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
if (serverPrivateKey) {
|
|
135
|
+
connectConfig.privateKey = serverPrivateKey;
|
|
136
|
+
} else if (serverPassword) {
|
|
137
|
+
connectConfig.password = serverPassword;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
conn.connect(connectConfig);
|
|
102
141
|
});
|
|
103
142
|
}
|
|
104
143
|
|
|
@@ -175,72 +214,6 @@ async function deployToServer() {
|
|
|
175
214
|
});
|
|
176
215
|
}
|
|
177
216
|
|
|
178
|
-
async function connectMySQL() {
|
|
179
|
-
// Environment info
|
|
180
|
-
const { host } = settings.server[options.environment];
|
|
181
|
-
const { user, password, database } = settings.mysql[options.environment];
|
|
182
|
-
|
|
183
|
-
// Tunnel info
|
|
184
|
-
const { tunnelHost, tunnelPort } = options;
|
|
185
|
-
|
|
186
|
-
return new Promise((resolve, reject) => {
|
|
187
|
-
m = mysql.createConnection({
|
|
188
|
-
host: tunnelHost,
|
|
189
|
-
port: tunnelPort,
|
|
190
|
-
user,
|
|
191
|
-
password,
|
|
192
|
-
database,
|
|
193
|
-
multipleStatements: true,
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
m.connect((err) => {
|
|
197
|
-
if (err) {
|
|
198
|
-
reject(err);
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
logger.log(`Connected to ${host} as id ${m.threadId}`);
|
|
203
|
-
resolve();
|
|
204
|
-
});
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
async function deployMySQL(file) {
|
|
209
|
-
return new Promise((resolve, reject) => {
|
|
210
|
-
if (!file || !fs.existsSync(file)) {
|
|
211
|
-
reject(new Error('SQL file missing'));
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
logger.log('Starting SQL deployment');
|
|
216
|
-
|
|
217
|
-
const sql = fs.readFileSync(file).toString();
|
|
218
|
-
m.query(sql, (error) => {
|
|
219
|
-
if (error) {
|
|
220
|
-
reject(new Error(`failed: ${error}`));
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
logger.log('SQL deployment was successful');
|
|
225
|
-
resolve();
|
|
226
|
-
});
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
async function disconnectMySQL() {
|
|
231
|
-
return new Promise((resolve, reject) => {
|
|
232
|
-
m.end((err) => {
|
|
233
|
-
if (err) {
|
|
234
|
-
reject(new Error(`Error disconnecting: ${err.stack}`));
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
logger.log('Disconnected from MySQL server');
|
|
239
|
-
resolve();
|
|
240
|
-
});
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
|
|
244
217
|
module.exports = async (selectOptions, callbacks) => {
|
|
245
218
|
options = {
|
|
246
219
|
...defaultOptions,
|
|
@@ -274,20 +247,10 @@ module.exports = async (selectOptions, callbacks) => {
|
|
|
274
247
|
|
|
275
248
|
if (options.sql) {
|
|
276
249
|
const file = await exportSql({ environment: options.environment });
|
|
277
|
-
await createTunnel();
|
|
278
|
-
await connectMySQL();
|
|
279
250
|
|
|
280
251
|
if (file) {
|
|
281
|
-
await
|
|
282
|
-
environmentIn: 'local',
|
|
283
|
-
environmentOut: options.environment,
|
|
284
|
-
file,
|
|
285
|
-
});
|
|
286
|
-
|
|
287
|
-
await deployMySQL(file);
|
|
252
|
+
await deployMySQLviaSSH(file);
|
|
288
253
|
}
|
|
289
|
-
|
|
290
|
-
await disconnectMySQL();
|
|
291
254
|
}
|
|
292
255
|
|
|
293
256
|
await bumpVersion(options);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wp-blank-scripts",
|
|
3
|
-
"version": "4.0.0-alpha.
|
|
3
|
+
"version": "4.0.0-alpha.4",
|
|
4
4
|
"description": "Personal Wordpress Scripts",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -55,7 +55,6 @@
|
|
|
55
55
|
"inquirer": "3.0.4",
|
|
56
56
|
"lint-staged": "^13.3.0",
|
|
57
57
|
"mini-css-extract-plugin": "^2.10.1",
|
|
58
|
-
"mysql": "^2.18.1",
|
|
59
58
|
"node-fetch": "^2.7.0",
|
|
60
59
|
"ora": "^5.4.1",
|
|
61
60
|
"postcss": "^8.5.8",
|
package/webpack.base.config.js
CHANGED
|
@@ -303,7 +303,8 @@ function makeBaseConfig(options) {
|
|
|
303
303
|
sourceMap: !isProd,
|
|
304
304
|
additionalData: (content, loaderContext) =>
|
|
305
305
|
loaderContext.resourcePath.endsWith('.css') ? content : sassVariables + content,
|
|
306
|
-
sassOptions: {
|
|
306
|
+
sassOptions: (loaderContext) => ({
|
|
307
|
+
syntax: loaderContext.resourcePath.endsWith('.css') ? 'scss' : undefined,
|
|
307
308
|
loadPaths: [process.cwd()],
|
|
308
309
|
// Handle @import 'node_modules/foo/bar' resolving to a .css file.
|
|
309
310
|
// Dart Sass won't find .css files when the extension is omitted, so
|
|
@@ -331,7 +332,7 @@ function makeBaseConfig(options) {
|
|
|
331
332
|
// project-by-project via: wp-scripts migrate-sass
|
|
332
333
|
// New projects using @use/@forward won't trigger these.
|
|
333
334
|
silenceDeprecations: ['import', 'color-functions', 'slash-div', 'global-builtin'],
|
|
334
|
-
},
|
|
335
|
+
}),
|
|
335
336
|
},
|
|
336
337
|
},
|
|
337
338
|
],
|
package/utils/tunnelSsh.js
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
const net = require('net');
|
|
2
|
-
const { Client: Connection } = require('ssh2');
|
|
3
|
-
const events = require('events');
|
|
4
|
-
|
|
5
|
-
const noop = () => {};
|
|
6
|
-
|
|
7
|
-
function createConfig(config) {
|
|
8
|
-
const env = process.env;
|
|
9
|
-
|
|
10
|
-
config = {
|
|
11
|
-
username: env.TUNNELSSH_USER || env.USER || env.USERNAME || 'root',
|
|
12
|
-
port: 22,
|
|
13
|
-
host: null,
|
|
14
|
-
srcPort: 0,
|
|
15
|
-
srcHost: '127.0.0.1',
|
|
16
|
-
dstPort: null,
|
|
17
|
-
dstHost: '127.0.0.1',
|
|
18
|
-
localHost: '127.0.0.1',
|
|
19
|
-
localPort: config.dstPort,
|
|
20
|
-
agent: process.env.SSH_AUTH_SOCK,
|
|
21
|
-
...config,
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
if (!config.host) {
|
|
25
|
-
throw new Error('host not set');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (!config.dstPort) {
|
|
29
|
-
throw new Error('dstPort not set');
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return config;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function bindSSHConnection(config, netConnection) {
|
|
36
|
-
const sshConnection = new Connection();
|
|
37
|
-
netConnection.on('close', sshConnection.end.bind(sshConnection));
|
|
38
|
-
|
|
39
|
-
sshConnection.on('ready', function () {
|
|
40
|
-
netConnection.emit('sshConnection', sshConnection, netConnection);
|
|
41
|
-
sshConnection.forwardOut(
|
|
42
|
-
config.srcHost,
|
|
43
|
-
config.srcPort,
|
|
44
|
-
config.dstHost,
|
|
45
|
-
config.dstPort,
|
|
46
|
-
function (err, sshStream) {
|
|
47
|
-
if (err) {
|
|
48
|
-
// Bubble up the error => netConnection => server
|
|
49
|
-
netConnection.emit('error', err);
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
netConnection.emit('sshStream', sshStream);
|
|
54
|
-
netConnection.pipe(sshStream).pipe(netConnection);
|
|
55
|
-
}
|
|
56
|
-
);
|
|
57
|
-
});
|
|
58
|
-
return sshConnection;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function createServer(config) {
|
|
62
|
-
let server;
|
|
63
|
-
const connections = [];
|
|
64
|
-
let connectionCount = 0;
|
|
65
|
-
|
|
66
|
-
server = net.createServer(function (netConnection) {
|
|
67
|
-
let sshConnection;
|
|
68
|
-
connectionCount++;
|
|
69
|
-
netConnection.on('error', server.emit.bind(server, 'error'));
|
|
70
|
-
netConnection.on('close', function () {
|
|
71
|
-
connectionCount--;
|
|
72
|
-
if (connectionCount === 0) {
|
|
73
|
-
if (!config.keepAlive) {
|
|
74
|
-
setTimeout(function () {
|
|
75
|
-
if (connectionCount === 0) {
|
|
76
|
-
server.close();
|
|
77
|
-
}
|
|
78
|
-
}, 2);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
server.emit('netConnection', netConnection, server);
|
|
84
|
-
sshConnection = bindSSHConnection(config, netConnection);
|
|
85
|
-
sshConnection.on('error', server.emit.bind(server, 'error'));
|
|
86
|
-
|
|
87
|
-
netConnection.on('sshStream', function (sshStream) {
|
|
88
|
-
sshStream.on('error', function () {
|
|
89
|
-
server.close();
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
connections.push(sshConnection, netConnection);
|
|
94
|
-
try {
|
|
95
|
-
sshConnection.connect(config);
|
|
96
|
-
} catch (error) {
|
|
97
|
-
server.emit('error', error);
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
server.on('close', function () {
|
|
102
|
-
connections.forEach(function (connection) {
|
|
103
|
-
connection.end();
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
return server;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function tunnel(configArgs, callback) {
|
|
111
|
-
let server;
|
|
112
|
-
let config;
|
|
113
|
-
|
|
114
|
-
if (!callback) {
|
|
115
|
-
callback = noop;
|
|
116
|
-
}
|
|
117
|
-
try {
|
|
118
|
-
config = createConfig(configArgs);
|
|
119
|
-
server = createServer(config);
|
|
120
|
-
|
|
121
|
-
server.listen(config.localPort, config.localHost, function (error) {
|
|
122
|
-
callback(error, server);
|
|
123
|
-
});
|
|
124
|
-
} catch (e) {
|
|
125
|
-
server = new events.EventEmitter();
|
|
126
|
-
setImmediate(function () {
|
|
127
|
-
callback(e);
|
|
128
|
-
server.emit('error', e);
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
return server;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
module.exports = tunnel;
|