feat(updater): add native Windows ARM64 installer

This commit is contained in:
GeekMr committed 2026-09-24 14:11:16 +08:00
1 parent 9dc058d127
commit ba2e7eb756
11 files changed
+106 -18

No files matched your search

+8 -2
View File
@@ -9,6 +9,9 @@ param(
[ValidateSet('NebulaTerminal', 'Pebrel')]
[string] $PackageBrand = 'Pebrel',
[ValidateSet('x64', 'arm64')]
[string] $Architecture = 'x64',
[switch] $SkipBuild,
# 与 -SkipBuild 联用:跳过「exe 必须比源码新」的陈旧检查。仅用于脚本
# 自测;发布安装包一律走全新构建。
@@ -57,7 +60,7 @@ if ([string]::IsNullOrWhiteSpace($TargetDirectory)) {
}
$cargoTargetRoot = [System.IO.Path]::GetFullPath($TargetDirectory)
$targetRoot = Join-Path $cargoTargetRoot $Configuration
$setupPath = Join-Path $outputRoot "$PackageBrand-v$Version-windows-x64-setup.exe"
$setupPath = Join-Path $outputRoot "$PackageBrand-v$Version-windows-$Architecture-setup.exe"
$requiredFiles = @(
(Join-Path $targetRoot 'pebrel.exe'),
@@ -94,6 +97,8 @@ if ($missing.Count -ne 0) {
}
$packagedExe = Join-Path $targetRoot 'pebrel.exe'
. (Join-Path $PSScriptRoot 'windows-package-architecture.ps1')
Assert-WindowsPackageArchitecture -Root $targetRoot -Architecture $Architecture
if ($PackageBrand -eq 'Pebrel' -and (Get-Item -LiteralPath $packagedExe).VersionInfo.ProductName -ne 'Pebrel') {
throw 'Pebrel packages require a freshly built Pebrel executable, not renamed Nebula binaries.'
}
@@ -145,6 +150,7 @@ if ($ValidateOnly) {
InstallerScript = $installerScript
Version = $Version
Configuration = $Configuration
Architecture = $Architecture
Files = $requiredFiles.Count
} | Format-List
return
@@ -202,7 +208,7 @@ if (-not $translationValid) {
Push-Location $PSScriptRoot
try {
& $InnoCompiler "/DAppVersion=$Version" "/DNumericVersion=$numericVersion" "/DConfiguration=$Configuration" "/DPackageBrand=$PackageBrand" "/DBuildRoot=$targetRoot" "/O$outputRoot" $installerScript
& $InnoCompiler "/DAppVersion=$Version" "/DNumericVersion=$numericVersion" "/DConfiguration=$Configuration" "/DPackageBrand=$PackageBrand" "/DArchitecture=$Architecture" "/DBuildRoot=$targetRoot" "/O$outputRoot" $installerScript
if ($LASTEXITCODE -ne 0) {
throw "Inno Setup compilation failed with exit code $LASTEXITCODE"
}
+9 -1
View File
@@ -14,6 +14,10 @@
#define PackageBrand "Pebrel"
#endif
#ifndef Architecture
#define Architecture "x64"
#endif
#define RepoRoot ".."
#ifndef BuildRoot
#define BuildRoot RepoRoot + "\target\" + Configuration
@@ -50,13 +54,17 @@ DisableWelcomePage=no
DisableDirPage=no
DisableReadyPage=no
PrivilegesRequired=lowest
#if Architecture == "arm64"
ArchitecturesAllowed=arm64
#else
ArchitecturesAllowed=x64compatible
#endif
MinVersion=10.0.17763
LicenseFile={#RepoRoot}\LICENSE
SetupIconFile={#RepoRoot}\nebula_app\windows\nebula.ico
UninstallDisplayIcon={app}\pebrel.exe
OutputDir={#RepoRoot}\dist
OutputBaseFilename={#PackageBrand}-v{#AppVersion}-windows-x64-setup
OutputBaseFilename={#PackageBrand}-v{#AppVersion}-windows-{#Architecture}-setup
Compression=lzma2/max
SolidCompression=yes
WizardStyle=modern
+2
View File
@@ -45,6 +45,8 @@ def expected_asset_names(version: str) -> tuple[str, ...]:
)
if tuple(map(int, version.split("."))) >= (1, 9, 0):
names += (f"Pebrel-v{version}-windows-arm64.zip",)
if tuple(map(int, version.split("."))) > (1, 9, 0):
names += (f"Pebrel-v{version}-windows-arm64-setup.exe",)
# The old-name installer was retired from 1.7.0; retain historical manifests.
if tuple(map(int, version.split("."))) < (1, 7, 0):
names += (f"NebulaTerminal-{version}-windows-x64-setup.exe",)
+2 -1
View File
@@ -34,7 +34,8 @@ $requiredPatterns = [ordered]@{
'Pebrel display name' = 'AppName=Pebrel'
'compatible installer identity' = 'AppId=\{\{61022144-7D0A-4E54-94F2-C329A8F58656\}'
'Pebrel default asset name' = '#define PackageBrand "Pebrel"'
'explicit package brand' = 'OutputBaseFilename=\{#PackageBrand\}-v\{#AppVersion\}-windows-x64-setup'
'architecture-specific package name' = 'OutputBaseFilename=\{#PackageBrand\}-v\{#AppVersion\}-windows-\{#Architecture\}-setup'
'native ARM64 gate' = '(?s)#if Architecture == "arm64".*ArchitecturesAllowed=arm64'
'localized Chinese context menu label' = 'chinesesimplified\.OpenInPebrel=\S.+'
'localized WSL context menu label' = 'english\.OpenInPebrelWsl=Open in Pebrel'
'localized Chinese WSL context menu label' = 'chinesesimplified\.OpenInPebrelWsl=\S.+'
+6 -1
View File
@@ -74,9 +74,14 @@ class PebrelBrandingTests(unittest.TestCase):
self.assertIn("Stale binary:", source)
installer = self.source("scripts/installer.iss")
self.assertIn('#define PackageBrand "Pebrel"', installer)
self.assertIn("OutputBaseFilename={#PackageBrand}-v{#AppVersion}-windows-x64-setup", installer)
self.assertIn(
"OutputBaseFilename={#PackageBrand}-v{#AppVersion}-windows-{#Architecture}-setup",
installer,
)
builder = self.source("scripts/build-installer.ps1")
self.assertIn("[ValidateSet('x64', 'arm64')]", builder)
self.assertIn('"/DPackageBrand=$PackageBrand"', builder)
self.assertIn('"/DArchitecture=$Architecture"', builder)
def test_update_asset_validation_shares_current_and_legacy_names(self):
check = self.source("nebula_app/src/update_check.rs")
+13 -2
View File
@@ -106,7 +106,8 @@ class StableReleaseTests(unittest.TestCase):
arm = workflow.split("\n windows-arm64:\n", 1)[1].split("\n aggregate:\n", 1)[0]
for required in ("runs-on: windows-11-arm", "host: aarch64-pc-windows-msvc",
"-Architecture arm64", "windows-arm64-report.json",
"scripts/build-windows-product.ps1", "--platform windows-aarch64"):
"scripts/build-windows-product.ps1", "scripts/build-installer.ps1",
"windows-arm64-setup.exe", "--platform windows-aarch64"):
self.assertIn(required, arm)
self.assertNotIn("continue-on-error", arm)
self.assertNotIn("always()", aggregate)
@@ -140,7 +141,8 @@ class StableReleaseTests(unittest.TestCase):
for version in ("1.7.0", "1.7.1", "1.10.0", "2.0.0"):
with self.subTest(version=version):
names = expected_asset_names(version)
self.assertEqual(len(names), 8 if tuple(map(int, version.split('.'))) >= (1, 9, 0) else 7)
parsed = tuple(map(int, version.split('.')))
self.assertEqual(len(names), 9 if parsed > (1, 9, 0) else 8 if parsed >= (1, 9, 0) else 7)
self.assertIn(f"Pebrel-v{version}-windows-x64-setup.exe", names)
self.assertNotIn(f"NebulaTerminal-{version}-windows-x64-setup.exe", names)
@@ -156,6 +158,15 @@ class StableReleaseTests(unittest.TestCase):
with self.assertRaisesRegex(StableReleaseError, "missing: Pebrel-v1.9.0-windows-arm64.zip"):
validate_assets(root, version)
def test_post_190_requires_native_windows_arm64_installer(self) -> None:
self.assertNotIn("Pebrel-v1.9.0-windows-arm64-setup.exe", expected_asset_names("1.9.0"))
for version in ("1.9.1", "1.10.0", "2.0.0"):
with self.subTest(version=version):
self.assertIn(
f"Pebrel-v{version}-windows-arm64-setup.exe",
expected_asset_names(version),
)
def test_17_assets_reject_retired_alias_and_missing_installer(self) -> None:
version = "1.7.0"
with tempfile.TemporaryDirectory() as directory: