From d0487b014ed9a933aebe3f3031f95d7d98c84441 Mon Sep 17 00:00:00 2001 From: develar Date: Mon, 19 Feb 2018 08:26:36 +0100 Subject: [PATCH] fix(deployment): Bintray publisher doesn't escape filename Close #2600 --- packages/builder-util/src/nodeHttpExecutor.ts | 2 + packages/electron-publish/package.json | 1 + .../electron-publish/src/BintrayPublisher.ts | 21 ++--- .../electron-publish/src/gitHubPublisher.ts | 22 ++--- test/src/ArtifactPublisherTest.ts | 4 +- yarn.lock | 88 +++++++++++-------- 6 files changed, 72 insertions(+), 66 deletions(-) diff --git a/packages/builder-util/src/nodeHttpExecutor.ts b/packages/builder-util/src/nodeHttpExecutor.ts index 9753af208ee..7ccfccb2b45 100644 --- a/packages/builder-util/src/nodeHttpExecutor.ts +++ b/packages/builder-util/src/nodeHttpExecutor.ts @@ -10,6 +10,8 @@ export class NodeHttpExecutor extends HttpExecutor { .then(() => destination) } + // noinspection JSMethodCanBeStatic + // noinspection JSUnusedGlobalSymbols doRequest(options: any, callback: (response: any) => void): any { return (options.protocol === "http:" ? httpRequest : https.request)(options, callback) } diff --git a/packages/electron-publish/package.json b/packages/electron-publish/package.json index 6c67c1be97f..bf3344eadfe 100644 --- a/packages/electron-publish/package.json +++ b/packages/electron-publish/package.json @@ -11,6 +11,7 @@ "out" ], "dependencies": { + "lazy-val": "^1.0.3", "fs-extra-p": "^4.5.2", "mime": "^2.2.0", "bluebird-lst": "^1.0.5", diff --git a/packages/electron-publish/src/BintrayPublisher.ts b/packages/electron-publish/src/BintrayPublisher.ts index 437c79b9d0b..63ea66bf305 100644 --- a/packages/electron-publish/src/BintrayPublisher.ts +++ b/packages/electron-publish/src/BintrayPublisher.ts @@ -1,13 +1,13 @@ -import BluebirdPromise from "bluebird-lst" import { Arch, InvalidConfigurationError, isEmptyOrSpaces, isTokenCharValid, log, toLinuxArchString } from "builder-util" import { BintrayOptions, configureRequestOptions, HttpError } from "builder-util-runtime" import { BintrayClient, Version } from "builder-util-runtime/out/bintray" import { httpExecutor } from "builder-util/out/nodeHttpExecutor" import { ClientRequest, RequestOptions } from "http" +import { Lazy } from "lazy-val" import { HttpPublisher, PublishContext, PublishOptions } from "./publisher" export class BintrayPublisher extends HttpPublisher { - private _versionPromise: BluebirdPromise + private readonly _versionPromise = new Lazy(() => this.init()) private readonly client: BintrayClient @@ -31,7 +31,6 @@ export class BintrayPublisher extends HttpPublisher { } this.client = new BintrayClient(info, httpExecutor, this.context.cancellationToken, token) - this._versionPromise = this.init() as BluebirdPromise } private async init(): Promise { @@ -54,7 +53,7 @@ export class BintrayPublisher extends HttpPublisher { } protected async doUpload(fileName: string, arch: Arch, dataLength: number, requestProcessor: (request: ClientRequest, reject: (error: Error) => void) => void) { - const version = await this._versionPromise + const version = await this._versionPromise.value if (version == null) { log.notice({file: fileName, reason: "version doesn't exist and is not created", version: this.version}, "skipped publishing") return @@ -62,7 +61,7 @@ export class BintrayPublisher extends HttpPublisher { const options: RequestOptions = { hostname: "api.bintray.com", - path: `/content/${this.client.owner}/${this.client.repo}/${this.client.packageName}/${version.name}/${fileName}`, + path: `/content/${this.client.owner}/${this.client.repo}/${this.client.packageName}/${encodeURI(`${version.name}/${fileName}`)}`, method: "PUT", headers: { "Content-Length": dataLength, @@ -97,13 +96,15 @@ export class BintrayPublisher extends HttpPublisher { } //noinspection JSUnusedGlobalSymbols - deleteRelease(): Promise { - if (!this._versionPromise.isFulfilled()) { - return BluebirdPromise.resolve() + async deleteRelease(): Promise { + if (!this._versionPromise.hasValue) { + return } - const version = this._versionPromise.value() - return version == null ? BluebirdPromise.resolve() : this.client.deleteVersion(version.name) + const version = (await this._versionPromise.value) + if (version != null) { + await this.client.deleteVersion(version.name) + } } toString() { diff --git a/packages/electron-publish/src/gitHubPublisher.ts b/packages/electron-publish/src/gitHubPublisher.ts index 867e72ca6f7..5c49880b436 100644 --- a/packages/electron-publish/src/gitHubPublisher.ts +++ b/packages/electron-publish/src/gitHubPublisher.ts @@ -1,9 +1,9 @@ -import BluebirdPromise from "bluebird-lst" import { Arch, InvalidConfigurationError, isEmptyOrSpaces, isEnvTrue, isTokenCharValid, log } from "builder-util" import { configureRequestOptions, GithubOptions, HttpError, parseJson } from "builder-util-runtime" import { Fields } from "builder-util/out/log" import { httpExecutor } from "builder-util/out/nodeHttpExecutor" import { ClientRequest } from "http" +import { Lazy } from "lazy-val" import mime from "mime" import { parse as parseUrl } from "url" import { getCiTag, HttpPublisher, PublishContext, PublishOptions } from "./publisher" @@ -26,8 +26,8 @@ interface Asset { } export class GitHubPublisher extends HttpPublisher { - private tag: string - private _releasePromise: Promise | null = null + private readonly tag: string + readonly _release = new Lazy(() => this.token === "__test__" ? Promise.resolve(null as any) : this.getOrCreateRelease()) private readonly token: string @@ -37,14 +37,6 @@ export class GitHubPublisher extends HttpPublisher { private releaseLogFields: Fields | null = null - /** @private */ - get releasePromise(): Promise { - if (this._releasePromise == null) { - this._releasePromise = this.token === "__test__" ? BluebirdPromise.resolve(null as any) : this.getOrCreateRelease() - } - return this._releasePromise - } - constructor(context: PublishContext, private readonly info: GithubOptions, private readonly version: string, private readonly options: PublishOptions = {}) { super(context, true) @@ -169,7 +161,7 @@ export class GitHubPublisher extends HttpPublisher { } protected async doUpload(fileName: string, arch: Arch, dataLength: number, requestProcessor: (request: ClientRequest, reject: (error: Error) => void) => void): Promise { - const release = await this.releasePromise + const release = await this._release.value if (release == null) { log.warn({file: fileName, ...this.releaseLogFields}, "skipped publishing") return @@ -215,16 +207,16 @@ export class GitHubPublisher extends HttpPublisher { // test only //noinspection JSUnusedGlobalSymbols async getRelease(): Promise { - return this.githubRequest(`/repos/${this.info.owner}/${this.info.repo}/releases/${(await this._releasePromise)!.id}`, this.token) + return this.githubRequest(`/repos/${this.info.owner}/${this.info.repo}/releases/${(await this._release.value)!.id}`, this.token) } //noinspection JSUnusedGlobalSymbols async deleteRelease(): Promise { - const release = await this._releasePromise - if (release == null) { + if (!this._release.hasValue) { return } + const release = await this._release.value for (let i = 0; i < 3; i++) { try { return await this.githubRequest(`/repos/${this.info.owner}/${this.info.repo}/releases/${release.id}`, this.token, null, "DELETE") diff --git a/test/src/ArtifactPublisherTest.ts b/test/src/ArtifactPublisherTest.ts index d718852b1fc..5e70b6164a5 100644 --- a/test/src/ArtifactPublisherTest.ts +++ b/test/src/ArtifactPublisherTest.ts @@ -38,7 +38,7 @@ const publishContext: PublishContext = { test("GitHub unauthorized", async () => { try { - await new GitHubPublisher(publishContext, {provider: "github", owner: "actperepo", repo: "ecb2", token: "incorrect token"}, versionNumber()).releasePromise + await new GitHubPublisher(publishContext, {provider: "github", owner: "actperepo", repo: "ecb2", token: "incorrect token"}, versionNumber())._release.value } catch (e) { expect(e.message).toMatch(/(Bad credentials|Unauthorized|API rate limit exceeded)/) @@ -78,7 +78,7 @@ test("Bintray upload", async () => { const version = versionNumber() const tmpDir = new TmpDir("artifact-publisher-test") - const artifactPath = await tmpDir.getTempFile({suffix: ".icns"}) + const artifactPath = await tmpDir.getTempFile({suffix: " test space.icns"}) await copyFile(iconPath, artifactPath) //noinspection SpellCheckingInspection diff --git a/yarn.lock b/yarn.lock index d1da438c516..da8bd2c0262 100644 --- a/yarn.lock +++ b/yarn.lock @@ -127,8 +127,8 @@ "@types/lodash" "*" "@types/lodash@*": - version "4.14.103" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.103.tgz#56ac640f029f67655f0721f479f1faa982bd8122" + version "4.14.104" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.104.tgz#53ee2357fa2e6e68379341d92eb2ecea4b11bb80" "@types/node-emoji@^1.8.0": version "1.8.0" @@ -855,8 +855,8 @@ braces@^1.8.2: repeat-element "^1.1.2" braces@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.0.tgz#a46941cb5fb492156b3d6a656e06c35364e3e66e" + version "2.3.1" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.1.tgz#7086c913b4e5a08dbe37ac0ee6a2500c4ba691bb" dependencies: arr-flatten "^1.1.0" array-unique "^0.3.2" @@ -864,6 +864,7 @@ braces@^2.3.0: extend-shallow "^2.0.1" fill-range "^4.0.0" isobject "^3.0.1" + kind-of "^6.0.2" repeat-element "^1.1.2" snapdragon "^0.8.1" snapdragon-node "^2.0.1" @@ -1462,6 +1463,13 @@ define-property@^1.0.0: dependencies: is-descriptor "^1.0.0" +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -1753,8 +1761,8 @@ es-to-primitive@^1.1.1: is-symbol "^1.0.1" es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.11, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.5, es5-ext@~0.10.6: - version "0.10.38" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.38.tgz#fa7d40d65bbc9bb8a67e1d3f9cc656a00530eed3" + version "0.10.39" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.39.tgz#fca21b67559277ca4ac1a1ed7048b107b6f76d87" dependencies: es6-iterator "~2.0.3" es6-symbol "~3.1.1" @@ -1915,7 +1923,7 @@ extend-shallow@^2.0.1: dependencies: is-extendable "^0.1.0" -extend-shallow@^3.0.0: +extend-shallow@^3.0.0, extend-shallow@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" dependencies: @@ -2106,14 +2114,7 @@ front-matter@^2.1.0: dependencies: js-yaml "^3.10.0" -fs-extra-p@^4.4.4, fs-extra-p@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/fs-extra-p/-/fs-extra-p-4.5.0.tgz#b79f3f3fcc0b5e57b7e7caeb06159f958ef15fe8" - dependencies: - bluebird-lst "^1.0.5" - fs-extra "^5.0.0" - -fs-extra-p@^4.5.2: +fs-extra-p@^4.4.4, fs-extra-p@^4.5.0, fs-extra-p@^4.5.2: version "4.5.2" resolved "https://registry.yarnpkg.com/fs-extra-p/-/fs-extra-p-4.5.2.tgz#0a22aba489284d17f375d5dc5139aa777fe2df51" dependencies: @@ -2712,7 +2713,7 @@ is-descriptor@^0.1.0: is-data-descriptor "^0.1.4" kind-of "^5.0.0" -is-descriptor@^1.0.0: +is-descriptor@^1.0.0, is-descriptor@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" dependencies: @@ -2803,15 +2804,19 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + is-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" -is-odd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-1.0.0.tgz#3b8a932eb028b3775c39bb09e91767accdb69088" +is-odd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-2.0.0.tgz#7646624671fd7ea558ccd9a2795182f2958f1b24" dependencies: - is-number "^3.0.0" + is-number "^4.0.0" is-path-inside@^1.0.0: version "1.0.1" @@ -2867,6 +2872,10 @@ is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + is@^3.1.0: version "3.2.1" resolved "https://registry.yarnpkg.com/is/-/is-3.2.1.tgz#d0ac2ad55eb7b0bec926a5266f6c662aaa83dca5" @@ -3432,7 +3441,7 @@ kind-of@^4.0.0: dependencies: is-buffer "^1.1.5" -kind-of@^5.0.0, kind-of@^5.0.2: +kind-of@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" @@ -3672,8 +3681,8 @@ map-visit@^1.0.0: object-visit "^1.0.0" marked@^0.3.12, marked@~0.3.6: - version "0.3.12" - resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.12.tgz#7cf25ff2252632f3fe2406bde258e94eee927519" + version "0.3.15" + resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.15.tgz#de96982e54c880962f5093a2fa93d0866bf73668" media-typer@0.3.0: version "0.3.0" @@ -3762,15 +3771,15 @@ micromatch@^2.1.5, micromatch@^2.3.11: parse-glob "^3.0.4" regex-cache "^0.4.2" -mime-db@~1.30.0: - version "1.30.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" +mime-db@~1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" -mime-types@^2.1.12, mime-types@~2.1.15, mime-types@~2.1.17, mime-types@~2.1.7: - version "2.1.17" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.18, mime-types@~2.1.7: + version "2.1.18" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" dependencies: - mime-db "~1.30.0" + mime-db "~1.33.0" mime@1.3.4: version "1.3.4" @@ -3844,16 +3853,17 @@ nan@^2.3.0: resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a" nanomatch@^1.2.5: - version "1.2.7" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.7.tgz#53cd4aa109ff68b7f869591fdc9d10daeeea3e79" + version "1.2.9" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.9.tgz#879f7150cb2dab7a471259066c104eee6e0fa7c2" dependencies: arr-diff "^4.0.0" array-unique "^0.3.2" - define-property "^1.0.0" - extend-shallow "^2.0.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" fragment-cache "^0.2.1" - is-odd "^1.0.0" - kind-of "^5.0.2" + is-odd "^2.0.0" + is-windows "^1.0.2" + kind-of "^6.0.2" object.pick "^1.3.0" regex-not "^1.0.0" snapdragon "^0.8.1" @@ -5431,11 +5441,11 @@ type-check@~0.3.2: prelude-ls "~1.1.2" type-is@~1.6.10: - version "1.6.15" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" + version "1.6.16" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" dependencies: media-typer "0.3.0" - mime-types "~2.1.15" + mime-types "~2.1.18" typescript@2.7.2: version "2.7.2"