electron-builder icon indicating copy to clipboard operation
electron-builder copied to clipboard

Is it possible to run afterPack on a per-target basis?

Open Nantris opened this issue 9 months ago • 15 comments

I'm working on a workaround for https://github.com/electron/electron/issues/42510 but it it seems like I can't target only AppImage and it would affect Snap and other Linux targets too.

Is there any way I can modify only the AppImage?

Of course, if I get this working I'll share what I've got!

Nantris avatar Mar 28 '25 20:03 Nantris

Same I am looking for a hook per target but for auto-update. So far what I am using is a custom publish provider to hack into the build process, it works but its a mess.

Sytten avatar Mar 28 '25 21:03 Sytten

@Sytten can you clarify what you're looking for exactly?

Nantris avatar Mar 28 '25 21:03 Nantris

I need a hook to create a file in the resources different based on the target.

Sytten avatar Mar 28 '25 21:03 Sytten

@mmaietta I can code this, but I don't have the authority / experience to decide what it should look like. I think something like beforeTargetBuild would be good.

Sytten avatar Apr 01 '25 14:04 Sytten

So the limitation is within PlatformPackager as afterPack accepts a list of targets, which the Packager then assembles per-Target. The downside here is that compressed archives (tar.gz, zip, etc.) all are within the same ArchiveTarget that iterates through it separately, so PlatformPackager doesn't have insight into when a specific archive is created. All archives are created from the same linux-unpacked folder though, so inserting a file into resources will be included in all archives.

I'm wondering if your usecase might be best solved with the event artifactBuildStarted which has targetPresentableName for you to key specific logic to the destination archive. https://www.electron.build/app-builder-lib.interface.configuration#artifactbuildstarted

I'm thinking something along the lines of

module.exports = (context: ArtifactBuildStarted) => {
	const yourFile = "<path to your file>"
	const unpackedResources = path.resolve(path.dirname(context.file), "linux-unpacked", "resources"))
	const dest = path.join(unpackedResources, path.basename(yourFile))

 	if (context.targetPresentableName === "AppImage") {
 		fs.copySync(yourFile, dest)
 	} else if (fs.existSync(dest){
 		fs.rm(dest)
 	}
}

This would insert or remove your file from resources on a per-target basis.

mmaietta avatar Apr 01 '25 15:04 mmaietta

Interesting, I will try it out for sure. I thought this was async due to the Started name, but it might not.

Sytten avatar Apr 01 '25 20:04 Sytten

It can contain async operations, as it's still awaited in code when the event is emitted. This is to maintain consistency with other hooks, but also prevent side effects of files being manipulated while electron-builder's packaging phase is in progress.

mmaietta avatar Apr 01 '25 22:04 mmaietta

That seems promising and I'd love to leverage what already exists, but it seems too late to modify the internals of the AppImage at that phase unless I repack it.

The processing and tedium of repacking isn't too onerous but I do wonder if that might break auto-updates or anything by potentially changing the hash or blockmap?

Nantris avatar Apr 02 '25 03:04 Nantris

As far as I am understand this hook would allow to modify the permission of the sandbox binary before its packed in the appimage which should work around the permission issue. I am also facing this problem, so I will also try to dig into it.

The publish is done after that hook and worst case you can customize the auto update provider (this is what I did).

Sytten avatar Apr 02 '25 05:04 Sytten

I was able to make headway with this method. It's a little clunky. It would be nice if the context included the appOutDir but it's a minor thing.

Nantris avatar Apr 02 '25 19:04 Nantris

I see no reason why not to support that. I don't have time currently to work on this specifically, as I'm focused on other bugs and trying to balance with work. Feel free to open up a PR if you can!

mmaietta avatar Apr 03 '25 03:04 mmaietta

@mmaietta Another thing I realized while doing some testing, there is a flag called isAsyncSupported. Some targets will be true and will run concurrently. We likely need a way to disable that otherwise artifactBuildStarted will just override each other. I can take a look at how this currently works but it's a big limitation of the hook for sure.

Sytten avatar Apr 03 '25 20:04 Sytten

Hmmm valid point. Modifying any of the unpacked directories during a parallel packaging would be an issue, especially more so with the upcoming experimental config property for concurrent builds of targets+archs https://github.com/electron-userland/electron-builder/blob/106640dd42a3db08bfbe3a3a32fe333e93ba5c10/packages/app-builder-lib/src/platformPackager.ts#L170-L173

We could theoretically have an unpacked directory for each archive target, but holy moly, that would tremendously increase the footprint/size-taken of each build.

mmaietta avatar Apr 04 '25 04:04 mmaietta

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 30 days.

github-actions[bot] avatar May 05 '25 00:05 github-actions[bot]

Please see my feature request and workaround here: https://github.com/electron-userland/electron-builder/issues/9296

softworkz avatar Oct 03 '25 02:10 softworkz