Cai
2026-09-01 9de34a52319e9c5432dfb3988e79a7d420304405
dev/project-dev/bili_authenticated_extension/build_host.ps1
@@ -52,6 +52,26 @@
    }
}
function Assert-ExactSourceSnapshot([string]$Root, [string]$ManifestPath, [string[]]$ExpectedFiles, [object]$Manifest) {
    Assert-ExactSourceTree $Root $ManifestPath $ExpectedFiles
    foreach ($entry in $Manifest.files) {
        if ($entry.path -notmatch '^[A-Za-z0-9._/-]+$' -or $entry.path.Contains('..') -or
            $entry.sha256 -notmatch '^[A-F0-9]{64}$' -or $entry.bytes -lt 1) {
            throw 'Source artifact manifest contains an invalid entry.'
        }
        $candidate = [System.IO.Path]::GetFullPath((Join-Path $Root $entry.path))
        if (-not $candidate.StartsWith($Root + [System.IO.Path]::DirectorySeparatorChar, [StringComparison]::OrdinalIgnoreCase)) {
            throw 'Source artifact path escaped its root.'
        }
        $item = Get-Item -LiteralPath $candidate
        if (($item.Attributes -band [IO.FileAttributes]::ReparsePoint) -or
            $item.Length -ne $entry.bytes -or
            (Get-FileHash -Algorithm SHA256 -LiteralPath $candidate).Hash -cne $entry.sha256) {
            throw 'Source artifact hash mismatch.'
        }
    }
}
$resolvedOutput = [System.IO.Path]::GetFullPath($OutputRoot)
if (-not [System.IO.Path]::IsPathRooted($resolvedOutput) -or $resolvedOutput.StartsWith('\\')) {
    throw 'OutputRoot must be an absolute local path.'
@@ -83,18 +103,19 @@
    '__init__.py', 'background.js', 'build_host.ps1', 'config.example.json',
    'constants.py', 'dependencies/dependency-artifact-manifest.json',
    'dependencies/yt_dlp-2026.7.4-py3-none-any.whl',
    'install_native_host.ps1', 'job.py', 'manifest.json',
    'formal_legacy_identity_manifest.py', 'install_native_host.ps1', 'job.py', 'manifest.json',
    'native-host-manifest.template.json', 'native_host.py', 'protocol.py',
    'queue-producer.example.json', 'queue_producer.py', 'queue_state.py',
    'sidepanel.css', 'sidepanel.html', 'sidepanel.js', 'worker.py'
)
Assert-ExactSourceTree $sourceRoot $resolvedSourceManifest $expectedSourceFiles
$dependencyManifestPath = Join-Path $sourceRoot 'dependencies/dependency-artifact-manifest.json'
$dependencyManifestItem = Get-Item -LiteralPath $dependencyManifestPath
$sourceManifest = Get-StrictJson $resolvedSourceManifest
if ($sourceManifest.schema -ne 1 -or $sourceManifest.target -cne 'BV1HA3o6oEJJ' -or
if ($sourceManifest.schema -ne 1 -or $sourceManifest.scope -cne 'generic-bilibili-queue' -or
    $sourceManifest.extension_id -cne 'oidmclckpdmpabbfedplkbdplmfcenbb' -or
    $sourceManifest.extension_build -cne 'project-info-bili-auth-ingress/1.0.0+20260805.v002' -or
    $sourceManifest.host_build -cne 'project-info-bili-auth-native-host/1.0.0+20260805.v002' -or
    $sourceManifest.extension_build -cne 'project-info-bili-auth-ingress/1.2.25+20260829.generic.v027' -or
    $sourceManifest.host_build -cne 'project-info-bili-auth-native-host/1.2.25+20260829.generic.v027' -or
    $sourceManifest.dependency_artifact_manifest_bytes -ne $dependencyManifestItem.Length -or
    $sourceManifest.dependency_artifact_manifest_sha256 -cne (Get-FileHash -Algorithm SHA256 -LiteralPath $dependencyManifestPath).Hash) {
    throw 'Source artifact manifest identity mismatch.'
@@ -124,22 +145,7 @@
if (Compare-Object -CaseSensitive ($expectedSourceFiles | Sort-Object) $actualSourceFiles) {
    throw 'Source artifact manifest file set mismatch.'
}
foreach ($entry in $sourceManifest.files) {
    if ($entry.path -notmatch '^[A-Za-z0-9._/-]+$' -or $entry.path.Contains('..') -or
        $entry.sha256 -notmatch '^[A-F0-9]{64}$' -or $entry.bytes -lt 1) {
        throw 'Source artifact manifest contains an invalid entry.'
    }
    $candidate = [System.IO.Path]::GetFullPath((Join-Path $sourceRoot $entry.path))
    if (-not $candidate.StartsWith($sourceRoot + [System.IO.Path]::DirectorySeparatorChar, [StringComparison]::OrdinalIgnoreCase)) {
        throw 'Source artifact path escaped its root.'
    }
    $item = Get-Item -LiteralPath $candidate
    if (($item.Attributes -band [IO.FileAttributes]::ReparsePoint) -or
        $item.Length -ne $entry.bytes -or
        (Get-FileHash -Algorithm SHA256 -LiteralPath $candidate).Hash -cne $entry.sha256) {
        throw 'Source artifact hash mismatch.'
    }
}
Assert-ExactSourceSnapshot $sourceRoot $resolvedSourceManifest $expectedSourceFiles $sourceManifest
$dependencyManifest = Get-StrictJson $dependencyManifestPath
$expectedDependencyKeys = @(
@@ -229,6 +235,7 @@
    foreach ($name in @($pythonEnvironment.Keys)) {
        Remove-Item -LiteralPath "Env:$name" -ErrorAction SilentlyContinue
    }
    $env:PYTHONDONTWRITEBYTECODE = '1'
    $pyInstallerVersion = & $resolvedPython -I -B -c "import importlib.metadata; print(importlib.metadata.version('PyInstaller'))"
    if ($LASTEXITCODE -ne 0 -or $pyInstallerVersion.Trim() -cne '6.15.0') {
        throw 'PyInstaller 6.15.0 is required; no unpinned builder is allowed.'
@@ -673,10 +680,10 @@
    $hostItem = Get-Item -LiteralPath $hostExecutable
    $buildManifest = [ordered]@{
        schema = 2
        target = 'BV1HA3o6oEJJ'
        scope = 'generic-bilibili-queue'
        extension_id = 'oidmclckpdmpabbfedplkbdplmfcenbb'
        extension_build = 'project-info-bili-auth-ingress/1.0.0+20260805.v002'
        host_build = 'project-info-bili-auth-native-host/1.0.0+20260805.v002'
        extension_build = 'project-info-bili-auth-ingress/1.2.25+20260829.generic.v027'
        host_build = 'project-info-bili-auth-native-host/1.2.25+20260829.generic.v027'
        packaging = 'pyinstaller-onefile'
        pyinstaller_version = '6.15.0'
        yt_dlp_version = '2026.7.4'
@@ -712,12 +719,20 @@
        ($buildManifest | ConvertTo-Json -Depth 5),
        $utf8NoBom
    )
    Assert-ExactSourceSnapshot $sourceRoot $resolvedSourceManifest $expectedSourceFiles $sourceManifest
} catch {
    $caught = $_
    if ($outputCreated -and (Test-Path -LiteralPath $resolvedOutput)) {
        Remove-Item -LiteralPath $resolvedOutput -Recurse -Force
    }
    throw
    try {
        Assert-ExactSourceSnapshot $sourceRoot $resolvedSourceManifest $expectedSourceFiles $sourceManifest
    } catch {
        throw "Post-build source snapshot drifted: $($_.Exception.Message)"
    }
    throw $caught
} finally {
    Remove-Item -LiteralPath 'Env:PYTHONDONTWRITEBYTECODE' -ErrorAction SilentlyContinue
    foreach ($name in @($pythonEnvironment.Keys)) {
        Set-Item -LiteralPath "Env:$name" -Value $pythonEnvironment[$name]
    }