Build the Linux and Windows desktop packages in a container from a Mac, with DOCKER choosing the container runtime
This commit is contained in:
parent
7910c5c184
commit
57ed02eecb
3 changed files with 33 additions and 18 deletions
12
README.md
12
README.md
|
|
@ -142,9 +142,10 @@ Wayland docks can identify it. It leaves existing user and system launchers alon
|
||||||
entry from a development run, and updates the entry when an update renames the AppImage. Windows
|
entry from a development run, and updates the entry when an update renames the AppImage. Windows
|
||||||
uses the executable's icon resources.
|
uses the executable's icon resources.
|
||||||
|
|
||||||
Linux packaging requires Linux. Windows packaging from Linux uses the pinned official
|
Linux packaging from macOS and Windows packaging from Linux or macOS use the pinned official
|
||||||
`electronuserland/builder` Wine image through Docker, mounting only a temporary copy of the prepared
|
`electronuserland/builder` Wine image through Docker, mounting only a temporary copy of the prepared
|
||||||
Electron project. Native addons need a target-OS ABI rebuild and cannot use this cross-build path.
|
Electron project. Set `DOCKER=podman` in `.env.local` to use Podman instead. Native addons need a
|
||||||
|
target-OS ABI rebuild and cannot use this cross-build path.
|
||||||
Native Windows preparation needs Bash on PATH, for example Git Bash. DMG creation requires macOS. On
|
Native Windows preparation needs Bash on PATH, for example Git Bash. DMG creation requires macOS. On
|
||||||
Linux, `pnpm run package:desktop:macos --dir` prepares unsigned bundles for inspection only, and
|
Linux, `pnpm run package:desktop:macos --dir` prepares unsigned bundles for inspection only, and
|
||||||
verifies nothing about the macOS runtime, Gatekeeper, or signing.
|
verifies nothing about the macOS runtime, Gatekeeper, or signing.
|
||||||
|
|
@ -206,12 +207,13 @@ run and prints the command to pick up from there.
|
||||||
| `fdroid` | reruns F-Droid's own preparation and build against the tag in a throwaway worktree |
|
| `fdroid` | reruns F-Droid's own preparation and build against the tag in a throwaway worktree |
|
||||||
| `play` | `bundleRelease` signed with the upload key, uploaded to a Play track as a draft |
|
| `play` | `bundleRelease` signed with the upload key, uploaded to a Play track as a draft |
|
||||||
| `ios` | `cap build ios` to an archive and IPA, uploaded with `altool` |
|
| `ios` | `cap build ios` to an archive and IPA, uploaded with `altool` |
|
||||||
| `desktop` | `package:desktop:*` for this OS: Linux and Windows from Linux, signed and notarized macOS from a Mac |
|
| `desktop` | `package:desktop:*` for this OS: Linux and Windows from Linux, all three from a Mac, with macOS signed and notarized |
|
||||||
| `gitea` | creates a draft release from the changelog, attaches the APK, desktop packages and update manifests, and publishes it once every platform is there |
|
| `gitea` | creates a draft release from the changelog, attaches the APK, desktop packages and update manifests, and publishes it once every platform is there |
|
||||||
| `zapstore` | `zsp publish zapstore.yaml` |
|
| `zapstore` | `zsp publish zapstore.yaml` |
|
||||||
|
|
||||||
Linux builds the Linux and Windows packages and a Mac builds the macOS ones, so a release takes a
|
A Mac builds every desktop package, the Linux and Windows ones in a container. Linux can't build
|
||||||
run on each, both ending in `gitea`. Gitea's latest release is the desktop update feed, so the release stays a
|
the macOS ones, so a release run from Linux needs a `pnpm release desktop gitea` on a Mac as well.
|
||||||
|
Gitea's latest release is the desktop update feed, so the release stays a
|
||||||
draft, hidden from updaters and Obtainium, until it has the APK and all three `latest*.yml`
|
draft, hidden from updaters and Obtainium, until it has the APK and all three `latest*.yml`
|
||||||
manifests. Each manifest is uploaded after the files it lists. A mobile-only release can't be
|
manifests. Each manifest is uploaded after the files it lists. A mobile-only release can't be
|
||||||
published, so package the desktop apps for every release.
|
published, so package the desktop apps for every release.
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,11 @@ import {loadEnv} from "vite"
|
||||||
const root = fileURLToPath(new URL("../", import.meta.url))
|
const root = fileURLToPath(new URL("../", import.meta.url))
|
||||||
const [target, option, ...rest] = process.argv.slice(2)
|
const [target, option, ...rest] = process.argv.slice(2)
|
||||||
const platforms = {linux: "--linux", windows: "--win", macos: "--mac"}
|
const platforms = {linux: "--linux", windows: "--win", macos: "--mac"}
|
||||||
const env = {...process.env, ...loadEnv("production", root, "VITE_"), NODE_ENV: "production"}
|
const env = {
|
||||||
|
...process.env,
|
||||||
|
...loadEnv("production", root, ["VITE_", "DOCKER"]),
|
||||||
|
NODE_ENV: "production",
|
||||||
|
}
|
||||||
|
|
||||||
const run = (command, args, options = {}) =>
|
const run = (command, args, options = {}) =>
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
|
|
@ -70,12 +74,13 @@ try {
|
||||||
// --dir replaces configured targets, including their architectures.
|
// --dir replaces configured targets, including their architectures.
|
||||||
args.push("--x64", "--arm64")
|
args.push("--x64", "--arm64")
|
||||||
}
|
}
|
||||||
if (target === "windows" && process.platform === "linux") {
|
if (
|
||||||
|
(target === "windows" && process.platform !== "win32") ||
|
||||||
|
(target === "linux" && process.platform !== "linux")
|
||||||
|
) {
|
||||||
const files = await readdir(join(root, "electron/vendor"), {recursive: true})
|
const files = await readdir(join(root, "electron/vendor"), {recursive: true})
|
||||||
if (files.some(file => file.endsWith(".node"))) {
|
if (files.some(file => file.endsWith(".node"))) {
|
||||||
throw new Error(
|
throw new Error(`Native Electron addons require a rebuild before packaging for ${target}`)
|
||||||
"Native Electron addons require a Windows ABI rebuild before packaging on Windows",
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
await mkdir(join(root, "electron/dist"), {recursive: true})
|
await mkdir(join(root, "electron/dist"), {recursive: true})
|
||||||
const directory = await mkdtemp(join(root, "electron/dist/package-"))
|
const directory = await mkdtemp(join(root, "electron/dist/package-"))
|
||||||
|
|
@ -92,7 +97,7 @@ try {
|
||||||
]) {
|
]) {
|
||||||
await cp(join(root, "electron", file), join(directory, "electron", file), {recursive: true})
|
await cp(join(root, "electron", file), join(directory, "electron", file), {recursive: true})
|
||||||
}
|
}
|
||||||
await run("docker", [
|
await run(env.DOCKER || "docker", [
|
||||||
"run",
|
"run",
|
||||||
"--rm",
|
"--rm",
|
||||||
"--platform",
|
"--platform",
|
||||||
|
|
|
||||||
|
|
@ -107,8 +107,13 @@ const apkMetadata = async () => {
|
||||||
return element
|
return element
|
||||||
}
|
}
|
||||||
|
|
||||||
const desktopTargets = {darwin: ["macos"], linux: ["linux", "windows"], win32: []}
|
const desktopTargets = {
|
||||||
|
darwin: ["macos", "linux", "windows"],
|
||||||
|
linux: ["linux", "windows"],
|
||||||
|
win32: [],
|
||||||
|
}
|
||||||
const hostTargets = desktopTargets[process.platform] ?? []
|
const hostTargets = desktopTargets[process.platform] ?? []
|
||||||
|
const docker = process.env.DOCKER || "docker"
|
||||||
|
|
||||||
// Gitea's latest release is the desktop update feed, so it only goes public once every platform's
|
// Gitea's latest release is the desktop update feed, so it only goes public once every platform's
|
||||||
// manifest is on it
|
// manifest is on it
|
||||||
|
|
@ -292,15 +297,16 @@ const steps = [
|
||||||
missing: () => [
|
missing: () => [
|
||||||
...(hostTargets.length > 0 ? [] : [`desktop packaging on ${process.platform}`]),
|
...(hostTargets.length > 0 ? [] : [`desktop packaging on ${process.platform}`]),
|
||||||
...(existsSync(join(root, "electron/node_modules")) ? [] : ["electron dependencies"]),
|
...(existsSync(join(root, "electron/node_modules")) ? [] : ["electron dependencies"]),
|
||||||
...(hostTargets.includes("windows") && !installed("docker") ? ["docker"] : []),
|
...(hostTargets.includes("windows") && !installed(docker) ? [docker] : []),
|
||||||
...(hostTargets.includes("macos")
|
...(hostTargets.includes("macos")
|
||||||
? missingEnv("CSC_NAME", "ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH")
|
? missingEnv("CSC_NAME", "ASC_KEY_ID", "ASC_ISSUER_ID", "ASC_KEY_PATH")
|
||||||
: []),
|
: []),
|
||||||
],
|
],
|
||||||
setup: [
|
setup: [
|
||||||
"Run npm ci --prefix electron. Each platform's packages have to be built on that platform,",
|
"Run npm ci --prefix electron. Each platform's packages have to be built on that platform,",
|
||||||
"so run pnpm release desktop gitea on the others to add theirs to the same release.",
|
"so on Linux run pnpm release desktop gitea on a Mac to add the macOS ones to the release.",
|
||||||
"Linux also cross-builds the Windows installer, which needs docker.",
|
"Linux and macOS build the other platforms' packages in a container, which needs docker,",
|
||||||
|
"or set DOCKER=podman in .env.local.",
|
||||||
"macOS only installs updates to a signed app, so macOS packages are signed and notarized:",
|
"macOS only installs updates to a signed app, so macOS packages are signed and notarized:",
|
||||||
"set CSC_NAME to the name of the Developer ID Application certificate in your keychain,",
|
"set CSC_NAME to the name of the Developer ID Application certificate in your keychain,",
|
||||||
"without its prefix, and the ASC_* key the ios step uses notarizes them.",
|
"without its prefix, and the ASC_* key the ios step uses notarizes them.",
|
||||||
|
|
@ -324,9 +330,11 @@ const steps = [
|
||||||
.flat()
|
.flat()
|
||||||
.filter(target => !hostTargets.includes(target))
|
.filter(target => !hostTargets.includes(target))
|
||||||
|
|
||||||
followUps.push(
|
if (elsewhere.length > 0) {
|
||||||
`Desktop: ${elsewhere.join(" and ")} packages have to be built on those platforms, then attached with pnpm release desktop gitea`,
|
followUps.push(
|
||||||
)
|
`Desktop: ${elsewhere.join(" and ")} packages have to be built on those platforms, then attached with pnpm release desktop gitea`,
|
||||||
|
)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue