Harden Windows checkpoint packaging

This commit is contained in:
Codex 2026-10-24 16:55:05 +02:00
parent f87135657c
commit 4d6bf60895
3 changed files with 41 additions and 3 deletions

View file

@ -79,6 +79,12 @@ if ($PSCmdlet.ShouldProcess($addonDestination, "Stage no-device addon")) {
New-Item -ItemType Directory -Force -Path $addonDestination | Out-Null New-Item -ItemType Directory -Force -Path $addonDestination | Out-Null
Copy-Item -Path (Join-Path $addonSource "*") ` Copy-Item -Path (Join-Path $addonSource "*") `
-Destination $addonDestination -Recurse -Force -Destination $addonDestination -Recurse -Force
Get-ChildItem -LiteralPath $addonDestination -Recurse -Directory -Force |
Where-Object { $_.Name -eq "__pycache__" } |
Remove-Item -Recurse -Force
Get-ChildItem -LiteralPath $addonDestination -Recurse -File -Force |
Where-Object { $_.Extension -eq ".pyc" } |
Remove-Item -Force
} }
$prepareArguments = @{ $prepareArguments = @{
@ -86,10 +92,21 @@ $prepareArguments = @{
BuildWindowsBundle = $true BuildWindowsBundle = $true
AllowStagedPirateRayAddon = $true AllowStagedPirateRayAddon = $true
} }
$pyInstallerSiteCustomize = Join-Path $PSScriptRoot "pyinstaller-sitecustomize"
$previousPythonPath = $env:PYTHONPATH
try {
$env:PYTHONPATH = if ($previousPythonPath) {
"$pyInstallerSiteCustomize;$previousPythonPath"
} else {
$pyInstallerSiteCustomize
}
& (Join-Path $PSScriptRoot "prepare_rayforge_build.ps1") @prepareArguments & (Join-Path $PSScriptRoot "prepare_rayforge_build.ps1") @prepareArguments
if ($LASTEXITCODE -ne 0) { if ($LASTEXITCODE -ne 0) {
throw "Pinned Rayforge Windows bundle build failed" throw "Pinned Rayforge Windows bundle build failed"
} }
} finally {
$env:PYTHONPATH = $previousPythonPath
}
$bundleName = "rayforge-vpirateray-$shortCommit" $bundleName = "rayforge-vpirateray-$shortCommit"
$bundleDirectory = Join-Path $checkout "dist\$bundleName" $bundleDirectory = Join-Path $checkout "dist\$bundleName"
@ -132,6 +149,10 @@ if ($PSCmdlet.ShouldProcess($archive, "Create portable checkpoint archive")) {
} }
$addonFiles = Get-ChildItem -LiteralPath $addonSource -Recurse -File | $addonFiles = Get-ChildItem -LiteralPath $addonSource -Recurse -File |
Where-Object {
$_.Extension -ne ".pyc" -and
$_.FullName -notmatch '[\\/]__pycache__[\\/]'
} |
Sort-Object FullName | Sort-Object FullName |
ForEach-Object { ForEach-Object {
[ordered]@{ [ordered]@{

View file

@ -0,0 +1,6 @@
"""Keep PyInstaller's isolated analysis from initializing a GTK display."""
import gi
gi.disable_legacy_autoinit()

View file

@ -6,6 +6,9 @@ from pathlib import Path
ROOT = Path(__file__).resolve().parents[1] ROOT = Path(__file__).resolve().parents[1]
ACCEPTANCE = ROOT / "scripts" / "run_m1_no_device_acceptance.py" ACCEPTANCE = ROOT / "scripts" / "run_m1_no_device_acceptance.py"
BUILD = ROOT / "scripts" / "build_rayforge_windows_checkpoint.ps1" BUILD = ROOT / "scripts" / "build_rayforge_windows_checkpoint.ps1"
PYINSTALLER_SITE_CUSTOMIZE = (
ROOT / "scripts" / "pyinstaller-sitecustomize" / "sitecustomize.py"
)
VERIFY = ROOT / "scripts" / "verify_rayforge_windows_checkpoint.py" VERIFY = ROOT / "scripts" / "verify_rayforge_windows_checkpoint.py"
UPSTREAM = ROOT / "upstreams" / "rayforge.json" UPSTREAM = ROOT / "upstreams" / "rayforge.json"
@ -54,6 +57,14 @@ class M1AcceptancePipelineTests(unittest.TestCase):
self.assertIn("-LiteralPath $artifactInstaller", source) self.assertIn("-LiteralPath $artifactInstaller", source)
self.assertIn("checkout must be clean", source) self.assertIn("checkout must be clean", source)
self.assertIn("Artifact root must be absent or empty", source) self.assertIn("Artifact root must be absent or empty", source)
self.assertIn('Name -eq "__pycache__"', source)
self.assertIn('Extension -eq ".pyc"', source)
self.assertIn('Extension -ne ".pyc"', source)
self.assertIn("pyinstaller-sitecustomize", source)
self.assertIn("$env:PYTHONPATH", source)
site_customize = PYINSTALLER_SITE_CUSTOMIZE.read_text(encoding="utf-8")
self.assertIn("gi.disable_legacy_autoinit()", site_customize)
def test_acceptance_has_no_hardware_commands(self): def test_acceptance_has_no_hardware_commands(self):
source = ACCEPTANCE.read_text(encoding="utf-8").lower() source = ACCEPTANCE.read_text(encoding="utf-8").lower()