UNPKG

10.4 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.GitHubPublisher = undefined;
7
8var _bluebirdLstC;
9
10function _load_bluebirdLstC() {
11 return _bluebirdLstC = require("bluebird-lst-c");
12}
13
14var _bluebirdLstC2;
15
16function _load_bluebirdLstC2() {
17 return _bluebirdLstC2 = _interopRequireDefault(require("bluebird-lst-c"));
18}
19
20var _electronBuilderHttp;
21
22function _load_electronBuilderHttp() {
23 return _electronBuilderHttp = require("electron-builder-http");
24}
25
26var _electronBuilderUtil;
27
28function _load_electronBuilderUtil() {
29 return _electronBuilderUtil = require("electron-builder-util");
30}
31
32var _log;
33
34function _load_log() {
35 return _log = require("electron-builder-util/out/log");
36}
37
38var _nodeHttpExecutor;
39
40function _load_nodeHttpExecutor() {
41 return _nodeHttpExecutor = require("electron-builder-util/out/nodeHttpExecutor");
42}
43
44var _mime;
45
46function _load_mime() {
47 return _mime = _interopRequireDefault(require("mime"));
48}
49
50var _url;
51
52function _load_url() {
53 return _url = require("url");
54}
55
56var _publisher;
57
58function _load_publisher() {
59 return _publisher = require("./publisher");
60}
61
62function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
63
64class GitHubPublisher extends (_publisher || _load_publisher()).HttpPublisher {
65 constructor(context, info, version) {
66 let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
67
68 super(context, true);
69 this.info = info;
70 this.version = version;
71 this.options = options;
72 this.providerName = "GitHub";
73 let token = info.token;
74 if ((0, (_electronBuilderUtil || _load_electronBuilderUtil()).isEmptyOrSpaces)(token)) {
75 token = process.env.GH_TOKEN;
76 if ((0, (_electronBuilderUtil || _load_electronBuilderUtil()).isEmptyOrSpaces)(token)) {
77 throw new Error(`GitHub Personal Access Token is not set, neither programmatically, nor using env "GH_TOKEN"`);
78 }
79 }
80 this.token = token;
81 if (version.startsWith("v")) {
82 throw new Error(`Version must not starts with "v": ${version}`);
83 }
84 this.tag = info.vPrefixedTagName === false ? version : `v${version}`;
85 }
86 get releasePromise() {
87 if (this._releasePromise == null) {
88 this._releasePromise = this.token === "__test__" ? (_bluebirdLstC2 || _load_bluebirdLstC2()).default.resolve(null) : this.getOrCreateRelease();
89 }
90 return this._releasePromise;
91 }
92 getOrCreateRelease() {
93 var _this = this;
94
95 return (0, (_bluebirdLstC || _load_bluebirdLstC()).coroutine)(function* () {
96 // we don't use "Get a release by tag name" because "tag name" means existing git tag, but we draft release and don't create git tag
97 const releases = yield _this.githubRequest(`/repos/${_this.info.owner}/${_this.info.repo}/releases`, _this.token);
98 for (const release of releases) {
99 if (release.tag_name === _this.tag || release.tag_name === _this.version) {
100 if (release.draft) {
101 return release;
102 }
103 // https://github.com/electron-userland/electron-builder/issues/1197
104 // https://electron-builder.slack.com/archives/general/p1485961449000202
105 if (_this.options.draft == null || _this.options.draft) {
106 (0, (_log || _load_log()).warn)(`Release with tag ${_this.tag} already exists`);
107 return null;
108 }
109 // https://github.com/electron-userland/electron-builder/issues/1133
110 // if release created < 2 hours — allow to upload
111 const publishedAt = release.published_at == null ? null : new Date(release.published_at);
112 if (publishedAt != null && Date.now() - publishedAt.getMilliseconds() > 2 * 3600 * 1000) {
113 // https://github.com/electron-userland/electron-builder/issues/1183#issuecomment-275867187
114 (0, (_log || _load_log()).warn)(`Release with tag ${_this.tag} published at ${publishedAt.toString()}, more than 2 hours ago`);
115 return null;
116 }
117 return release;
118 }
119 }
120 (0, (_log || _load_log()).log)(`Release with tag ${_this.tag} doesn't exist, creating one`);
121 return _this.createRelease();
122 })();
123 }
124 doUpload(fileName, dataLength, requestProcessor) {
125 var _this2 = this;
126
127 return (0, (_bluebirdLstC || _load_bluebirdLstC()).coroutine)(function* () {
128 const release = yield _this2.releasePromise;
129 if (release == null) {
130 (0, (_electronBuilderUtil || _load_electronBuilderUtil()).debug)(`Release with tag ${_this2.tag} doesn't exist and is not created, artifact ${fileName} is not published`);
131 return;
132 }
133 const parsedUrl = (0, (_url || _load_url()).parse)(release.upload_url.substring(0, release.upload_url.indexOf("{")) + "?name=" + fileName);
134 let badGatewayCount = 0;
135 uploadAttempt: for (let i = 0; i < 3; i++) {
136 try {
137 return yield (_nodeHttpExecutor || _load_nodeHttpExecutor()).httpExecutor.doApiRequest((0, (_electronBuilderHttp || _load_electronBuilderHttp()).configureRequestOptions)({
138 hostname: parsedUrl.hostname,
139 path: parsedUrl.path,
140 method: "POST",
141 headers: {
142 Accept: "application/vnd.github.v3+json",
143 "Content-Type": (_mime || _load_mime()).default.lookup(fileName),
144 "Content-Length": dataLength
145 }
146 }, _this2.token), _this2.context.cancellationToken, requestProcessor);
147 } catch (e) {
148 if (e instanceof (_electronBuilderHttp || _load_electronBuilderHttp()).HttpError) {
149 if (e.response.statusCode === 422 && e.description != null && e.description.errors != null && e.description.errors[0].code === "already_exists") {
150 // delete old artifact and re-upload
151 (0, (_electronBuilderUtil || _load_electronBuilderUtil()).debug)(`Artifact ${fileName} already exists on GitHub, overwrite one`);
152 const assets = yield _this2.githubRequest(`/repos/${_this2.info.owner}/${_this2.info.repo}/releases/${release.id}/assets`, _this2.token, null);
153 for (const asset of assets) {
154 if (asset.name === fileName) {
155 yield _this2.githubRequest(`/repos/${_this2.info.owner}/${_this2.info.repo}/releases/assets/${asset.id}`, _this2.token, null, "DELETE");
156 continue uploadAttempt;
157 }
158 }
159 (0, (_electronBuilderUtil || _load_electronBuilderUtil()).debug)(`Artifact ${fileName} not found on GitHub, trying to upload again`);
160 continue;
161 } else if (e.response.statusCode === 502 && badGatewayCount++ < 3) {
162 continue;
163 }
164 }
165 throw e;
166 }
167 }
168 })();
169 }
170 createRelease() {
171 return this.githubRequest(`/repos/${this.info.owner}/${this.info.repo}/releases`, this.token, {
172 tag_name: this.tag,
173 name: this.version,
174 draft: this.options.draft == null || this.options.draft,
175 prerelease: this.options.prerelease != null && this.options.prerelease
176 });
177 }
178 // test only
179 //noinspection JSUnusedGlobalSymbols
180 getRelease() {
181 var _this3 = this;
182
183 return (0, (_bluebirdLstC || _load_bluebirdLstC()).coroutine)(function* () {
184 return _this3.githubRequest(`/repos/${_this3.info.owner}/${_this3.info.repo}/releases/${(yield _this3._releasePromise).id}`, _this3.token);
185 })();
186 }
187 //noinspection JSUnusedGlobalSymbols
188 deleteRelease() {
189 var _this4 = this;
190
191 return (0, (_bluebirdLstC || _load_bluebirdLstC()).coroutine)(function* () {
192 const release = yield _this4._releasePromise;
193 if (release == null) {
194 return;
195 }
196 for (let i = 0; i < 3; i++) {
197 try {
198 return yield _this4.githubRequest(`/repos/${_this4.info.owner}/${_this4.info.repo}/releases/${release.id}`, _this4.token, null, "DELETE");
199 } catch (e) {
200 if (e instanceof (_electronBuilderHttp || _load_electronBuilderHttp()).HttpError) {
201 if (e.response.statusCode === 404) {
202 (0, (_log || _load_log()).warn)(`Cannot delete release ${release.id} — doesn't exist`);
203 return;
204 } else if (e.response.statusCode === 405 || e.response.statusCode === 502) {
205 continue;
206 }
207 }
208 throw e;
209 }
210 }
211 (0, (_log || _load_log()).warn)(`Cannot delete release ${release.id}`);
212 })();
213 }
214 githubRequest(path, token) {
215 let data = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
216 let method = arguments[3];
217
218 return (_nodeHttpExecutor || _load_nodeHttpExecutor()).httpExecutor.request((0, (_electronBuilderHttp || _load_electronBuilderHttp()).configureRequestOptions)({
219 host: this.info.host || "api.github.com",
220 path: this.info.host != null && this.info.host !== "github.com" ? `/api/v3/${path}` : path,
221 headers: { Accept: "application/vnd.github.v3+json" }
222 }, token, method), this.context.cancellationToken, data);
223 }
224 toString() {
225 return `Github (owner: ${this.info.owner}, project: ${this.info.repo}, version: ${this.version})`;
226 }
227}
228exports.GitHubPublisher = GitHubPublisher; //# sourceMappingURL=gitHubPublisher.js.map
\No newline at end of file