This repository was archived by the owner on Sep 27, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathdeploy.js
executable file
·222 lines (201 loc) · 5.88 KB
/
deploy.js
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#!/usr/bin/env node
/**
* Using clasp, create and deploy a new version of the script.
* Then update the archive manifest with the new version number, and
* get a refreshed google auth token, then upload the archive and publish
* the application on the chrome web store
* Env variables:
* APP_ID: ID of the deployed application on the chrome web store
* PRODUCTION_CLIENT_ID: client id of the project on google coud console
* PRODUCTION_CLIENT_SECRET: client secret
* PRODUCTION_CLIENT_REFRESH_TOKEN: refresh token (see authenticate() function)
*/
const fs = require('fs');
const readline = require('readline');
const {google} = require('googleapis');
const path = require('path');
const fetch = require('node-fetch');
const FormData = require('form-data');
const { exec } = require('child_process');
const archiver = require('archiver');
const ARCHIVE_NAME="archive.zip";
const MANIFEST="archive/manifest.json";
// If you need to generate a token for the get_refreshed_token function,
// call authenticate with a chromewebstore auth scope:
/*
const {authenticate} = require('./auth');
const SCOPES = [
'https://www.googleapis.com/auth/chromewebstore',
];
authenticate(SCOPES);
*/
console.log("creating new version...")
return create_new_version()
.then((version) => {
console.log(`deploying new version ${version}...`)
return deploy_version(version)
.then(() => {
console.log("updating manifest...")
return update_manifest_version(version)
})
})
.then(() => {
console.log("zipping archive...")
return zip_archive()
})
.then(() => {
console.log("getting oauth token...")
return get_refreshed_token()
})
.then((token) => {
console.log("uploading archive to google chrome store...")
return upload_archive(token)
.then(() => {
console.log("publishing application...");
return publish(token)
})
})
.then(() => {
console.log("Successfully updated application !")
process.exit(0)
})
.catch((error) => {
console.log("Error while updating application")
console.log(error)
process.exit(1)
})
// Creates an immutable version of the script.
// @return [String] the version number
function create_new_version() {
return new Promise((resolve, reject) => {
exec("clasp version 'new version'", (err, stdout, stderr) => {
if (err) {
reject(err);
}
resolve(stdout)
});
})
.then((stdout) => {
match = stdout.match(/Created version (\d+)\./)
if(match) {
return match[1];
} else {
throw new Error(`no version number found in stdout : ${stdout}`)
}
})
}
// Deploys a version of the script.
// @param [String] the version to deploy
// @return [String] the version number
function deploy_version(version) {
return new Promise((resolve, reject) => {
exec(`clasp deploy ${version} 'deploy version ${version}'`, (err, stdout, stderr) => {
if (err) {
reject(err);
}
resolve(version)
});
})
}
// Update the archive manifest content with the new version number
// @param [String] the version number
function update_manifest_version(version) {
var contents = fs.readFileSync(MANIFEST);
var json = JSON.parse(contents);
json.container_info.container_version = version;
json.version = version;
json.description = `Facebook Addon - PRODUCTION - version ${version}`;
fs.writeFileSync(MANIFEST, JSON.stringify(json, null, 4));
return Promise.resolve();
}
// Zip the archive
function zip_archive() {
return new Promise((resolve, reject) => {
var output = fs.createWriteStream(ARCHIVE_NAME);
var archive = archiver('zip');
output.on('close', function() {
resolve()
});
archive.on('error', function(err) {
reject(err)
});
archive.pipe(output);
archive.directory('archive/', false);
archive.finalize();
})
}
// Get a valid auth token
// @return [Promise] a (refreshed) google auth token
function get_refreshed_token() {
var form = new FormData();
form.append('client_id', process.env.PRODUCTION_CLIENT_ID);
form.append('client_secret', process.env.PRODUCTION_CLIENT_SECRET);
form.append('refresh_token', process.env.PRODUCTION_CLIENT_REFRESH_TOKEN);
form.append('grant_type', "refresh_token");
return fetch("https://accounts.google.com/o/oauth2/token", {
method: "POST",
body: form
})
.then((result) => result.json())
.then((json) => {
if(!json.access_token) {
throw new Error("No access_token in response")
}
return json.access_token;
})
.catch((err) => {
throw err;
})
}
// Upload the ARCHIVE_NAME archive on the chrome web store
// @param [String] A valid oauth token with chromewebstore authorization
function upload_archive(token) {
var bufferContent = fs.readFileSync(ARCHIVE_NAME);
return fetch(`https://www.googleapis.com/upload/chromewebstore/v1.1/items/${process.env.APP_ID}`, {
method: "PUT",
headers: {
"Authorization": `Bearer ${token}`,
"x-goog-api-version": "2"
},
body: bufferContent
})
.then((res) => {
if(res.status != 200) {
return res.json().then((json) => {
throw new Error(json.error.message)
})
}
return res.json()
})
.then((json) => {
if(json.itemError) {
throw new Error(JSON.stringify(json.itemError))
}
})
}
// Publish the application on the chrome web store
// @param [String] A valid oauth token with chromewebstore authorization
function publish(token) {
return fetch(`https://www.googleapis.com/chromewebstore/v1.1/items/${process.env.APP_ID}/publish`, {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"x-goog-api-version": "2",
"Content-Length": "0"
}
})
.then((res) => {
if(res.status != 200) {
console.log("got a " + res.status)
return res.json().then((json) => {
throw new Error(json.error.message)
})
}
return res.json()
})
.then((json) => {
if(json.itemError) {
throw new Error(JSON.stringify(json.itemError))
}
})
}