QRun-IO/ci-policy: ci / fork-guard (push) Skipped
QRun-IO/ci-policy: ci / head-profile (push) Skipped
QRun-IO/ci-policy: ci / application-template-0 (push) Skipped
QRun-IO/ci-policy: ci / gradle-1 (push) Skipped
QRun-IO/ci-policy: ci / java-docker-3 (push) Skipped
QRun-IO/ci-policy: ci / java-docker-4 (push) Skipped
QRun-IO/ci-policy: ci / java-frontend-browser-5 (push) Skipped
QRun-IO/ci-policy: ci / java-maven-6 (push) Skipped
QRun-IO/ci-policy: ci / java-maven-7 (push) Skipped
QRun-IO/ci-policy: ci / node-8 (push) Skipped
QRun-IO/ci-policy: ci / node-9 (push) Skipped
QRun-IO/ci-policy: ci / node-10 (push) Skipped
QRun-IO/ci-policy: ci / node-playwright-11 (push) Skipped
QRun-IO/ci-policy: ci / repository-policy-12 (push) Skipped
QRun-IO/ci-policy: ci / source-config-13 (push) Skipped
QRun-IO/ci-policy: ci / source-config-14 (push) Skipped
QRun-IO/ci-policy: ci / android-0 (push) Skipped
QRun-IO/ci-policy: ci / original-business (push) Skipped
QRun-IO/ci-policy: ci / original-mcp (push) Skipped
QRun-IO/ci-policy: ci / original-voyage (push) Skipped
QRun-IO/ci-policy: ci / original-cli (push) Skipped
QRun-IO/ci-policy: ci / repository-policy (push) Skipped
QRun-IO/ci-policy: ci / java-core-2-head (push) Skipped
QRun-IO/ci-policy: ci / java-docker-3-head (push) Skipped
QRun-IO/ci-policy: ci / java-maven-6-head (push) Skipped
QRun-IO/ci-policy: ci / java-maven-7-head (push) Skipped
QRun-IO/ci-policy: ci / not-enrolled (push) Failing after 7s
QRun-IO/ci-policy: native / fork-deny (push) Skipped
QRun-IO/ci-policy: native / dotnet-0 (push) Skipped
QRun-IO/ci-policy: ci / ci-result (push) Failing after 6s
QRun-IO/ci-policy: native / native-result (push) Successful in 6s
Save the current implementation and README, status, and known-issue documentation at the user-requested stop. No completed release or deployment is claimed. Co-Authored-By: Claude <noreply@anthropic.com> Co-Authored-By: GPT-6 Codex <noreply@openai.com>
87 lines
5.0 KiB
PowerShell
87 lines
5.0 KiB
PowerShell
# Copyright (C) 2026 Kingsrook, LLC.
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
<#
|
|
.SYNOPSIS
|
|
Reproduce the fixed Javy/QuickJS Wasm guest from locked inputs and verify it against PINNED-WASM.json.
|
|
.DESCRIPTION
|
|
Offline only. Never downloads an SDK or crate. Refuses an existing output directory.
|
|
Verifies, before building: Cargo.lock/source-input hashes, the Rust compiler commit, and the
|
|
already-extracted WASI SDK's clang version line plus clang.exe, libclang.dll and wasi libc hashes.
|
|
After building: the artifact must match the pinned sha256 and length, otherwise the script fails.
|
|
Run it twice with different -OutputDir values (and, ideally, from different checkouts) to prove
|
|
reproducibility. Writes provenance.json next to the artifact.
|
|
.EXAMPLE
|
|
pwsh -File Build-Wasm.ps1 -SdkRoot C:/tools/wasi-sdk-33.0-x86_64-windows -OutputDir C:/new/output-1
|
|
#>
|
|
param(
|
|
[Parameter(Mandatory)][string]$SdkRoot,
|
|
[Parameter(Mandatory)][string]$OutputDir
|
|
)
|
|
$ErrorActionPreference = 'Stop'
|
|
$root = $PSScriptRoot
|
|
$pin = Get-Content -Raw (Join-Path $root 'PINNED-WASM.json') | ConvertFrom-Json
|
|
|
|
function Sha256Of([string]$path) { (Get-FileHash -Algorithm SHA256 -LiteralPath $path).Hash.ToLowerInvariant() }
|
|
function Require([bool]$condition, [string]$message) { if (-not $condition) { throw "Build-Wasm refused: $message" } }
|
|
|
|
Require ([IO.Path]::IsPathRooted($OutputDir)) 'OutputDir must be absolute'
|
|
Require (-not (Test-Path -LiteralPath $OutputDir)) 'OutputDir must not already exist'
|
|
Require (Test-Path -LiteralPath $SdkRoot) 'SdkRoot not found'
|
|
|
|
# 1. locked source inputs
|
|
$combined = New-Object System.Text.StringBuilder
|
|
foreach ($name in $pin.sourceInputs) {
|
|
[void]$combined.Append($name + "`n" + (Sha256Of (Join-Path $root $name)) + "`n")
|
|
}
|
|
$sha = [Security.Cryptography.SHA256]::Create()
|
|
$inputsHash = ([BitConverter]::ToString($sha.ComputeHash([Text.Encoding]::UTF8.GetBytes($combined.ToString()))) -replace '-', '').ToLowerInvariant()
|
|
Require ($inputsHash -eq $pin.sourceInputsSha256) "source inputs differ from PINNED-WASM.json (have $inputsHash); re-pin only after a reviewed source change"
|
|
Require ((Sha256Of (Join-Path $root 'Cargo.lock')) -eq $pin.cargoLockSha256) 'Cargo.lock differs from the pin'
|
|
|
|
# 2. toolchain
|
|
$rustc = (& rustc "+$($pin.toolchain.rust)" -vV) -join "`n"
|
|
Require ($rustc -match "commit-hash: $($pin.toolchain.rustcCommitHash)") 'rustc commit differs from the pin'
|
|
$sdkInfo = $pin.toolchain.wasiSdk
|
|
$clang = Join-Path $SdkRoot 'bin/clang.exe'
|
|
Require ((Sha256Of $clang) -eq $sdkInfo.clangExeSha256) 'SDK clang.exe differs from the pin'
|
|
Require ((Sha256Of (Join-Path $SdkRoot 'bin/libclang.dll')) -eq $sdkInfo.libclangDllSha256) 'SDK libclang.dll differs from the pin'
|
|
Require ((Sha256Of (Join-Path $SdkRoot 'share/wasi-sysroot/lib/wasm32-wasip1/libc.a')) -eq $sdkInfo.wasiLibcSha256) 'SDK wasi libc differs from the pin'
|
|
Require (((& $clang --version) | Select-Object -First 1) -eq $sdkInfo.clangVersionLine) 'SDK clang version line differs from the pin'
|
|
$clangInclude = Get-ChildItem (Join-Path $SdkRoot 'lib/clang') -Directory | Select-Object -First 1
|
|
Require ($null -ne $clangInclude) 'SDK has no clang resource directory'
|
|
|
|
# 3. build (new output directory; offline; locked)
|
|
New-Item -ItemType Directory -Path $OutputDir | Out-Null
|
|
$saved = @{}
|
|
foreach ($key in 'CARGO_TARGET_DIR', 'WASI_SDK', 'LIBCLANG_PATH', 'BINDGEN_EXTRA_CLANG_ARGS') { $saved[$key] = [Environment]::GetEnvironmentVariable($key) }
|
|
try {
|
|
$env:CARGO_TARGET_DIR = (Join-Path $OutputDir 'cargo-target')
|
|
$env:WASI_SDK = $SdkRoot
|
|
$env:LIBCLANG_PATH = (Join-Path $SdkRoot 'bin')
|
|
# forward slashes: the clang-args parser treats backslashes as escapes
|
|
$env:BINDGEN_EXTRA_CLANG_ARGS = '-isystem ' + ((Join-Path $clangInclude.FullName 'include') -replace '\\', '/')
|
|
Push-Location $root
|
|
try {
|
|
& cargo "+$($pin.toolchain.rust)" build --release --target $pin.toolchain.target --offline --locked
|
|
if ($LASTEXITCODE -ne 0) { throw "cargo build failed ($LASTEXITCODE)" }
|
|
} finally { Pop-Location }
|
|
} finally {
|
|
foreach ($key in $saved.Keys) { [Environment]::SetEnvironmentVariable($key, $saved[$key]) }
|
|
}
|
|
|
|
# 4. verify against the pin and record provenance
|
|
$built = Join-Path $OutputDir "cargo-target/$($pin.toolchain.target)/release/qqq_javy_runtime.wasm"
|
|
$artifact = Join-Path $OutputDir $pin.artifact
|
|
Copy-Item -LiteralPath $built -Destination $artifact
|
|
$actual = Sha256Of $artifact
|
|
$length = (Get-Item -LiteralPath $artifact).Length
|
|
$result = [ordered]@{
|
|
artifact = $pin.artifact; sha256 = $actual; bytes = $length; pinnedSha256 = $pin.sha256; matchesPin = ($actual -eq $pin.sha256 -and $length -eq $pin.bytes)
|
|
sourceInputsSha256 = $inputsHash; cargoLockSha256 = $pin.cargoLockSha256
|
|
rustc = ($rustc -split "`n" | Select-Object -First 1); wasiSdkClang = $sdkInfo.clangVersionLine
|
|
builtAtUtc = [DateTime]::UtcNow.ToString('o')
|
|
}
|
|
($result | ConvertTo-Json) | Set-Content -LiteralPath (Join-Path $OutputDir 'provenance.json') -Encoding utf8
|
|
Require $result.matchesPin "built artifact $actual ($length bytes) does not match the pin $($pin.sha256)"
|
|
Write-Output ($result | ConvertTo-Json -Compress)
|