-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdeploy.js
More file actions
127 lines (100 loc) · 3.58 KB
/
deploy.js
File metadata and controls
127 lines (100 loc) · 3.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/**
* Based off of https://gist.github.com/domenic/ec8b0fc8ab45f39403dd
*/
const path = require('path');
const { readdirSync, existsSync } = require('fs');
const { execSync } = require('child_process');
const tmp = require('tmp');
const emoji = require('emoji-random');
const parseGitUrl = require('git-url-parse');
if (!process.argv[2]) {
console.log('Usage: deploy.js {mono-repo-root}');
process.exit(0);
}
const monoRepoDir = path.resolve(process.argv[2]);
const sitesDir = path.join(monoRepoDir, 'sites');
const sites = readdirSync(sitesDir);
const exec = (cmd, options = {}) => (
execSync(cmd, Object.assign(
{ stdio: 'inherit', env: process.env },
options
))
)
const execIn = cwd => (command, options = {}) => (
exec(command, Object.assign(options, { cwd }))
);
const monoRepoExec = execIn(monoRepoDir);
console.log(`\nStarting deploy script for [ ${sites.join(', ')} ]\n`)
exec('git config --global user.name "WWWTF Deploy Bot"');
exec('git config --global user.email "deploy@wwwtf.berlin"');
sites.forEach(site => {
const siteDir = path.join(sitesDir, site);
const siteExec = execIn(siteDir);
const packagePath = path.join(siteDir, 'package.json');
if (!existsSync(packagePath)) {
return console.log(`\nNo package.json for ${site}. Skipping.\n`);
}
const packageJson = require(packagePath);
const { deploy, repository, scripts } = packageJson;
if (!deploy || !repository || !repository.url || !scripts.build) {
return console.log(`\Bad deploy config for ${site}. Skipping.\n`)
}
const { buildDir, ignoreDiff } = deploy;
const gitUrlObj = parseGitUrl(repository.url);
const sshUrl = gitUrlObj.toString('ssh');
const httpsUrl = gitUrlObj.toString('https');
console.log(`\nInstalling and building ${site}\n`);
try {
siteExec('npm install');
siteExec('npm run build');
} catch (err) {
return console.log(`Error installing or building ${site}. Skipping.`);
}
const tmpDir = tmp.dirSync().name;
const deployCloneExec = execIn(tmpDir);
try {
console.log(`\nCloning ${site} deployment repo from ${httpsUrl}\n`);
// We need to clone via HTTPS since we don't know what the SSH key is yet
exec(`git clone ${httpsUrl} ${tmpDir}`);
deployCloneExec(`cp -Rf ${path.join(siteDir, buildDir)}/* .`);
} catch (err) {
return console.log(`Problem cloning ${site}. Skipping.`);
}
// Mark intent to add files so that git diff also works for
// untracked files
deployCloneExec('git add -N .');
try {
const ignores = ignorePathspec(ignoreDiff);
deployCloneExec(`git diff --quiet -- . ${ignores}`);
return console.log(`\nNo changes to ${site}. Skipping.\n`);
} catch (err) {
if (commitAndPush()) {
return console.log(
`\nError pushing to ${site} deployment repo. Skipping.\n`
);
}
}
function commitAndPush () {
try {
const deploySHA = process.env['TRAVIS_COMMIT'];
deployCloneExec('git add -A .');
deployCloneExec(`git commit -m 'Deploy! ${emoji.random()} ${deploySHA}'`);
console.log(`\nPushing changes to ${site} deployment repo\n`);
deployCloneExec(`openssl aes-256-cbc -K $${deploy.key} -iv $${deploy.iv} -in id_rsa.enc -out id_rsa -d`);
deployCloneExec('chmod 600 id_rsa');
deployCloneExec(
`GIT_SSH_COMMAND="ssh -i id_rsa -F /dev/null" git push ${sshUrl} master`
);
} catch (err) {
return err;
}
}
exec(`rm -Rf ${tmpDir}`);
});
function ignorePathspec (ignores) {
return !ignores
? ''
: ignores.split(',').reduce((acc, path) => (
`${acc}':(glob,exclude)${path}' `
), '');
}