Skip to content

Commit

Permalink
feat: Adding Keygen as an official publisher/updater for electron-bui…
Browse files Browse the repository at this point in the history
  • Loading branch information
mmaietta committed Aug 19, 2021
1 parent 2656b5e commit 7f81021
Show file tree
Hide file tree
Showing 28 changed files with 23,199 additions and 4,409 deletions.
1 change: 0 additions & 1 deletion .gitignore
Expand Up @@ -16,7 +16,6 @@ out/

/packages/dmg-builder/vendor/
/packages/electron-builder/README.md
#/packages/app-builder-lib/scheme.json

/scripts/jsdoc/out/
/scripts/renderer/out/
Expand Down
5 changes: 3 additions & 2 deletions package.json
Expand Up @@ -25,7 +25,7 @@
"generate-changeset": "pnpm changeset",
"ci:version": "pnpm changelog && changeset version && node scripts/update-package-version-export.js && git add .",
"ci:publish": "pnpm compile && pnpm publish -r",
"schema": "typescript-json-schema packages/app-builder-lib/tsconfig.json Configuration --out packages/app-builder-lib/scheme.json --noExtraProps --useTypeOfKeyword --strictNullChecks --required && node ./scripts/fix-schema.js",
"schema": "ts-generate-schema packages/app-builder-lib/src/configuration.ts",
"jsdoc": "ts2jsdoc packages/builder-util-runtime packages/builder-util packages/app-builder-lib packages/electron-builder packages/electron-publish",
"jsdoc2md": "node scripts/jsdoc2md.js",
"/////": "git clone --single-branch -b docs git@github.com:electron-userland/electron-builder.git docs",
Expand All @@ -43,6 +43,7 @@
"dmg-license": "1.0.9"
},
"devDependencies": {
"@babel/core": "^7",
"@babel/plugin-transform-modules-commonjs": "7.14.5",
"@changesets/changelog-git": "0.1.7",
"@changesets/cli": "2.16.0",
Expand All @@ -61,9 +62,9 @@
"path-sort": "0.1.0",
"prettier": "2.3.2",
"source-map-support": "0.5.19",
"ts-generate-schema": "^2.0.0",
"ts-jsdoc": "3.2.2",
"typescript": "4.3.5",
"typescript-json-schema": "0.50.1",
"v8-compile-cache": "2.3.0"
},
"engines": {
Expand Down
1 change: 0 additions & 1 deletion packages/app-builder-lib/package.json
Expand Up @@ -6,7 +6,6 @@
"files": [
"out",
"templates",
"scheme.json",
"electron-osx-sign",
"certs/root_certs.keychain"
],
Expand Down
119 changes: 119 additions & 0 deletions packages/app-builder-lib/src/publish/KeygenPublisher.ts
@@ -0,0 +1,119 @@
import { Arch, InvalidConfigurationError, log, isEmptyOrSpaces } from "builder-util"
import { httpExecutor } from "builder-util/out/nodeHttpExecutor"
import { ClientRequest, RequestOptions } from "http"
import { HttpPublisher, PublishContext } from "electron-publish"
import { KeygenOptions } from "builder-util-runtime/out/publishOptions"
import { configureRequestOptions, HttpError, parseJson } from "builder-util-runtime"
import * as path from "path"
export class KeygenPublisher extends HttpPublisher {
readonly providerName = "keygen"
readonly hostname = "api.keygen.sh"

private readonly info: KeygenOptions
private readonly auth: string
private readonly version: string
private readonly basePath: string

constructor(context: PublishContext, info: KeygenOptions, version: string) {
super(context)

const token = process.env.KEYGEN_TOKEN
if (isEmptyOrSpaces(token)) {
throw new InvalidConfigurationError(`Keygen token is not set using env "KEYGEN_TOKEN" (see https://www.electron.build/configuration/publish#KeygenOptions)`)
}

this.info = info
this.auth = `Bearer ${token.trim()}`
this.version = version
this.basePath = `/v1/accounts/${this.info.account}/releases`
}

protected async doUpload(
fileName: string,
arch: Arch,
dataLength: number,
requestProcessor: (request: ClientRequest, reject: (error: Error) => void) => void,
file?: string
): Promise<any> {
for (let attemptNumber = 0; ; attemptNumber++) {
try {
const { data, errors } = await this.upsertVersion(fileName, dataLength)
const releaseId = data.id
if (releaseId == null) {
log.warn({ file: fileName, reason: "UUID doesn't exist and was not created" }, "upserting release failed")
return
}
if (errors) {
log.error({ ...errors }, "upserting release returned errors. Continuing to attempt upload since UUID is present")
}
const upload: RequestOptions = {
hostname: this.hostname,
path: `${this.basePath}/${releaseId}/artifact`,
headers: {
Accept: "application/vnd.api+json",
"Content-Length": dataLength,
},
}
await httpExecutor.doApiRequest(configureRequestOptions(upload, this.auth, "PUT"), this.context.cancellationToken, requestProcessor)
return releaseId
} catch (e) {
if (attemptNumber < 3 && ((e instanceof HttpError && e.statusCode === 502) || e.code === "EPIPE")) {
continue
}

throw e
}
}
}

private async upsertVersion(fileName: string, dataLength: number): Promise<{ data: any; errors: any }> {
const req: RequestOptions = {
hostname: this.hostname,
method: "PUT",
path: this.basePath,
headers: {
"Content-Type": "application/vnd.api+json",
Accept: "application/vnd.api+json",
},
}
const data = {
data: {
type: "release",
attributes: {
filename: fileName,
filetype: path.extname(fileName),
filesize: dataLength,
version: this.version,
platform: this.info.platform,
channel: this.info.channel || "stable",
},
relationships: {
product: {
data: {
type: "product",
id: this.info.product,
},
},
},
},
}
log.debug({ data: JSON.stringify(data) }, "Keygen upsert release")
return parseJson(httpExecutor.request(configureRequestOptions(req, this.auth, "PUT"), this.context.cancellationToken, data))
}

async deleteRelease(releaseId: string): Promise<void> {
const req: RequestOptions = {
hostname: this.hostname,
path: `${this.basePath}/${releaseId}`,
headers: {
Accept: "application/vnd.api+json",
},
}
await httpExecutor.request(configureRequestOptions(req, this.auth, "DELETE"), this.context.cancellationToken)
}

toString() {
const { account, product, platform } = this.info
return `Keygen (account: ${account}, product: ${product}, platform: ${platform}, version: ${this.version})`
}
}
17 changes: 17 additions & 0 deletions packages/app-builder-lib/src/publish/PublishManager.ts
Expand Up @@ -7,6 +7,7 @@ import {
getS3LikeProviderBaseUrl,
GithubOptions,
githubUrl,
KeygenOptions,
PublishConfiguration,
PublishProvider,
} from "builder-util-runtime"
Expand All @@ -29,6 +30,7 @@ import { expandMacro } from "../util/macroExpander"
import { WinPackager } from "../winPackager"
import { SnapStoreOptions, SnapStorePublisher } from "./SnapStorePublisher"
import { createUpdateInfoTasks, UpdateInfoFileTask, writeUpdateInfoFiles } from "./updateInfoBuilder"
import { KeygenPublisher } from "./KeygenPublisher"

const publishForPrWarning =
"There are serious security concerns with PUBLISH_FOR_PULL_REQUEST=true (see the CircleCI documentation (https://circleci.com/docs/1.0/fork-pr-builds/) for details)" +
Expand Down Expand Up @@ -297,6 +299,9 @@ export function createPublisher(context: PublishContext, version: string, publis
case "bintray":
return new BintrayPublisher(context, publishConfig as BintrayOptions, version, options)

case "keygen":
return new KeygenPublisher(context, publishConfig as KeygenOptions, version)

case "generic":
return null

Expand All @@ -321,6 +326,9 @@ function requireProviderClass(provider: string, packager: Packager): any | null
case "generic":
return null

case "keygen":
return KeygenPublisher

case "s3":
return S3Publisher

Expand Down Expand Up @@ -419,6 +427,8 @@ async function resolvePublishConfigurations(
serviceName = "github"
} else if (!isEmptyOrSpaces(process.env.BT_TOKEN)) {
serviceName = "bintray"
} else if (!isEmptyOrSpaces(process.env.KEYGEN_TOKEN)) {
serviceName = "keygen"
}

if (serviceName != null) {
Expand Down Expand Up @@ -499,6 +509,13 @@ async function getResolvedPublishConfig(
return options
}

if (provider === "keygen") {
return {
...options,
platform: platformPackager?.platform.name,
} as KeygenOptions
}

const isGithub = provider === "github"
if (!isGithub && provider !== "bintray") {
return options
Expand Down

0 comments on commit 7f81021

Please sign in to comment.