Refactor Windows installer scripts and enhance build process
Some checks failed
farmcontrol/farmcontrol-server/pipeline/head There was a failure building this commit
Some checks failed
farmcontrol/farmcontrol-server/pipeline/head There was a failure building this commit
- Updated farmcontrol-server.nsi to simplify setup file handling by defining APP_SOURCE_DIR and removing unnecessary variables. - Modified installer.nsh to reference the correct launcher executable path. - Refactored build-windows-nsis.ps1 to accept APP_DIR instead of individual setup file parameters, streamlining the build process. - Introduced expand-windows-installer.mjs for handling decompression and extraction of Windows app archives, improving artifact management. - Enhanced finalize-desktop-artifacts.mjs to integrate the new expansion process and ensure proper cleanup of temporary files.
This commit is contained in:
parent
ebc3920d65
commit
72cea3a740
@ -9,16 +9,8 @@
|
||||
!define VERSION "1.0.0"
|
||||
!endif
|
||||
|
||||
!ifndef SETUP_EXE_NAME
|
||||
!define SETUP_EXE_NAME "Farm Control Server-Setup.exe"
|
||||
!endif
|
||||
|
||||
!ifndef SETUP_ARCHIVE_NAME
|
||||
!define SETUP_ARCHIVE_NAME "Farm Control Server-Setup.tar.zst"
|
||||
!endif
|
||||
|
||||
!ifndef SETUP_METADATA_NAME
|
||||
!define SETUP_METADATA_NAME "Farm Control Server-Setup.metadata.json"
|
||||
!ifndef APP_SOURCE_DIR
|
||||
!define APP_SOURCE_DIR "."
|
||||
!endif
|
||||
|
||||
Name "Farm Control Server"
|
||||
@ -39,20 +31,8 @@ RequestExecutionLevel admin
|
||||
|
||||
Section "Farm Control Server" SecMain
|
||||
SetOutPath $INSTDIR
|
||||
File /r "${APP_SOURCE_DIR}\*"
|
||||
|
||||
File "${SETUP_EXE_NAME}"
|
||||
File "${SETUP_ARCHIVE_NAME}"
|
||||
File "${SETUP_METADATA_NAME}"
|
||||
|
||||
DetailPrint "Running Farm Control Server setup..."
|
||||
ExecWait '"$INSTDIR\${SETUP_EXE_NAME}" /S' $0
|
||||
StrCmp $0 "0" setup_ok setup_failed
|
||||
|
||||
setup_failed:
|
||||
MessageBox MB_ICONSTOP "Farm Control Server setup failed (exit code $0)."
|
||||
Abort
|
||||
|
||||
setup_ok:
|
||||
!insertmacro customInstall
|
||||
|
||||
WriteRegStr HKLM "Software\Tom Butcher\Farm Control Server" "InstallDir" $INSTDIR
|
||||
@ -75,12 +55,7 @@ SectionEnd
|
||||
Section "Uninstall"
|
||||
!insertmacro customUnInstall
|
||||
|
||||
Delete "$INSTDIR\${SETUP_EXE_NAME}"
|
||||
Delete "$INSTDIR\${SETUP_ARCHIVE_NAME}"
|
||||
Delete "$INSTDIR\${SETUP_METADATA_NAME}"
|
||||
Delete "$INSTDIR\launcher.exe"
|
||||
Delete "$INSTDIR\Uninstall.exe"
|
||||
|
||||
RMDir /r "$INSTDIR"
|
||||
|
||||
DeleteRegKey HKLM "Software\Tom Butcher\Farm Control Server"
|
||||
|
||||
@ -3,10 +3,10 @@
|
||||
DeleteRegKey HKCR "farmcontrolserver"
|
||||
WriteRegStr HKCR "farmcontrolserver" "" "URL:farmcontrolserver"
|
||||
WriteRegStr HKCR "farmcontrolserver" "URL Protocol" ""
|
||||
WriteRegStr HKCR "farmcontrolserver\DefaultIcon" "" "$INSTDIR\launcher.exe"
|
||||
WriteRegStr HKCR "farmcontrolserver\DefaultIcon" "" "$INSTDIR\bin\launcher.exe"
|
||||
WriteRegStr HKCR "farmcontrolserver\shell" "" ""
|
||||
WriteRegStr HKCR "farmcontrolserver\shell\Open" "" ""
|
||||
WriteRegStr HKCR "farmcontrolserver\shell\Open\command" "" '"$INSTDIR\launcher.exe" "%1"'
|
||||
WriteRegStr HKCR "farmcontrolserver\shell\Open\command" "" '"$INSTDIR\bin\launcher.exe" "%1"'
|
||||
!macroend
|
||||
|
||||
!macro customUnInstall
|
||||
|
||||
@ -1,12 +1,6 @@
|
||||
param(
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$SetupExe,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$SetupArchive,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$SetupMetadata,
|
||||
[string]$AppDir,
|
||||
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string]$OutputExe,
|
||||
@ -47,17 +41,8 @@ if (Test-Path $workDir) {
|
||||
}
|
||||
New-Item -ItemType Directory -Path $workDir | Out-Null
|
||||
|
||||
$setupExePath = (Resolve-Path -LiteralPath $SetupExe).Path
|
||||
$setupArchivePath = (Resolve-Path -LiteralPath $SetupArchive).Path
|
||||
$setupMetadataPath = (Resolve-Path -LiteralPath $SetupMetadata).Path
|
||||
$appDirPath = (Resolve-Path -LiteralPath $AppDir).Path
|
||||
|
||||
$setupExeName = Split-Path $setupExePath -Leaf
|
||||
$setupArchiveName = Split-Path $setupArchivePath -Leaf
|
||||
$setupMetadataName = Split-Path $setupMetadataPath -Leaf
|
||||
|
||||
Copy-Item -LiteralPath $setupExePath -Destination (Join-Path $workDir $setupExeName)
|
||||
Copy-Item -LiteralPath $setupArchivePath -Destination (Join-Path $workDir $setupArchiveName)
|
||||
Copy-Item -LiteralPath $setupMetadataPath -Destination (Join-Path $workDir $setupMetadataName)
|
||||
Copy-Item -LiteralPath $nsiPath -Destination (Join-Path $workDir "farmcontrol-server.nsi")
|
||||
Copy-Item -LiteralPath $installerInclude -Destination (Join-Path $workDir "installer.nsh")
|
||||
|
||||
@ -72,9 +57,7 @@ $makensisArgs = @(
|
||||
"/NOCD"
|
||||
"/DOUTFILE=$outputExePath"
|
||||
"/DVERSION=$Version"
|
||||
"/DSETUP_EXE_NAME=$setupExeName"
|
||||
"/DSETUP_ARCHIVE_NAME=$setupArchiveName"
|
||||
"/DSETUP_METADATA_NAME=$setupMetadataName"
|
||||
"/DAPP_SOURCE_DIR=$appDirPath"
|
||||
(Join-Path $workDir "farmcontrol-server.nsi")
|
||||
)
|
||||
|
||||
|
||||
123
scripts/expand-windows-installer.mjs
Normal file
123
scripts/expand-windows-installer.mjs
Normal file
@ -0,0 +1,123 @@
|
||||
import {
|
||||
existsSync,
|
||||
mkdirSync,
|
||||
readdirSync,
|
||||
rmSync,
|
||||
statSync,
|
||||
} from "node:fs";
|
||||
import path from "node:path";
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||
|
||||
function findZstdDecompressCommand() {
|
||||
const systemZstd = spawnSync("zstd", ["--version"], { encoding: "utf8" });
|
||||
if (systemZstd.status === 0) {
|
||||
return { command: "zstd", args: (inputPath, outputPath) => [
|
||||
"-d",
|
||||
"-f",
|
||||
"-o",
|
||||
outputPath,
|
||||
inputPath,
|
||||
] };
|
||||
}
|
||||
|
||||
const hostArch = process.arch === "arm64" ? "arm64" : "x64";
|
||||
const candidates = [
|
||||
path.join(
|
||||
rootDir,
|
||||
"node_modules/electrobun/dist-win-x64/zig-zstd",
|
||||
hostArch,
|
||||
"zig-zstd.exe",
|
||||
),
|
||||
path.join(
|
||||
rootDir,
|
||||
"node_modules/electrobun/dist-win-x64/zig-zstd",
|
||||
"x64",
|
||||
"zig-zstd.exe",
|
||||
),
|
||||
path.join(rootDir, "node_modules/electrobun/dist-win-x64", "zig-zstd"),
|
||||
];
|
||||
|
||||
for (const candidate of candidates) {
|
||||
if (existsSync(candidate)) {
|
||||
return {
|
||||
command: candidate,
|
||||
args: (inputPath, outputPath) => [
|
||||
"decompress",
|
||||
"-i",
|
||||
inputPath,
|
||||
"-o",
|
||||
outputPath,
|
||||
"--no-timing",
|
||||
],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function decompressTarZst(inputPath, outputPath) {
|
||||
const zstd = findZstdDecompressCommand();
|
||||
if (!zstd) {
|
||||
throw new Error(
|
||||
"expand-windows-installer: zstd not found (install zstd or use electrobun dist binaries)",
|
||||
);
|
||||
}
|
||||
|
||||
const result = spawnSync(zstd.command, zstd.args(inputPath, outputPath), {
|
||||
stdio: "inherit",
|
||||
});
|
||||
|
||||
if (result.status !== 0) {
|
||||
throw new Error(
|
||||
`expand-windows-installer: decompression failed (exit ${result.status ?? 1})`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function expandWindowsAppFromArchive(setupArchivePath, parentDir) {
|
||||
const resolvedArchive = path.resolve(setupArchivePath);
|
||||
if (!existsSync(resolvedArchive)) {
|
||||
throw new Error(`expand-windows-installer: archive not found: ${resolvedArchive}`);
|
||||
}
|
||||
|
||||
const workDir = path.join(path.resolve(parentDir), ".expanded-app");
|
||||
const tarPath = path.join(workDir, "app.tar");
|
||||
|
||||
rmSync(workDir, { recursive: true, force: true });
|
||||
mkdirSync(workDir, { recursive: true });
|
||||
|
||||
decompressTarZst(resolvedArchive, tarPath);
|
||||
|
||||
const extractTar = spawnSync("tar", ["-xf", tarPath, "-C", workDir], {
|
||||
stdio: "inherit",
|
||||
});
|
||||
|
||||
if (extractTar.status !== 0) {
|
||||
rmSync(workDir, { recursive: true, force: true });
|
||||
throw new Error(
|
||||
`expand-windows-installer: tar extraction failed (exit ${extractTar.status ?? 1})`,
|
||||
);
|
||||
}
|
||||
|
||||
const appDir = readdirSync(workDir)
|
||||
.filter((entry) => entry !== "app.tar" && entry !== "__MACOSX")
|
||||
.map((entry) => path.join(workDir, entry))
|
||||
.find((entryPath) => statSync(entryPath).isDirectory());
|
||||
|
||||
if (!appDir) {
|
||||
rmSync(workDir, { recursive: true, force: true });
|
||||
throw new Error("expand-windows-installer: app folder not found in archive");
|
||||
}
|
||||
|
||||
console.log(`expand-windows-installer: expanded ${appDir}`);
|
||||
return appDir;
|
||||
}
|
||||
|
||||
export function cleanExpandedWindowsApp(parentDir) {
|
||||
const workDir = path.join(path.resolve(parentDir), ".expanded-app");
|
||||
rmSync(workDir, { recursive: true, force: true });
|
||||
}
|
||||
@ -16,6 +16,10 @@ import {
|
||||
getReleaseArtifactName,
|
||||
getReleaseVersion,
|
||||
} from "./release-artifact-utils.mjs";
|
||||
import {
|
||||
cleanExpandedWindowsApp,
|
||||
expandWindowsAppFromArchive,
|
||||
} from "./expand-windows-installer.mjs";
|
||||
|
||||
const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const packageJson = JSON.parse(
|
||||
@ -299,7 +303,15 @@ function buildMacPkg(appBundlePath, arch) {
|
||||
return pkgPath;
|
||||
}
|
||||
|
||||
function buildWindowsNsis(installerFiles, arch) {
|
||||
function cleanWinBuildDir(arch) {
|
||||
const platformDir = path.join(getBuildRoot(), `stable-win-${arch}`);
|
||||
if (existsSync(platformDir)) {
|
||||
rmSync(platformDir, { recursive: true, force: true });
|
||||
console.log(`Removed build output ${platformDir}`);
|
||||
}
|
||||
}
|
||||
|
||||
function buildWindowsNsis(appDir, arch) {
|
||||
const scriptPath = path.join(rootDir, "scripts/build-windows-nsis.ps1");
|
||||
const exePath = path.join(
|
||||
artifactDir,
|
||||
@ -324,12 +336,8 @@ function buildWindowsNsis(installerFiles, arch) {
|
||||
"Bypass",
|
||||
"-File",
|
||||
scriptPath,
|
||||
"-SetupExe",
|
||||
installerFiles.setupExe,
|
||||
"-SetupArchive",
|
||||
installerFiles.setupArchive,
|
||||
"-SetupMetadata",
|
||||
installerFiles.setupMetadata,
|
||||
"-AppDir",
|
||||
appDir,
|
||||
"-OutputExe",
|
||||
exePath,
|
||||
"-Version",
|
||||
@ -376,19 +384,31 @@ if (targetOs === "macos") {
|
||||
const arch = getReleaseArch(process.env.ELECTROBUN_ARCH || "x64");
|
||||
const installerFiles = findWindowsInstallerFiles();
|
||||
|
||||
if (!installerFiles) {
|
||||
if (!installerFiles?.setupArchive) {
|
||||
throw new Error(
|
||||
"Could not find the Windows installer files (setup exe, archive, and metadata)",
|
||||
"Could not find the Windows setup archive (.tar.zst) to expand",
|
||||
);
|
||||
}
|
||||
|
||||
const published = [buildWindowsNsis(installerFiles, arch)];
|
||||
const platformDir = path.dirname(installerFiles.setupArchive);
|
||||
const appDir = expandWindowsAppFromArchive(
|
||||
installerFiles.setupArchive,
|
||||
platformDir,
|
||||
);
|
||||
|
||||
let published;
|
||||
try {
|
||||
published = [buildWindowsNsis(appDir, arch)];
|
||||
|
||||
if (installerFiles.setupZip) {
|
||||
published.push(publishArtifact(installerFiles.setupZip, arch, "zip"));
|
||||
}
|
||||
} finally {
|
||||
cleanExpandedWindowsApp(platformDir);
|
||||
}
|
||||
|
||||
cleanStagingArtifacts(published.map((filePath) => path.basename(filePath)));
|
||||
cleanWinBuildDir(arch);
|
||||
} else {
|
||||
console.log(
|
||||
"finalize-desktop-artifacts: no desktop packaging configured for",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user