Files
Piik/scripts/package-native-sender.ps1
T
AAA a560f54bcc feat(native): add WGC hardware H264 source (#109)
Adds the explicit Windows WGC/D3D11 hardware-only Media Foundation H.264 source, process-tree audio, direct Go/Pion fanout, source-aware UI/gate, and unique evaluation package helper. Browser VP8 remains the default. Local acceptance and bounded real-device evidence are recorded in the PR; GitHub jobs were billing-blocked before executing any step.
2026-08-21 05:37:29 +08:00

125 lines
5.9 KiB
PowerShell

[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$OutputDirectory,
[string]$Revision
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$scriptDirectory = Split-Path -Parent $MyInvocation.MyCommand.Path
$repositoryRoot = [IO.Path]::GetFullPath((Join-Path $scriptDirectory '..'))
$outputRoot = [IO.Path]::GetFullPath($OutputDirectory)
$repositoryPrefix = $repositoryRoot.TrimEnd([IO.Path]::DirectorySeparatorChar) + [IO.Path]::DirectorySeparatorChar
if ($outputRoot.Equals($repositoryRoot, [StringComparison]::OrdinalIgnoreCase) -or
$outputRoot.StartsWith($repositoryPrefix, [StringComparison]::OrdinalIgnoreCase)) {
throw 'OutputDirectory must be outside the repository.'
}
if (Test-Path -LiteralPath $outputRoot) {
throw 'OutputDirectory must not already exist.'
}
$headRevision = (& git -C $repositoryRoot rev-parse HEAD).Trim()
if ($LASTEXITCODE -ne 0) { throw 'Unable to resolve the Git revision.' }
if ([string]::IsNullOrWhiteSpace($Revision)) { $Revision = $headRevision }
$Revision = $Revision.Trim().ToLowerInvariant()
if ($Revision -notmatch '^[0-9a-f]{40}$' -or $Revision -ne $headRevision) {
throw 'Revision must be the full SHA-1 of the checked-out commit.'
}
$dirty = @(git -C $repositoryRoot status --porcelain)
if ($LASTEXITCODE -ne 0 -or $dirty.Count -ne 0) {
throw 'Native packages must be built from a clean Git checkout.'
}
$go = Get-Command go.exe -ErrorAction Stop
$senderDirectory = Join-Path $repositoryRoot 'native\sender'
$packageName = "screener-native-windows-x64-$($Revision.Substring(0, 12))"
$packageDirectory = Join-Path $outputRoot $packageName
$licenseDirectory = Join-Path $packageDirectory 'licenses'
$senderExecutable = Join-Path $packageDirectory 'screener-sender.exe'
$zipPath = Join-Path $outputRoot "$packageName.zip"
New-Item -ItemType Directory -Path $licenseDirectory -Force | Out-Null
$previousGoOS = $env:GOOS
$previousGoArch = $env:GOARCH
$previousCGO = $env:CGO_ENABLED
Push-Location $senderDirectory
try {
$env:GOOS = 'windows'
$env:GOARCH = 'amd64'
$env:CGO_ENABLED = '0'
$linkerFlags = "-X main.buildRevision=$Revision"
& $go.Source build -mod=readonly -trimpath -buildvcs=true -ldflags $linkerFlags -o $senderExecutable ./cmd/screener-sender
if ($LASTEXITCODE -ne 0) { throw 'Native sender build failed.' }
$moduleLines = @(& $go.Source list -deps -f '{{with .Module}}{{if not .Main}}{{.Path}}|{{.Version}}|{{.Dir}}{{end}}{{end}}' ./cmd/screener-sender |
Where-Object { -not [string]::IsNullOrWhiteSpace($_) } | Sort-Object -Unique)
if ($LASTEXITCODE -ne 0 -or $moduleLines.Count -eq 0) {
throw 'Unable to enumerate linked Go modules.'
}
$goVersion = (& $go.Source version).Trim()
$goRoot = (& $go.Source env GOROOT).Trim()
} finally {
Pop-Location
$env:GOOS = $previousGoOS
$env:GOARCH = $previousGoArch
$env:CGO_ENABLED = $previousCGO
}
& (Join-Path $repositoryRoot 'native\window-capture-helper\build.ps1') -OutputDirectory $packageDirectory | Out-Null
@('window-capture.obj', 'process-audio.obj') | ForEach-Object {
$helperObject = Join-Path $packageDirectory $_
if (Test-Path -LiteralPath $helperObject) { Remove-Item -LiteralPath $helperObject -Force }
}
$moduleManifest = @()
foreach ($line in $moduleLines) {
$modulePath, $moduleVersion, $moduleDirectory = $line -split '\|', 3
if ([string]::IsNullOrWhiteSpace($moduleDirectory) -or -not (Test-Path -LiteralPath $moduleDirectory -PathType Container)) {
throw "Linked module source is unavailable: $modulePath@$moduleVersion"
}
$licenseFiles = @(Get-ChildItem -LiteralPath $moduleDirectory -File | Where-Object {
$_.Name -match '^(LICENSE|LICENCE|COPYING|NOTICE)(\.|$)'
})
if ($licenseFiles.Count -eq 0) { throw "Linked module has no recognized license file: $modulePath@$moduleVersion" }
$moduleLicenseDirectory = Join-Path $licenseDirectory (($modulePath + '@' + $moduleVersion) -replace '[^A-Za-z0-9._@+-]', '_')
New-Item -ItemType Directory -Path $moduleLicenseDirectory | Out-Null
$licenseFiles | Copy-Item -Destination $moduleLicenseDirectory
$moduleManifest += "$modulePath $moduleVersion"
}
$goLicense = Join-Path $goRoot 'LICENSE'
if (-not (Test-Path -LiteralPath $goLicense -PathType Leaf)) { throw 'Go toolchain license was not found.' }
$goLicenseDirectory = Join-Path $licenseDirectory 'go-toolchain'
New-Item -ItemType Directory -Path $goLicenseDirectory | Out-Null
Copy-Item -LiteralPath $goLicense -Destination (Join-Path $goLicenseDirectory 'LICENSE')
$moduleManifest | Set-Content -LiteralPath (Join-Path $licenseDirectory 'MODULES.txt') -Encoding ascii
Copy-Item -LiteralPath (Join-Path $senderDirectory 'README.md') -Destination (Join-Path $packageDirectory 'README.md')
@(
"revision=$Revision"
'platform=windows/amd64'
"toolchain=$goVersion"
) | Set-Content -LiteralPath (Join-Path $packageDirectory 'REVISION.txt') -Encoding ascii
$versionOutput = (& $senderExecutable --version).Trim()
if ($LASTEXITCODE -ne 0 -or $versionOutput -ne "Screener sender $Revision") {
throw 'Packaged sender revision smoke failed.'
}
$packagePrefix = $packageDirectory.TrimEnd([IO.Path]::DirectorySeparatorChar) + [IO.Path]::DirectorySeparatorChar
$checksums = Get-ChildItem -LiteralPath $packageDirectory -File -Recurse | Sort-Object FullName | ForEach-Object {
$relativePath = $_.FullName.Substring($packagePrefix.Length).Replace('\', '/')
"$((Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash.ToLowerInvariant()) $relativePath"
}
$checksums | Set-Content -LiteralPath (Join-Path $packageDirectory 'SHA256SUMS.txt') -Encoding ascii
Compress-Archive -LiteralPath $packageDirectory -DestinationPath $zipPath -CompressionLevel Optimal
$zipHash = (Get-FileHash -LiteralPath $zipPath -Algorithm SHA256).Hash.ToLowerInvariant()
"$zipHash $([IO.Path]::GetFileName($zipPath))" |
Set-Content -LiteralPath "$zipPath.sha256" -Encoding ascii
Write-Output $zipPath
Write-Output "$zipPath.sha256"