Repository navigation
Expand file tree
/
Copy pathdeploy.js
More file actions
134 lines (107 loc) · 4.14 KB
/
Copy pathdeploy.js
File metadata and controls
134 lines (107 loc) · 4.14 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
128
129
130
131
132
133
134
const fs = require("fs");
const childProcess = require("child_process");
const path = require("path");
const CWD = process.cwd();
let projectdir = path.resolve(CWD, process.argv[2])
fs.mkdirSync(path.resolve(projectdir, "tmp"), {recursive: true})
fs.mkdirSync(path.resolve(projectdir, "backup"), {recursive: true})
const cfg = JSON.parse(fs.readFileSync(path.resolve(projectdir, "deploy.json")).toString())
class GIT {
constructor(cfg) {
this.org = cfg.git.org
this.repo = cfg.git.repo
this.branch = cfg.git.branch
this.token = cfg.git.token
this.headers = {
Accept: "application/vnd.github+json",
Authorization: `Bearer ${this.token}`,
"X-GitHub-Api-Version": "2022-11-28"
}
}
async getLatestTag() {
return await fetch(`https://api.github.com/repos/${this.org}/${this.repo}/tags`, {headers: this.headers})
.then(res => res.json())
.then(res => {
if (res.length === 0) error("Tags not found!");
else return res[0].name;
})
}
async read() {
console.log(`Fetchin ${this.branch} branch of ${this.org}/${this.repo}`)
return await fetch(`https://api.github.com/repos/${this.org}/${this.repo}/branches`, {headers: this.headers})
.then(res => res.json())
.then(res => res.find(item => item.name === this.branch))
.then(async res => {
if (res === undefined) error("Branch not found!");
else return await this.getLatestTag();
})
}
async clone(dir) {
await exec(`git clone git@github.com:${this.org}/${this.repo}.git ${dir}`, {});
}
}
function error(message) {
console.log("❌ " + message || "");
process.exit(1);
}
function ok(message) {
console.log(`✅ ${message || ""}`)
}
async function exec(cmd) {
console.log(`- RUN: ${cmd}`)
return new Promise((resolve) => childProcess.exec(cmd, (err, stdout, stderr) => {
// console.log(stdout)
resolve();
}));
}
async function execAll(cmds) {
for (const cmd of cmds) await exec(cmd)
}
async function deploy() {
const git = new GIT(cfg);
const NEWTAG = (await git.read()).trim();
const OLDTAG =
fs.existsSync(path.resolve(projectdir, "deployed.txt"))
? fs.readFileSync(path.resolve(projectdir, "deployed.txt")).toString().trim()
: "0";
console.log(`OLD-TAG: ${OLDTAG}`);
console.log(`NEW-TAG: ${NEWTAG}`);
if (OLDTAG !== NEWTAG) {
console.log("Changes detected, deploy project")
const timestamp = (Math.floor(Date.now().valueOf() / 1000)).toString();
const dir = path.resolve(projectdir, "tmp", timestamp);
fs.mkdirSync(dir)
console.log(`[Clone from GIT]`)
await git.clone(dir)
console.log(`[Copy/Link resources]`)
for (const symlink in cfg.symlink) {
const src = path.resolve(projectdir, symlink);
const target = path.resolve(CWD, dir, cfg.symlink[symlink]);
console.log(`- LINK: ${src} => ${target}`)
fs.symlinkSync(src, target);
}
for (const copy in cfg.copy) {
const src = path.resolve(projectdir, copy);
const target = path.resolve(CWD, dir, cfg.copy[copy]);
console.log(`- COPY: ${src} => ${target}`)
fs.copyFileSync(src, target);
}
process.chdir(dir)
console.log("[Prepare]")
await execAll(cfg.scripts.prepare)
console.log("[Stop service]")
await execAll(cfg.scripts.stop)
if (fs.existsSync(path.resolve(projectdir, cfg.target))) {
console.log("[Create Backup]")
fs.renameSync(path.resolve(projectdir, cfg.target), path.resolve(projectdir, "backup", timestamp + "(" + OLDTAG + ")"));
}
console.log("[Deploy]")
fs.renameSync(dir, path.resolve(projectdir, cfg.target));
console.log("[Start service]")
await execAll(cfg.scripts.start)
fs.writeFileSync(path.resolve(projectdir, "deployed.txt"), NEWTAG)
} else {
console.log("No changes detected")
}
}
deploy();