Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/hip-weeks-allow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"app-builder-lib": patch
---

fix: allow usage of .cjs, .mjs, and type=module custom/generic publishers
2 changes: 1 addition & 1 deletion packages/app-builder-lib/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export function build(options: PackagerOptions & PublishOptions, packager: Packa
}
buildResult.artifactPaths.push(newArtifact)
for (const publishConfiguration of publishConfigurations) {
publishManager.scheduleUpload(
await publishManager.scheduleUpload(
publishConfiguration,
{
file: newArtifact,
Expand Down
49 changes: 28 additions & 21 deletions packages/app-builder-lib/src/publish/PublishManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ import { PlatformPackager } from "../platformPackager"
import { expandMacro } from "../util/macroExpander"
import { WinPackager } from "../winPackager"
import { createUpdateInfoTasks, UpdateInfoFileTask, writeUpdateInfoFiles } from "./updateInfoBuilder"
import { existsSync } from "fs-extra"
import { resolveModule } from "../util/resolve"

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 @@ -135,7 +137,7 @@ export class PublishManager implements PublishContext {
if (debug.enabled) {
debug(`artifactCreated (isPublish: ${this.isPublish}): ${safeStringifyJson(event, new Set(["packager"]))},\n publishConfig: ${safeStringifyJson(publishConfiguration)}`)
}
this.scheduleUpload(publishConfiguration, event, this.getAppInfo(event.packager))
void this.scheduleUpload(publishConfiguration, event, this.getAppInfo(event.packager))
}
})
}
Expand All @@ -149,12 +151,12 @@ export class PublishManager implements PublishContext {
return await resolvePublishConfigurations(publishers, null, this.packager, null, true)
}

scheduleUpload(publishConfig: PublishConfiguration, event: UploadTask, appInfo: AppInfo): void {
async scheduleUpload(publishConfig: PublishConfiguration, event: UploadTask, appInfo: AppInfo): Promise<void> {
if (publishConfig.provider === "generic") {
return
}

const publisher = this.getOrCreatePublisher(publishConfig, appInfo)
const publisher = await this.getOrCreatePublisher(publishConfig, appInfo)
if (publisher == null) {
log.debug(
{
Expand Down Expand Up @@ -204,7 +206,7 @@ export class PublishManager implements PublishContext {
break
}

this.scheduleUpload(publishConfig, event, this.getAppInfo(platformPackager))
await this.scheduleUpload(publishConfig, event, this.getAppInfo(platformPackager))
}
}

Expand All @@ -219,12 +221,12 @@ export class PublishManager implements PublishContext {
}
}

private getOrCreatePublisher(publishConfig: PublishConfiguration, appInfo: AppInfo): Publisher | null {
private async getOrCreatePublisher(publishConfig: PublishConfiguration, appInfo: AppInfo): Promise<Publisher | null> {
// to not include token into cache key
const providerCacheKey = safeStringifyJson(publishConfig)
let publisher = this.nameToPublisher.get(providerCacheKey)
if (publisher == null) {
publisher = createPublisher(this, appInfo.version, publishConfig, this.publishOptions, this.packager)
publisher = await createPublisher(this, appInfo.version, publishConfig, this.publishOptions, this.packager)
this.nameToPublisher.set(providerCacheKey, publisher)
log.info({ publisher: publisher!.toString() }, "publishing")
}
Expand Down Expand Up @@ -297,7 +299,13 @@ export async function getPublishConfigsForUpdateInfo(
return publishConfigs
}

export function createPublisher(context: PublishContext, version: string, publishConfig: PublishConfiguration, options: PublishOptions, packager: Packager): Publisher | null {
export async function createPublisher(
context: PublishContext,
version: string,
publishConfig: PublishConfiguration,
options: PublishOptions,
packager: Packager
): Promise<Publisher | null> {
if (debug.enabled) {
debug(`Create publisher: ${safeStringifyJson(publishConfig)}`)
}
Expand All @@ -317,13 +325,13 @@ export function createPublisher(context: PublishContext, version: string, publis
return null

default: {
const clazz = requireProviderClass(provider, packager)
const clazz = await requireProviderClass(provider, packager)
return clazz == null ? null : new clazz(context, publishConfig)
}
}
}

function requireProviderClass(provider: string, packager: Packager): any | null {
async function requireProviderClass(provider: string, packager: Packager): Promise<any | null> {
switch (provider) {
case "github":
return GitHubPublisher
Expand All @@ -347,18 +355,17 @@ function requireProviderClass(provider: string, packager: Packager): any | null
return BitbucketPublisher

default: {
const name = `electron-publisher-${provider}`
let module: any = null
try {
module = require(path.join(packager.buildResourcesDir, name + ".js"))
} catch (_ignored) {
log.debug({ path: path.join(packager.buildResourcesDir, name + ".js") }, "Unable to find publish provider in build resources")
}

if (module == null) {
module = require(name)
const extensions = [".mjs", ".js", ".cjs"]
const template = `electron-publisher-${provider}`
const name = (ext: string) => `${template}.${ext}`

const validPublisherFiles = extensions.map(ext => path.join(packager.buildResourcesDir, name(ext)))
for (const potentialFile of validPublisherFiles) {
if (existsSync(potentialFile)) {
return await resolveModule(packager.appInfo.type, potentialFile)
}
}
return module.default || module
log.warn({ path: log.filePath(packager.buildResourcesDir), template, extensionsChecked: extensions }, "unable to find publish provider in build resources")
}
}
}
Expand Down Expand Up @@ -515,7 +522,7 @@ async function getResolvedPublishConfig(
return options
}

const providerClass = requireProviderClass(options.provider, packager)
const providerClass = await requireProviderClass(options.provider, packager)
if (providerClass != null && providerClass.checkAndResolveOptions != null) {
await providerClass.checkAndResolveOptions(options, channelFromAppVersion, errorIfCannot)
return options
Expand Down
2 changes: 1 addition & 1 deletion packages/electron-builder/src/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ async function publishPackageWithTasks(

for (const newArtifact of uploadTasks) {
for (const publishConfiguration of publishConfigurations) {
publishManager.scheduleUpload(publishConfiguration, newArtifact, appInfo)
await publishManager.scheduleUpload(publishConfiguration, newArtifact, appInfo)
}
}

Expand Down
12 changes: 6 additions & 6 deletions test/src/ArtifactPublisherTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ testAndIgnoreApiRate("GitHub upload", async () => {
})

test.ifEnv(process.env.AWS_ACCESS_KEY_ID != null && process.env.AWS_SECRET_ACCESS_KEY != null)("S3 upload", async () => {
const publisher = createPublisher(publishContext, "0.0.1", { provider: "s3", bucket: "electron-builder-test" } as S3Options, {}, {} as any)!
await publisher.upload({ file: iconPath, arch: Arch.x64 })
const publisher = await createPublisher(publishContext, "0.0.1", { provider: "s3", bucket: "electron-builder-test" } as S3Options, {}, {} as any)
await publisher!.upload({ file: iconPath, arch: Arch.x64 })
// test overwrite
await publisher.upload({ file: iconPath, arch: Arch.x64 })
await publisher!.upload({ file: iconPath, arch: Arch.x64 })
})

test.ifEnv(process.env.DO_KEY_ID != null && process.env.DO_SECRET_KEY != null)("DO upload", async () => {
Expand All @@ -95,10 +95,10 @@ test.ifEnv(process.env.DO_KEY_ID != null && process.env.DO_SECRET_KEY != null)("
name: "electron-builder-test",
region: "nyc3",
}
const publisher = createPublisher(publishContext, "0.0.1", configuration, {}, {} as any)!
await publisher.upload({ file: iconPath, arch: Arch.x64 })
const publisher = await createPublisher(publishContext, "0.0.1", configuration, {}, {} as any)
await publisher!.upload({ file: iconPath, arch: Arch.x64 })
// test overwrite
await publisher.upload({ file: iconPath, arch: Arch.x64 })
await publisher!.upload({ file: iconPath, arch: Arch.x64 })
})

testAndIgnoreApiRate("prerelease", async () => {
Expand Down
Loading