mirror of
https://github.com/openai/codex.git
synced 2026-09-14 11:57:03 +00:00
Bundle native voice runtimes in Windows releases (#44922)
## Why Windows release packages need the voice helper and native audio libraries. Realtime TLS connections on fresh Windows installations also need platform certificate validation so Windows can retrieve missing trusted roots on demand. ## What changed - Build and sign the voice helper and audio DLLs for Windows x64 and ARM64, bundle a pinned Microsoft CRT DLL, and verify signatures and runtime receipts before packaging. - Add verified, pinned Cygwin and native build tools plus MSVC linker, compiler, and path handling fixes for the Windows Bazel builds. - Include voice resources in primary release archives and WinGet packages. Preserve WinGet executable names, update manifest hashes, and recognize the package root through matching entrypoint metadata. Keep Python runtime wheels voice-free to preserve their existing Windows support floor. - Use Windows platform TLS validation for realtime WebSockets when no custom CA bundle is configured, preserving custom CA behavior. ## Testing Add coverage for build-input integrity and unsafe paths, signed Windows runtime assembly, WinGet file and hash preservation, package discovery, and TLS trust selection, untrusted certificate rejection, and hostname validation. GitOrigin-RevId: 423da35872fa5549d69fd4ca97d922bb49599386
This commit is contained in:
committed by
copyberry
parent
3f59eb965a
commit
ce7fbb373b
@@ -117,8 +117,8 @@ if [[ -z "$target" || -z "$bundle" || -z "$entrypoint_dir" || -z "$archive_dir"
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ ( -n "$voice_release_dir" || -n "$release_version" ) && ( -z "$voice_release_dir" || -z "$release_version" || "$bundle" != "primary" || ( "$target" != *-apple-darwin && "$target" != *-unknown-linux-musl ) ) ]]; then
|
||||
echo "Voice resources require a primary macOS or Linux release package version" >&2
|
||||
if [[ ( -n "$voice_release_dir" || -n "$release_version" ) && ( -z "$voice_release_dir" || -z "$release_version" || "$bundle" != "primary" || ( "$target" != *-apple-darwin && "$target" != *-unknown-linux-musl && "$target" != *-pc-windows-msvc ) ) ]]; then
|
||||
echo "Voice resources require a primary supported release package version" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -221,9 +221,10 @@ if [[ -n "$voice_release_dir" ]]; then
|
||||
fi
|
||||
voice_package="${RUNNER_TEMP:-/tmp}/${archive_stem}-voice-${target}"
|
||||
rm -rf "$voice_package"
|
||||
voice_helper="${voice_release_dir%/}/codex-voice-host${exe_suffix}"
|
||||
"$python_bin" "${repo_root}/third_party/voice/assemble_package.py" \
|
||||
--package "$package_dir" \
|
||||
--helper "${voice_release_dir%/}/codex-voice-host" \
|
||||
--helper "$voice_helper" \
|
||||
--runtime "${voice_release_dir%/}/runtime" \
|
||||
--voice-target "$voice_target" \
|
||||
--build-commit "$(git -C "$repo_root" rev-parse HEAD)" \
|
||||
|
||||
3
.github/scripts/run-bazel-ci.sh
vendored
3
.github/scripts/run-bazel-ci.sh
vendored
@@ -47,6 +47,9 @@ if [[ $# -eq 0 ]]; then
|
||||
fi
|
||||
|
||||
bazel_startup_args=()
|
||||
if [[ -n "${BAZEL_HOST_JVM_ARG:-}" ]]; then
|
||||
bazel_startup_args+=("--host_jvm_args=${BAZEL_HOST_JVM_ARG}")
|
||||
fi
|
||||
if [[ -n "${BAZEL_OUTPUT_USER_ROOT:-}" ]]; then
|
||||
bazel_startup_args+=("--output_user_root=${BAZEL_OUTPUT_USER_ROOT}")
|
||||
fi
|
||||
|
||||
96
.github/scripts/setup-voice-windows.ps1
vendored
Normal file
96
.github/scripts/setup-voice-windows.ps1
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
# CI-only prerequisites. Never install these tools into a Codex package.
|
||||
param(
|
||||
[Parameter(Mandatory = $true)][string]$Target,
|
||||
[Parameter(Mandatory = $true)][string]$SnapshotArchive
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$PkgHashes = @{
|
||||
"x86_64-pc-windows-msvc" = @("x64", "5604cf25ef38bb6a09520cff25ae9f0ecd8c2443053b15e40df4ad1eae0e4405")
|
||||
"aarch64-pc-windows-msvc" = @("arm64", "d5752ce2ac2296c8abb91fb12c12e75ee99ba8a18b52ce5febf325847b6f062b")
|
||||
}
|
||||
if (-not $PkgHashes.ContainsKey($Target)) { throw "Unsupported target: $Target" }
|
||||
$Root = Join-Path $env:RUNNER_TEMP "voice-windows-build-tools"
|
||||
$Evidence = Join-Path $Root "evidence"
|
||||
$Cygwin = Join-Path $Root "cygwin"
|
||||
$Cache = Join-Path $Root "cache"
|
||||
New-Item -ItemType Directory -Path $Root, $Evidence | Out-Null
|
||||
$ManifestPath = Join-Path $PSScriptRoot "voice-cygwin-snapshot.json"
|
||||
$Manifest = Get-Content -Raw $ManifestPath | ConvertFrom-Json
|
||||
$SnapshotTool = Join-Path $PSScriptRoot "voice-cygwin-inputs.py"
|
||||
& python $SnapshotTool extract --archive $SnapshotArchive --directory (Join-Path $Cache $Manifest.cacheDirectory)
|
||||
if ($LASTEXITCODE -ne 0) { throw "Cygwin snapshot could not be verified and extracted" }
|
||||
Copy-Item $ManifestPath (Join-Path $Evidence "cygwin-snapshot.json")
|
||||
|
||||
# Official https://cygwin.com/setup/sha512.sum and pkgconf release asset digests.
|
||||
# The complete package closure is pinned separately in cygwin-snapshot.json.
|
||||
$Inputs = @(
|
||||
@{
|
||||
url = "https://cygwin.com/setup/setup-2.937.x86_64.exe"
|
||||
file = "setup.exe"
|
||||
algorithm = "SHA512"
|
||||
digest = "6acea47c59781c9e7f544a18d53935d59df6e44d5d52ac95ee165671b8e388820455eebf30ccc7d254b00c3d0eb694269a0f8dc84b17944c1f355dac9c5aafcc"
|
||||
},
|
||||
@{
|
||||
url = "https://github.com/pkgconf/pkgconf/releases/download/pkgconf-3.0.6/pkgconf-$($PkgHashes[$Target][0])-3.0.6.msi"
|
||||
file = "pkgconf.msi"
|
||||
algorithm = "SHA256"
|
||||
digest = $PkgHashes[$Target][1]
|
||||
}
|
||||
)
|
||||
foreach ($InputFile in $Inputs) {
|
||||
$Destination = Join-Path $Root $InputFile.file
|
||||
Invoke-WebRequest -Uri $InputFile.url -OutFile $Destination
|
||||
$Actual = (Get-FileHash -Path $Destination -Algorithm $InputFile.algorithm).Hash.ToLowerInvariant()
|
||||
if ($Actual -ne $InputFile.digest) { throw "Build input digest mismatch: $($InputFile.file)" }
|
||||
}
|
||||
$Inputs | ConvertTo-Json | Set-Content (Join-Path $Evidence "bootstrap-inputs.json")
|
||||
$Packages = $Manifest.requestedPackages -join ","
|
||||
# Only setup.xz + setup.xz.sig are present: local mode still verifies that
|
||||
# signature. Never substitute an unsigned setup.ini or enable a network fallback.
|
||||
$Setup = Start-Process -FilePath (Join-Path $Root "setup.exe") -Wait -PassThru -ArgumentList @(
|
||||
"--quiet-mode", "--no-admin", "--no-shortcuts", "--only-site",
|
||||
"--local-install", "--no-version-check",
|
||||
"--root", "`"$Cygwin`"", "--local-package-dir", "`"$Cache`"",
|
||||
"--packages", $Packages
|
||||
)
|
||||
if ($Setup.ExitCode -ne 0) { throw "Cygwin setup failed: $($Setup.ExitCode)" }
|
||||
Copy-Item (Join-Path $Cygwin "var/log/setup.log*") $Evidence
|
||||
Copy-Item (Join-Path $Cygwin "etc/setup/installed.db") $Evidence
|
||||
& (Join-Path $Cygwin "bin/cygcheck.exe") -cd | Set-Content (Join-Path $Evidence "packages.txt")
|
||||
if ($LASTEXITCODE -ne 0) { throw "Cannot inventory Cygwin packages" }
|
||||
& python $SnapshotTool check-installed --inventory (Join-Path $Evidence "packages.txt")
|
||||
if ($LASTEXITCODE -ne 0) { throw "Installed Cygwin package set differs from the snapshot" }
|
||||
Get-ChildItem $Cache -File -Recurse | ForEach-Object {
|
||||
@{ file = [IO.Path]::GetRelativePath($Cache, $_.FullName); bytes = $_.Length;
|
||||
sha512 = (Get-FileHash $_.FullName -Algorithm SHA512).Hash.ToLowerInvariant() }
|
||||
} | ConvertTo-Json | Set-Content (Join-Path $Evidence "package-cache.json")
|
||||
|
||||
# Administrative extraction uses TARGETDIR, not a normal MSI installation:
|
||||
# no product registration or system PATH modification. Fail rather than fall
|
||||
# back to an ambient executable or ordinary installer if the payload is absent.
|
||||
$Image = Join-Path $Root "pkgconf-image"
|
||||
$Extract = Start-Process msiexec.exe -Wait -PassThru -ArgumentList @(
|
||||
"/a", "`"$(Join-Path $Root 'pkgconf.msi')`"", "/qn", "/norestart",
|
||||
"TARGETDIR=`"$Image`"", "/L*v", "`"$(Join-Path $Evidence 'pkgconf-extract.log')`""
|
||||
)
|
||||
if ($Extract.ExitCode -ne 0) { throw "pkgconf extraction failed: $($Extract.ExitCode)" }
|
||||
$Candidates = @(Get-ChildItem $Image -Filter pkgconf.exe -File -Recurse)
|
||||
if ($Candidates.Count -ne 1) { throw "Expected exactly one native pkgconf executable" }
|
||||
# Bazel shell-quotes execpaths containing spaces; Cargo executes PKG_CONFIG
|
||||
# directly. Keep the executable and its support files at a space-free execpath.
|
||||
$Native = Join-Path $Image "native"
|
||||
if (Test-Path $Native) { throw "Native pkgconf destination must be fresh" }
|
||||
Move-Item -LiteralPath $Candidates[0].Directory.FullName -Destination $Native
|
||||
$PkgConfig = Join-Path $Native "pkgconf.exe"
|
||||
$Version = & $PkgConfig --version
|
||||
if ($LASTEXITCODE -ne 0 -or $Version -ne "3.0.6") { throw "Unexpected native pkgconf version" }
|
||||
@{ target = $Target; cygwin_root = $Cygwin; pkg_config = $PkgConfig;
|
||||
pkgconf_version = $Version; requested_packages = $Packages } |
|
||||
ConvertTo-Json | Set-Content (Join-Path $Evidence "tools.json")
|
||||
# Declare complete installed support trees only after snapshot and tool checks.
|
||||
& python (Join-Path $PSScriptRoot "voice_windows_tools.py") --root $Root --target $Target --pkg-config $PkgConfig
|
||||
if ($LASTEXITCODE -ne 0) { throw "Cannot declare Windows Bazel tool inputs" }
|
||||
"VOICE_WINDOWS_BAZEL_REPOSITORY=$Root" | Out-File $env:GITHUB_ENV -Encoding utf8 -Append
|
||||
"VOICE_CYGWIN_ROOT=$Cygwin" | Out-File $env:GITHUB_ENV -Encoding utf8 -Append
|
||||
"VOICE_PKG_CONFIG=$PkgConfig" | Out-File $env:GITHUB_ENV -Encoding utf8 -Append
|
||||
83
.github/scripts/test_voice_cygwin_inputs.py
vendored
Normal file
83
.github/scripts/test_voice_cygwin_inputs.py
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
"""Offline checks for the public Windows build-input bootstrap."""
|
||||
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import io
|
||||
from pathlib import Path
|
||||
import tarfile
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
|
||||
SCRIPT = Path(__file__).with_name("voice-cygwin-inputs.py")
|
||||
SPEC = importlib.util.spec_from_file_location("voice_cygwin_inputs", SCRIPT)
|
||||
inputs = importlib.util.module_from_spec(SPEC)
|
||||
SPEC.loader.exec_module(inputs)
|
||||
|
||||
|
||||
class VoiceCygwinInputsTests(unittest.TestCase):
|
||||
def test_input_paths_cannot_escape_the_local_cache(self):
|
||||
manifest = {
|
||||
"metadata": [
|
||||
{"file": "x86_64/setup.xz"},
|
||||
{"file": "x86_64/setup.xz.sig"},
|
||||
],
|
||||
"packages": [{"file": "../outside.tar.xz"}],
|
||||
}
|
||||
with self.assertRaisesRegex(ValueError, "unsafe Cygwin input"):
|
||||
inputs.records(manifest)
|
||||
|
||||
def test_extract_verifies_archive_and_every_input_before_offline_installation(self):
|
||||
with tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory)
|
||||
payloads = {
|
||||
"x86_64/setup.xz": b"metadata",
|
||||
"x86_64/setup.xz.sig": b"signature",
|
||||
"x86_64/release/bash/bash.tar.xz": b"package",
|
||||
}
|
||||
records = [
|
||||
{
|
||||
"file": name,
|
||||
"bytes": len(data),
|
||||
"sha512": hashlib.sha512(data).hexdigest(),
|
||||
}
|
||||
for name, data in payloads.items()
|
||||
]
|
||||
archive = root / "inputs.tar.gz"
|
||||
|
||||
def write_archive(contents):
|
||||
with tarfile.open(archive, "w:gz") as bundle:
|
||||
for name, data in contents.items():
|
||||
info = tarfile.TarInfo(name)
|
||||
info.size = len(data)
|
||||
bundle.addfile(info, io.BytesIO(data))
|
||||
return {
|
||||
"bytes": archive.stat().st_size,
|
||||
"sha256": hashlib.sha256(archive.read_bytes()).hexdigest(),
|
||||
}
|
||||
|
||||
manifest = {
|
||||
"metadata": records[:2],
|
||||
"packages": records[2:],
|
||||
"archive": write_archive(payloads),
|
||||
}
|
||||
destination = root / "cache"
|
||||
inputs.extract(manifest, archive, destination)
|
||||
self.assertEqual(
|
||||
{
|
||||
record["file"]: (destination / record["file"]).read_bytes()
|
||||
for record in records
|
||||
},
|
||||
payloads,
|
||||
)
|
||||
|
||||
(destination / records[2]["file"]).unlink()
|
||||
payloads[records[2]["file"]] = b"wrong"
|
||||
manifest["archive"] = write_archive(payloads)
|
||||
with self.assertRaisesRegex(ValueError, "Cygwin input mismatch"):
|
||||
inputs.extract(manifest, archive, root / "rejected")
|
||||
self.assertFalse((root / "rejected").exists())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
98
.github/scripts/voice-cygwin-inputs.py
vendored
Normal file
98
.github/scripts/voice-cygwin-inputs.py
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
"""Verify the pinned Cygwin build-input archive before offline installation."""
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path, PurePosixPath
|
||||
import shutil
|
||||
import tarfile
|
||||
|
||||
|
||||
def records(manifest):
|
||||
metadata = manifest["metadata"]
|
||||
if {item["file"] for item in metadata} != {
|
||||
"x86_64/setup.xz",
|
||||
"x86_64/setup.xz.sig",
|
||||
}:
|
||||
raise ValueError("signed setup metadata is required")
|
||||
entries = metadata + manifest["packages"]
|
||||
expected = {entry["file"]: entry for entry in entries}
|
||||
if len(expected) != len(entries):
|
||||
raise ValueError("duplicate Cygwin input")
|
||||
for name in expected:
|
||||
path = PurePosixPath(name)
|
||||
if (
|
||||
not path.parts
|
||||
or path.is_absolute()
|
||||
or ".." in path.parts
|
||||
or path.as_posix() != name
|
||||
or "\\" in name
|
||||
or ":" in name
|
||||
):
|
||||
raise ValueError(f"unsafe Cygwin input: {name}")
|
||||
return expected
|
||||
|
||||
|
||||
def extract(manifest, archive, destination):
|
||||
expected = records(manifest)
|
||||
pin = manifest["archive"]
|
||||
with archive.open("rb") as stream:
|
||||
if (
|
||||
archive.stat().st_size != pin["bytes"]
|
||||
or hashlib.file_digest(stream, "sha256").hexdigest() != pin["sha256"]
|
||||
):
|
||||
raise ValueError("Cygwin archive digest or size mismatch")
|
||||
stream.seek(0)
|
||||
with tarfile.open(fileobj=stream, mode="r:gz") as bundle:
|
||||
members = bundle.getmembers()
|
||||
if len(members) != len(expected) or {m.name for m in members} != set(
|
||||
expected
|
||||
):
|
||||
raise ValueError("missing, extra, or duplicate Cygwin inputs")
|
||||
for member in members:
|
||||
if not member.isfile() or member.issparse():
|
||||
raise ValueError(f"non-regular Cygwin input: {member.name}")
|
||||
with bundle.extractfile(member) as source:
|
||||
if (
|
||||
member.size != expected[member.name]["bytes"]
|
||||
or hashlib.file_digest(source, "sha512").hexdigest()
|
||||
!= expected[member.name]["sha512"]
|
||||
):
|
||||
raise ValueError(f"Cygwin input mismatch: {member.name}")
|
||||
destination.mkdir(parents=True)
|
||||
try:
|
||||
bundle.extractall(destination, members=members, filter="data")
|
||||
except BaseException:
|
||||
shutil.rmtree(destination)
|
||||
raise
|
||||
|
||||
|
||||
def check_installed(manifest, inventory):
|
||||
installed = sorted(
|
||||
tuple(line.split())
|
||||
for line in inventory.read_text().splitlines()
|
||||
if len(line.split()) == 2 and not line.startswith("Package ")
|
||||
)
|
||||
expected = sorted((item["name"], item["version"]) for item in manifest["packages"])
|
||||
if installed != expected:
|
||||
raise ValueError("installed Cygwin packages differ from reviewed inputs")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("command", choices=("extract", "check-installed"))
|
||||
parser.add_argument("--archive", type=Path)
|
||||
parser.add_argument("--directory", type=Path)
|
||||
parser.add_argument("--inventory", type=Path)
|
||||
args = parser.parse_args()
|
||||
pinned = json.loads(
|
||||
Path(__file__).with_name("voice-cygwin-snapshot.json").read_text()
|
||||
)
|
||||
if args.command == "extract":
|
||||
if args.archive is None or args.directory is None:
|
||||
parser.error("extract requires --archive and --directory")
|
||||
extract(pinned, args.archive, args.directory)
|
||||
else:
|
||||
if args.inventory is None:
|
||||
parser.error("check-installed requires --inventory")
|
||||
check_installed(pinned, args.inventory)
|
||||
145
.github/scripts/voice-cygwin-snapshot.json
vendored
Normal file
145
.github/scripts/voice-cygwin-snapshot.json
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"sourceMirror": "https://mirrors.kernel.org/sourceware/cygwin/",
|
||||
"cacheDirectory": "https%3a%2f%2fmirrors.kernel.org%2fsourceware%2fcygwin%2f",
|
||||
"requestedPackages": [
|
||||
"bash",
|
||||
"make",
|
||||
"automake1.18",
|
||||
"coreutils",
|
||||
"diffutils",
|
||||
"findutils",
|
||||
"grep",
|
||||
"sed",
|
||||
"gawk"
|
||||
],
|
||||
"signingFingerprint": "56405CF6FCC81574682A5D561A698DE9E2E56300",
|
||||
"archive": {
|
||||
"tag": "voice-cygwin-108b38cf67cbb731",
|
||||
"name": "cygwin-build-inputs.tar.gz",
|
||||
"bytes": 62276721,
|
||||
"sha256": "108b38cf67cbb731801e5ca8d8412b8f349961e4e71d8e3d5a1768f1a8d15c50"
|
||||
},
|
||||
"metadata": [
|
||||
{
|
||||
"file": "x86_64/setup.xz",
|
||||
"bytes": 3598392,
|
||||
"sha512": "306bffefa1e86178d9c6ff78a8add2e1af3c96f7cd698d62b58d0237a568e1a9f1b30016ed5891f9fe1d1c8a1e58089c3d9cb8989eb7bed758a928f212078e25"
|
||||
},
|
||||
{
|
||||
"file": "x86_64/setup.xz.sig",
|
||||
"bytes": 566,
|
||||
"sha512": "7c466da6446bbef67762ff4038dd4986018ed09432bd6ee6ca9e33150874dbb9d61c7e4b06bd925f932a55fda345401224689bbaddc135d7300651f67ec8160b"
|
||||
}
|
||||
],
|
||||
"sourceArchive": {
|
||||
"name": "cygwin-build-sources.tar",
|
||||
"bytes": 368824320,
|
||||
"sha256": "13a42ea4e6465f77c32f91e4162f41bcfeab7c0eca47701bb6a8b9aca1eb99f4"
|
||||
},
|
||||
"packages": [
|
||||
{"name": "_autorebase", "version": "001091-1", "file": "noarch/release/_autorebase/_autorebase-001091-1.tar.zst", "bytes": 4696, "sha512": "a9416ce992ca57f3a6208f46517520d21dfac61988ac84cbb5b17b76e053a0845c15368ccb8ca9c483d8935f9e3db81568433c0d08d0265ec5e6916ea30f2831"},
|
||||
{"name": "alternatives", "version": "1.31-1", "file": "x86_64/release/alternatives/alternatives-1.31-1.tar.xz", "bytes": 123748, "sha512": "94adf3376e7fcaf937594be718f54a99f2a2b66367eb2bb294b6fd4a933a9515954a9e9f309ed74cc62fbb353adb053d8500bbaf42994e4355f7180664afa62c"},
|
||||
{"name": "autoconf", "version": "15-3", "file": "noarch/release/autoconf/autoconf-15-3-noarch.tar.zst", "bytes": 2396, "sha512": "edaa6c97c5b50e138acef4b80406bfdd0988da3360cc622be2541593f6e926a4fbe1088ff608ddadfacf275b3924605d54f59e140cc7c79b31f4885e5878ad6f"},
|
||||
{"name": "autoconf2.1", "version": "2.13-12", "file": "noarch/release/autoconf2.1/autoconf2.1-2.13-12.tar.bz2", "bytes": 204911, "sha512": "96f8f592fff4665512c0023d6a7844fdc281ba99dc98dee9e55c37523b3a1279ae8fd31559fa6426edb1da7559a483b3eae99ae7911d50646ec60338ef209c18"},
|
||||
{"name": "autoconf2.5", "version": "2.69-5", "file": "noarch/release/autoconf2.5/autoconf2.5-2.69-5.tar.zst", "bytes": 341597, "sha512": "3739719f29ad3ab1c1045b72ccbfe6c58e3f7696ac063c2ff4e09e11e1a9015f289fa8fc267a62b43cb2f6b682b83d3b4b6450040e733f9f41d086dc4a2f36b9"},
|
||||
{"name": "autoconf2.7", "version": "2.73-1", "file": "noarch/release/autoconf2.7/autoconf2.7-2.73-1-noarch.tar.zst", "bytes": 906344, "sha512": "0493d68a7ea9cd61e403b6b7086b5302bad5bc1cc35715349f59605a795ac7a9f901c444cb387e5f44d1860de3e5d0fcfceee4ee2726d68904cfc5e2db6e90e9"},
|
||||
{"name": "automake1.18", "version": "1.18.1-1", "file": "noarch/release/automake1.18/automake1.18-1.18.1-1-noarch.tar.zst", "bytes": 921189, "sha512": "416ef8041505ecddc23e9e72394ef3a81311c6c378b8b6d348e989584c77924d40aa427b47ab4d3a9a2b83438d13995bb7c6302afb73af3d3af7f2e9061579c0"},
|
||||
{"name": "base-cygwin", "version": "3.8-2", "file": "noarch/release/base-cygwin/base-cygwin-3.8-2.tar.xz", "bytes": 1260, "sha512": "e03949b4ae6b692858e1d29fb764afbda990c07a6b70b0eb7219fc12f28dfba3cf7e757a7570c31e315be79f091b012d6a6ddafdb4b0b8961afe9af9f4977fab"},
|
||||
{"name": "base-files", "version": "4.3-3", "file": "noarch/release/base-files/base-files-4.3-3.tar.zst", "bytes": 46481, "sha512": "dfafbe28fbe89d9b72a2eeb10901712e04de71d9089a85cfd2b8d45ffd739bdd49dadb7b57d098f01b8902456f5b839e9d4a10dbd6a8001573e035fde6797b63"},
|
||||
{"name": "bash", "version": "5.2.21-1", "file": "x86_64/release/bash/bash-5.2.21-1.tar.xz", "bytes": 1650932, "sha512": "c3a5594f1c248dd27a3b5aa10c31fb1651072eae878479d3d8cab09c28354ce4509a2fe230f176ad200a6484a561bc10c2dc9c74c4e9f03164190dac2e683d65"},
|
||||
{"name": "bzip2", "version": "1.0.8-2", "file": "x86_64/release/bzip2/bzip2-1.0.8-2-x86_64.tar.xz", "bytes": 36396, "sha512": "86e4b0b21b64d17b9fb60260a787626125102b0cb786de67893cb1d39a109457637bdb93956c992429f1135f64b07def64dd0116682a6190b635ba12f81395d7"},
|
||||
{"name": "ca-certificates", "version": "2025.2.80_v9.0.304-1", "file": "noarch/release/ca-certificates/ca-certificates-2025.2.80_v9.0.304-1-noarch.tar.zst", "bytes": 902180, "sha512": "49d08f490db12855f8794cd5cfc721940504d36deffdd3b9aea0fc75909e27471f795d48c739630498fd4baeecb76ee0adb5e5c4cecab4db2ea39b03391a02d0"},
|
||||
{"name": "coreutils", "version": "9.0-1", "file": "x86_64/release/coreutils/coreutils-9.0-1.tar.xz", "bytes": 2767296, "sha512": "530f47640d878f5953580f3556c492a93786191abe573322026b70206a46c7f17d05927784db3e7f2c044d1555f35941880316f7288b887eaec770a9eda4c687"},
|
||||
{"name": "crypto-policies", "version": "20190218-1", "file": "noarch/release/crypto-policies/crypto-policies-20190218-1.tar.xz", "bytes": 14032, "sha512": "44d50ff08528df786eeb26ec1d312445ec92d77ecc9f448a3b741f7647e187f11eabdc0b38f8ab8de803e21d2e610f67eb44de7554f3fa83f6e8172e609b0054"},
|
||||
{"name": "cygutils", "version": "1.4.17-4", "file": "x86_64/release/cygutils/cygutils-1.4.17-4-x86_64.tar.xz", "bytes": 90580, "sha512": "a9c63f8ac86e529fa8809c9637bb80651721003160726e2058c361687e5df6377c4cdbea2d023677b23e1d166bbce37d5a412f7d1135baf075ae2631fdeb77b2"},
|
||||
{"name": "cygwin", "version": "3.6.10-1", "file": "x86_64/release/cygwin/cygwin-3.6.10-1-x86_64.tar.xz", "bytes": 1626060, "sha512": "50e5a100f5229eecba279799363a30d599f8c6ad06967eabc4fc8ed9105736576a522539abc250110282cf18da8536d4e408823cc6c0d2abd8692a91d9fd3341"},
|
||||
{"name": "dash", "version": "0.5.12-5", "file": "x86_64/release/dash/dash-0.5.12-5.tar.xz", "bytes": 79612, "sha512": "8891165224ca8531ad7b601309bc1a74f8b68dad24721060fd3db5d12ae504e3c96bbd0217006bbcbe0650d13283f04c1f58412bde54c40f19acb5291dfaced9"},
|
||||
{"name": "diffutils", "version": "3.12-1", "file": "x86_64/release/diffutils/diffutils-3.12-1-x86_64.tar.xz", "bytes": 431400, "sha512": "2a9d8fa0acd5a6108f74afe515f55a2a7cade6fa7f96368e46a6f33cf3b49d270b50dc3cee0320740c8f1729edcbf8dd3824f4b268261fba7aeed0d75a4e943c"},
|
||||
{"name": "editrights", "version": "1.04-1", "file": "x86_64/release/editrights/editrights-1.04-1.tar.xz", "bytes": 7112, "sha512": "aadc188201441ee1ff5710df0e5550c8ca5cb65421d025c5845921510560a2875c317d1f35b6ea8abbb5077172c0de7fc8f2f55ae95dc8d1e59d26c963c93aa7"},
|
||||
{"name": "file", "version": "5.46-1", "file": "x86_64/release/file/file-5.46-1-x86_64.tar.xz", "bytes": 840940, "sha512": "e4b52477d353557d36af625a6a55c97a11ae41053ce17602624210df2a6d2683f46250c2b9f6db5a9f9e5fcccb7b0be4b24705a36d196cee677bf47d90dfee99"},
|
||||
{"name": "findutils", "version": "4.11.0-1", "file": "x86_64/release/findutils/findutils-4.11.0-1-x86_64.tar.xz", "bytes": 768172, "sha512": "cbb1359fd81c55f98da1485f84f11f905a7a3fe9ce1676424e86da4d7f0effa5fc298546bd5c62c9707e8ddf93c31597d6da01e60be0610c50b9b22ef9475814"},
|
||||
{"name": "gawk", "version": "5.4.0-1", "file": "x86_64/release/gawk/gawk-5.4.0-1-x86_64.tar.xz", "bytes": 1496256, "sha512": "3604c99921d0cff387279aec1d3b332e8afcd2746b052304c0511221efdb6ae6d4a3117b36593e44adc43c67b6f6c4c48bccf6b686e2e1a5cac644c89613d829"},
|
||||
{"name": "getent", "version": "2.18.90-5", "file": "x86_64/release/getent/getent-2.18.90-5.tar.xz", "bytes": 17864, "sha512": "b860f3d01f32da7312a0ce118bdaa53e2418c53f0ac5cfd52b3e4267f353fa21ae27fd2649eb9c6bff48b3d10a0a9f7bcaa2d644f770f0f3916f5d969beedd65"},
|
||||
{"name": "gettext-locale-alias", "version": "0.26-1", "file": "x86_64/release/gettext/gettext-locale-alias/gettext-locale-alias-0.26-1-x86_64.tar.xz", "bytes": 1596, "sha512": "289feafbe00598a2451527b64b0187ab62115577ceaa960774b020270e5a8c5bff4038f389a44c7d9eb870f7e2741c7bb2b27be507843cc8c4ae5c33bc74c8f3"},
|
||||
{"name": "grep", "version": "3.12-1", "file": "x86_64/release/grep/grep-3.12-1-x86_64.tar.xz", "bytes": 418788, "sha512": "2ba28b5d93c352bc3f3f0f232e2052e6651b71cc535841f4ff8cedb23e61e9e4c030d7d5516ed9c797074e1a59cbf3a56732ca678cb0e986e86dcbbf25955976"},
|
||||
{"name": "groff", "version": "1.24.1-1", "file": "x86_64/release/groff/groff-1.24.1-1-x86_64.tar.zst", "bytes": 5878965, "sha512": "9e8aaab0e6f464df3fec6b96fed6679673091aaeafaa463ed518081cb156ef7441fb5f9341a251f602334862640ea0b0fc1b158746c08a1e2529cceeb37e9802"},
|
||||
{"name": "gzip", "version": "1.14-1", "file": "x86_64/release/gzip/gzip-1.14-1-x86_64.tar.xz", "bytes": 164124, "sha512": "57995d2e90bf435ffff8f61cd79c4970ad7260e0c407ab52d4dbacb0540a74c7f8fd0d8bd905316eff31525d9b0367284f9f250950f78f179e5260ce59be3a98"},
|
||||
{"name": "hostname", "version": "3.13-1", "file": "x86_64/release/hostname/hostname-3.13-1.tar.bz2", "bytes": 14024, "sha512": "75114326fa4575b8341434658a881feb81a6565e7e0adf8fd100dde87022d3818b5fc3df430bd9b3298d818a1d23f6b6c4bc7ff33efb3ded5f0ea0bf118c1aae"},
|
||||
{"name": "info", "version": "7.3-1", "file": "x86_64/release/texinfo/info/info-7.3-1-x86_64.tar.zst", "bytes": 607040, "sha512": "3af0e7c2edc34a068d88974c6c1b0f529663f4bbce145b5a33f3b7e90671fd908fb4a544e033b98a6906d3244c64a18732104c5f1d323c0ccac8a5134e13f411"},
|
||||
{"name": "ipc-utils", "version": "1.1-1", "file": "x86_64/release/ipc-utils/ipc-utils-1.1-1.tar.xz", "bytes": 11120, "sha512": "374ef40c871d00eb3b4774c383bb85872443a2e8b9abf74b8b9b9b27984598abfb6284716c2d2cd264181e6d012cf7dc8cd04f6bab91f9b083f72e9b51e6226b"},
|
||||
{"name": "less", "version": "704-1", "file": "x86_64/release/less/less-704-1-x86_64.tar.xz", "bytes": 171024, "sha512": "2d1ecf29272e7c1781bb0df5b0f0531b009972edc8d246d63e17edf7d8314109f0a8f38668b371c6f5e1dc1f948d63384eecdca5409eacb927c4f267f89f4bfe"},
|
||||
{"name": "libargp", "version": "20250917-2", "file": "x86_64/release/libargp/libargp-20250917-2-x86_64.tar.xz", "bytes": 19508, "sha512": "a83ef7c1809cae1b10a50e228643a640ea14e1be324429b9f53be9a4c8cee03ddd0efb46b24e159493dfa36569e73b636bc897943d61cdb90511e5e4cbb54257"},
|
||||
{"name": "libattr1", "version": "2.5.2-2", "file": "x86_64/release/attr/libattr1/libattr1-2.5.2-2-x86_64.tar.xz", "bytes": 6160, "sha512": "345b8f84b9c4df2eeea5e211dbaff5e0382aaee788435e1f4cc69f546e1603bbb45e9baec02a37d935674fcd55fb782d924c3a1540d2f829bde4969c96945ce4"},
|
||||
{"name": "libblkid1", "version": "2.40.2-2", "file": "x86_64/release/util-linux/libblkid1/libblkid1-2.40.2-2.tar.xz", "bytes": 120936, "sha512": "d931c47cce5a7caf18799a16ed526e0f0d0f82c0f6d0af952420d50d88f1e0f0ea9d6c07be72f9d0baa06a3299b2db8c3bd3c43d13d94400edc816e7c00da148"},
|
||||
{"name": "libbz2_1", "version": "1.0.8-2", "file": "x86_64/release/bzip2/libbz2_1/libbz2_1-1.0.8-2-x86_64.tar.xz", "bytes": 26884, "sha512": "d15d88e8e0fae69f7c4c3025515e748c273d758a0f470312162cec46c4cf0d340d2ef036e3a4f4d03b5edf4508b4927834ffa0f9aa45585a5f3bc3b3163ff675"},
|
||||
{"name": "libcrypt2", "version": "4.5.2-1", "file": "x86_64/release/libxcrypt/libcrypt2/libcrypt2-4.5.2-1-x86_64.tar.xz", "bytes": 106104, "sha512": "7668d29aaebba8ca94e48e810d92108db72b067b2786cea8dcf4a049c29f20f0aeb8653a6e9524869c69e0b1df9d4d0ac499a052a86f0d44178e8a8167002c97"},
|
||||
{"name": "libdb18.1", "version": "18.1.40-1", "file": "x86_64/release/db/libdb18.1/libdb18.1-18.1.40-1.tar.xz", "bytes": 733872, "sha512": "51955ae95823c54051b5345a7dbe6927521411754dff416ad6af2061bd3c9b2230ca2ea88f9b921b4b09b7654c7dac924b0ae08af708a93604cc193d6a18f4ff"},
|
||||
{"name": "libfdisk1", "version": "2.40.2-2", "file": "x86_64/release/util-linux/libfdisk1/libfdisk1-2.40.2-2.tar.xz", "bytes": 160264, "sha512": "0c8e6854eb72bb8cc51fc33565ee0d36a747e520e98e074a1d2400672a45651807b53be0f5a1c97efa0ce34975063f86953c9465312dcfdaba8104edb1298d62"},
|
||||
{"name": "libffi8", "version": "3.8.0-1", "file": "x86_64/release/libffi/libffi8/libffi8-3.8.0-1-x86_64.tar.xz", "bytes": 196924, "sha512": "935a0567f740a314d70ecd4adc8c4cf5ad37c6fb43f2d26dee882d4fda71f08efb2646bee10cee6e2000f52e25cce87fa29ce07665ba6d22532e0daa76bc887c"},
|
||||
{"name": "libgc1", "version": "8.2.12-1", "file": "x86_64/release/libgc/libgc1/libgc1-8.2.12-1-x86_64.tar.xz", "bytes": 62392, "sha512": "faf226ea2b58949da714e2c50f1aa95738082c3499e2ae4828af5173bdd617248f000bf4868636b31a2b76b3a905057ab307c4f6a0d7112f23422531a97be92d"},
|
||||
{"name": "libgcc1", "version": "14.4.0-1", "file": "x86_64/release/gcc/libgcc1/libgcc1-14.4.0-1-x86_64.tar.zst", "bytes": 59166, "sha512": "5ac8a56e5eee285efcd6dbd05a473e795e181021d7194b8a98dfe2fa201a71f0abe2908e0b4c81490eb5ef472efaeac8e56a61a5f289eee4ad6e90e52a844ff8"},
|
||||
{"name": "libgdbm6", "version": "1.26-1", "file": "x86_64/release/gdbm/libgdbm6/libgdbm6-1.26-1-x86_64.tar.xz", "bytes": 25436, "sha512": "8ed666a5b978b40f8cfc69d270d47cd674a31eb41bac499f783137eedfde6aa02ba4346de3d5dc3184d9af10ec80f57730c7517a88732616f4c6e0ef637d4bce"},
|
||||
{"name": "libgdbm_compat4", "version": "1.26-1", "file": "x86_64/release/gdbm/libgdbm_compat4/libgdbm_compat4-1.26-1-x86_64.tar.xz", "bytes": 3892, "sha512": "fd026dd74c495c1ee67b790269e77e8525ad78d52d4895923443feab55f7bb32dc07b115d490143c7e0277167d9cdbef5dad4707ecc7ca6df13a9f1a5184f8ca"},
|
||||
{"name": "libgmp10", "version": "6.3.0-1", "file": "x86_64/release/gmp/libgmp10/libgmp10-6.3.0-1.tar.zst", "bytes": 254680, "sha512": "947cd56e1945ddf180622b453f17e6655b4ee3e79fcc91238370a8826b88cd07c31d939f1ed7b87d91344d46fee90af2560105267a9207dcca800cba72459191"},
|
||||
{"name": "libguile3.0_1", "version": "3.0.11-1", "file": "x86_64/release/guile3.0/libguile3.0_1/libguile3.0_1-3.0.11-1-x86_64.tar.xz", "bytes": 6969492, "sha512": "a559914ed5d62d0a701e4ce3810276436cf1ce54d579c72fc72c3b4688f2af71ef93f3cdae7089ad7f85107c7ca5c87f2e497cac6f2550b38df1bc6ba7f16230"},
|
||||
{"name": "libiconv2", "version": "1.19-2", "file": "x86_64/release/libiconv/libiconv2/libiconv2-1.19-2-x86_64.tar.xz", "bytes": 555664, "sha512": "a1b23e24e0a495e7163923bcf40a4b933403e0826cfc0d9bde785bc92c909b8c4fb94b1e6b2c0242f4328a723855e72ff3baab9f557ef855b7fe7a7d901b0943"},
|
||||
{"name": "libintl8", "version": "0.22.5-1", "file": "x86_64/release/gettext/libintl8/libintl8-0.22.5-1.tar.xz", "bytes": 43256, "sha512": "370a19af888bc7c9ed95cf8ade0d36d5e7cdb634abdebcba260cad61fa9a4cc05b5e748e315c9709f66861e8756b227d6757d529846591189e19ee2b2d00002d"},
|
||||
{"name": "liblastlog2", "version": "2.40.2-2", "file": "x86_64/release/util-linux/liblastlog2/liblastlog2-2.40.2-2.tar.xz", "bytes": 4908, "sha512": "89350921fe76c9065662dd9d72dd464d2f404f1690e806210cbb828ae8325ea5f3f9909d8eb04c8342b80417a4e1e22c3569241515762ad081ecd58d56927c02"},
|
||||
{"name": "liblz4_1", "version": "1.9.4-1", "file": "x86_64/release/lz4/liblz4_1/liblz4_1-1.9.4-1.tar.xz", "bytes": 53296, "sha512": "70e6b0f3af2c5e04089c955b46c13293ab935ee4683e4690da0cebfffba4ba91614004aede99dd804f54e4def93461159f55d151e7fbb647d1ca97ca29e619cc"},
|
||||
{"name": "liblzma5", "version": "5.8.3-1", "file": "x86_64/release/xz/liblzma5/liblzma5-5.8.3-1-x86_64.tar.zst", "bytes": 87321, "sha512": "7399c6d117f23788a7edb11cf7f5eec77724aad2bf7cf8a437001fc1515941f6ca415f42363981be35361290f43cd60cd04e15bb1b01cffc0fd275f3167037e0"},
|
||||
{"name": "libmpfr6", "version": "4.2.2-1", "file": "x86_64/release/mpfr/libmpfr6/libmpfr6-4.2.2-1.tar.zst", "bytes": 284416, "sha512": "8203dc61bf646041c71f7fece9fe59422ded96ac28dd24826ffb00a9607f274f3226673f9bee441f32b424a7e26c2f178281bd7836db26b0253d37da208d06a8"},
|
||||
{"name": "libncursesw10", "version": "6.5+20240427-1", "file": "x86_64/release/ncurses/libncursesw10/libncursesw10-6.5+20240427-1.tar.xz", "bytes": 393928, "sha512": "08102f7a7083cb5663fecc46d819f2ece4123444a8f94c42300f03f7eebd40395f556c44b22ab58bf57321b44d9b8fb8b19358e535c7500d36e52d48b05dcca8"},
|
||||
{"name": "libp11-kit0", "version": "0.26.5-1", "file": "x86_64/release/p11-kit/libp11-kit0/libp11-kit0-0.26.5-1-x86_64.tar.xz", "bytes": 212700, "sha512": "dd64f129fe71233e26e0845b6711db5cf2eb2e6d2d050f07b6aec0d9dd54d980e87390614744fbf022cf57aa2b3f7edbdc30c548c2f9d480188c22bcde0c2eba"},
|
||||
{"name": "libpcre1", "version": "8.45-1", "file": "x86_64/release/pcre/libpcre1/libpcre1-8.45-1.tar.zst", "bytes": 166711, "sha512": "85c793ed3622a00b811773b94c45376882513e267b9f1d2a3efa0bc42ff86a4e4bebd8362a193d302e66ae9e5c9b93befc1bb1096c0fd397e2cd0f5632c808dd"},
|
||||
{"name": "libpcre2_8_0", "version": "10.47-1", "file": "x86_64/release/pcre2/libpcre2_8_0/libpcre2_8_0-10.47-1-x86_64.tar.zst", "bytes": 237134, "sha512": "a98b38e1591c19404a5794cef488810747d86cc27ce5ee326e706cfa7069cf088d8a64571933f4c1f7a611fd8c232008837271bebe2e81c04a3f6ec571f0009e"},
|
||||
{"name": "libpipeline1", "version": "1.5.8-1", "file": "x86_64/release/libpipeline/libpipeline1/libpipeline1-1.5.8-1-x86_64.tar.xz", "bytes": 24880, "sha512": "1d062ac4909d37fbac3ce66b07ac691df0ae5acbd01f08c5019a5ed897cb2bbef95f9e347c5bc71185ae3317d89383306e46f2c59acae5d28a18fa65f66d4e80"},
|
||||
{"name": "libpopt-common", "version": "1.19-1", "file": "x86_64/release/popt/libpopt-common/libpopt-common-1.19-1.tar.xz", "bytes": 18536, "sha512": "4d69e6d7e196cdb4caad558c5d7543f706a4c6d7053476be861be07672506e378084126f22903deab8113557f757d2a07578f4a790ae316a2ea50ba612148a43"},
|
||||
{"name": "libpopt0", "version": "1.19-1", "file": "x86_64/release/popt/libpopt0/libpopt0-1.19-1.tar.xz", "bytes": 18748, "sha512": "e820a7bac13cdd3bff07673ac54dcb80f342c6a32917035f218ef255bdb707d654ee6a1684242d7ce8439eebf050ade6566f27f5118896fbf8e0171173b5bfee"},
|
||||
{"name": "libreadline7", "version": "8.2-2", "file": "x86_64/release/readline/libreadline7/libreadline7-8.2-2.tar.xz", "bytes": 113340, "sha512": "1d27576cf49b056f35f90ad933e39c5d946bc271ddcd109daa98f95b97123b428256827889ff45ca8a76409cdb1afd0146e99c9b70150b302538356512acfe38"},
|
||||
{"name": "libreadline8", "version": "8.3-1", "file": "x86_64/release/readline/libreadline8/libreadline8-8.3-1-x86_64.tar.xz", "bytes": 120084, "sha512": "64142c5f305b9836c5be9a4271e4163d8b3e739a0451c0d152373eeb3338342f7cf5691e4437b8e6d0a8404c30ea7a21832e342e7a1ca3b5f3e8e3403051b96e"},
|
||||
{"name": "libsmartcols1", "version": "2.40.2-2", "file": "x86_64/release/util-linux/libsmartcols1/libsmartcols1-2.40.2-2.tar.xz", "bytes": 96124, "sha512": "71ded6f02d264343d068b90450d96f4fdeb4087f278b990709aaa814c16123f4ae947714e5f10020260c30a6d78865c2d35d9ffe57a51b038815db52c3274317"},
|
||||
{"name": "libsqlite3_0", "version": "3.49.1-1", "file": "x86_64/release/sqlite3/libsqlite3_0/libsqlite3_0-3.49.1-1.tar.xz", "bytes": 686212, "sha512": "cd81686fe5778a94ab91e4aebdd2a229cb963318ce7b393e0a0299e29ed7648c24135733c1978cbebbb926813d7f994b9e38318ede12c72fe79ad404dbfdeaf2"},
|
||||
{"name": "libssl3", "version": "3.5.7-1", "file": "x86_64/release/openssl/libssl3/libssl3-3.5.7-1-x86_64.tar.zst", "bytes": 2081790, "sha512": "18161f1292404554742ced4beaa10548c7e1bbfb9398ec0b733e632401dfaa49c33336ad4b1e80e2b7bd77c20f00c10196c5804c327e37f641d49da2288837b8"},
|
||||
{"name": "libstdc++6", "version": "14.4.0-1", "file": "x86_64/release/gcc/libstdc++6/libstdc++6-14.4.0-1-x86_64.tar.zst", "bytes": 651767, "sha512": "3d86409193c952618eee7e2dea32bdeb97f22ee800e13cc46f98b5095d4d0b1b31ac4336dc5819abb2d553ad1c2151619e9f6f337dfe921ba80fda1323f6f4e3"},
|
||||
{"name": "libtasn1_6", "version": "4.21.0-1", "file": "x86_64/release/libtasn1/libtasn1_6/libtasn1_6-4.21.0-1-x86_64.tar.xz", "bytes": 32072, "sha512": "d28713b27d5d41408b29caed785e29380da4d8b4ccdc1c479ae13906e6765bedc6d6b9e6c1c22fd2111d678fcf1663187d3de27d7ad2e104cd48c38086189e36"},
|
||||
{"name": "libuchardet0", "version": "0.0.8-1", "file": "x86_64/release/uchardet/libuchardet0/libuchardet0-0.0.8-1.tar.zst", "bytes": 72637, "sha512": "1fad5711590a82a8386c2492286dd9c0ad7cbe086aab249d07ad27277757327a6a67264e9718aef7d30307515462fe67d64f23582f08f0ced85a19cc8e0afe23"},
|
||||
{"name": "libunistring-devel", "version": "1.4.1-1", "file": "x86_64/release/libunistring/libunistring-devel/libunistring-devel-1.4.1-1-x86_64.tar.xz", "bytes": 43332, "sha512": "14e067719e5c0a973950955a05685c18d6fa97df5defa8d0915125ea3af1d01ac921c2a84565a49cc7fb785b15a8be4640ee209f3f0d2e13cb542eb6c75b51f9"},
|
||||
{"name": "libunistring5", "version": "1.4.1-1", "file": "x86_64/release/libunistring/libunistring5/libunistring5-1.4.1-1-x86_64.tar.xz", "bytes": 498220, "sha512": "cbd454f5068bfb9291d440a3b03b0c58437aa0342a199007d5cce6fa006b6b5ea4d3ba10c136fb0257ffb0d0199db73484275c632506e4ec31c81e1746667b80"},
|
||||
{"name": "libuuid1", "version": "2.40.2-2", "file": "x86_64/release/util-linux/libuuid1/libuuid1-2.40.2-2.tar.xz", "bytes": 12532, "sha512": "3ba0c5d5a401c88796077e9f45164532408882f2f5d9f0ab99b2fdf6eb915917250124cde3653a7c53b648866e091aa3baf3304d0b243337f0d4e254a7631f55"},
|
||||
{"name": "libzstd1", "version": "1.5.7-1", "file": "x86_64/release/zstd/libzstd1/libzstd1-1.5.7-1.tar.zst", "bytes": 253786, "sha512": "f89cdaa004487ec8c4796b8f56887c81f6f497873c1495b9cb585ffe6c8d6e6b8ad4b52617d5238075f965f1fe001da287d9a00d121590274b2d87672b415a0f"},
|
||||
{"name": "login", "version": "1.13-1", "file": "x86_64/release/login/login-1.13-1.tar.xz", "bytes": 17264, "sha512": "66acc3255962a27af8d701a8c02846f3b9180b7b1d65d946f6fb27cd24aeedc8e6a9a2601b419e981c94b356ef376a5c565ea31a4a220e5add9d70ae501a11d1"},
|
||||
{"name": "m4", "version": "1.4.21-1", "file": "x86_64/release/m4/m4-1.4.21-1-x86_64.tar.xz", "bytes": 363204, "sha512": "0d86c88d4bbbfc59e136bba3101ca3714139fba2ab7fea2883bc773ca884c3876f8a8f3a2ea8b05c29fd5280c1fb2d686401346f2761160917edf0818a2b232b"},
|
||||
{"name": "make", "version": "4.4.1-2", "file": "x86_64/release/make/make-4.4.1-2.tar.xz", "bytes": 598004, "sha512": "9a89a0f4ceadf5c2d0390029d16274fbed0190d2410ad6beb76e39b7153f38d0d1169ad0abf57c96929e6ab0523a0a76c345868e9ae46f9cd3d708d23f6fa3e6"},
|
||||
{"name": "man-db", "version": "2.13.1-1", "file": "x86_64/release/man-db/man-db-2.13.1-1-x86_64.tar.zst", "bytes": 1301518, "sha512": "a1e8a0d6d5a75465e32be83c13e685a73f084fa41abc5500d9437837a2c9de2f897827d3516c1076fa6cdd07a3d1aaaa4751f3b393fcfe64c370ff8f6b8b7f84"},
|
||||
{"name": "mintty", "version": "3.8.3-1", "file": "x86_64/release/mintty/mintty-3.8.3-1-x86_64.tar.xz", "bytes": 1190356, "sha512": "79068708c81a7bf6abba3ad1cd0550a2c3eb6f6eea21adade8b0d2b77339cd2519716f528159da9f0972f93bb624867e394d782c3e3b0b7e841a8db985395b92"},
|
||||
{"name": "ncurses", "version": "6.5+20240427-1", "file": "x86_64/release/ncurses/ncurses-6.5+20240427-1.tar.xz", "bytes": 111396, "sha512": "e15664bdab3f4d82bac6481deaa66476adbe34404937079983b5165930fa18cec3aa0345b93fbb2c390f8304ef20f041cd47d268552b92d01a51adb6abde0fc5"},
|
||||
{"name": "openssl", "version": "3.5.7-1", "file": "x86_64/release/openssl/openssl-3.5.7-1-x86_64.tar.zst", "bytes": 1392875, "sha512": "c50821b61eec47d58d1624a4a3d5a4013c80a8b48cdc803d81a656e6859079d321b34fa0ff97db4c093735a76b71a68c8a7f12184b2c4f0677014e910d1ba9d3"},
|
||||
{"name": "p11-kit", "version": "0.26.5-1", "file": "x86_64/release/p11-kit/p11-kit-0.26.5-1-x86_64.tar.xz", "bytes": 332724, "sha512": "1f057de789a5553f04649c80e6f78385135b57de7ba078e9dd51f2db60afee37717bb6de9dcf0a330cf72fce1359e08c0186988632b5f858992ebf95739bb840"},
|
||||
{"name": "p11-kit-trust", "version": "0.26.5-1", "file": "x86_64/release/p11-kit/p11-kit-trust/p11-kit-trust-0.26.5-1-x86_64.tar.xz", "bytes": 110096, "sha512": "2f98ae11e42f69fa4626638f7cefe2ba2fed808ae618093c1e6c568f8a8be79e6690b40e39e20df02a8d363c371cca8b8320fea7b288e8561cd299f15cc5b796"},
|
||||
{"name": "perl", "version": "5.44.0-1", "file": "x86_64/release/perl/perl-5.44.0-1-x86_64.tar.zst", "bytes": 5129424, "sha512": "42f80064ff94ea778319a24e011d4a7236944c79d9db22e0ed64a7ca7d9b65bc2df5998130eb64c50aa95c173937776cc42665174c5717e84fe6dca523368f27"},
|
||||
{"name": "perl-Algorithm-Diff", "version": "1.2010-5", "file": "noarch/release/perl-Algorithm-Diff/perl-Algorithm-Diff-1.2010-5-noarch.tar.zst", "bytes": 31580, "sha512": "d840b605043448ceab8ded77313e12653c81fd7db08062a99010fb19b334429c15628b1a0a805f88110e7aae4dcd3f667b515c18870ba873169533663f4374de"},
|
||||
{"name": "perl-Archive-Zip", "version": "1.680.0-1", "file": "noarch/release/perl-Archive-Zip/perl-Archive-Zip-1.680.0-1-noarch.tar.zst", "bytes": 85917, "sha512": "de23da6dac8aa8c8218c141c845723d092f6eaf2f1e67ced96d7b0385206c2e335b150bb7066bd0c7d257125ad1b3fc7691686dc535c56429b4a0f4535b6c73a"},
|
||||
{"name": "perl-Class-Inspector", "version": "1.360.0-1", "file": "noarch/release/perl-Class-Inspector/perl-Class-Inspector-1.360.0-1-noarch.tar.zst", "bytes": 21261, "sha512": "299489c9d0bc86fe8ba625c0ec0530f0e6ecacab3f67b2826760413f6bc58252c6c11f45583063cfcf0944f9127ed2bece9168fd76220e735841f374a57943f5"},
|
||||
{"name": "perl-Devel-Cycle", "version": "1.120.0-1", "file": "noarch/release/perl-Devel-Cycle/perl-Devel-Cycle-1.120.0-1-noarch.tar.zst", "bytes": 8884, "sha512": "308211af5b57106629b168be340fd682e23670fd97cc7c7f80c3bac48223984c1a226148c99cf5d904b09e352f1008f13bd4645897223a162a22af819aa7af11"},
|
||||
{"name": "perl-File-ShareDir", "version": "1.118.0-1", "file": "noarch/release/perl-File-ShareDir/perl-File-ShareDir-1.118.0-1-noarch.tar.zst", "bytes": 19857, "sha512": "7cb0f5fe4c327e9f870fc9c303f5e7e1483d2d2d012dbb5487f4b08f350170b7eb0a345766bd0a809bb4b8fa138788112eed2528b92718e817a5f21a9b82774d"},
|
||||
{"name": "perl-Text-Diff", "version": "1.450.0-1", "file": "noarch/release/perl-Text-Diff/perl-Text-Diff-1.450.0-1-noarch.tar.zst", "bytes": 30982, "sha512": "c19c80564d50d1d8efd44b156013aa5620b79205fd291897b938735c49214c84867a1337dfe9e7857f97e6f924ec919f5a0197df2d3bfeae78e0ec9dc8b9a6ac"},
|
||||
{"name": "perl-Win32-API", "version": "0.840.0-1", "file": "x86_64/release/perl-Win32-API/perl-Win32-API-0.840.0-1-x86_64.tar.zst", "bytes": 84514, "sha512": "758b1881d55942e91365780bede1dca63838995ad6574f9a242c15f613e7e3211a029e9bd3a3bd24d834ca6838e7a85c2812411783423ba23ccf808d094b6890"},
|
||||
{"name": "perl_autorebase", "version": "5.44.0-1", "file": "x86_64/release/perl/perl_autorebase/perl_autorebase-5.44.0-1-x86_64.tar.zst", "bytes": 175, "sha512": "55cd94604cfa3e2491df45e5a3715f32b2dee8298a656ca2da8de2eba4096329c595228a8c950760e9641b2c6097309571350c0ffe1c8d13759eb76ec841a4f8"},
|
||||
{"name": "perl_base", "version": "5.44.0-1", "file": "x86_64/release/perl/perl_base/perl_base-5.44.0-1-x86_64.tar.zst", "bytes": 3772189, "sha512": "3039e7a60c950cd682d8372f948ec83f7ebea27e9b425ab7406ed2eff0bebb80f7622423cf82b9ab07e34deb183bdf1b56fe129c8306bd2cfb04e7cd96beb992"},
|
||||
{"name": "rebase", "version": "4.6.6-1", "file": "x86_64/release/rebase/rebase-4.6.6-1.tar.xz", "bytes": 248832, "sha512": "9f3751c4687b09f3c286cf5c4522a0d976fce2d79ab471ab37560b15f14af84f7d13162b6102c02d0d60784448ff0586e76e9291675af4fa0c9320a3713633da"},
|
||||
{"name": "run", "version": "1.3.4-2", "file": "x86_64/release/run/run-1.3.4-2.tar.xz", "bytes": 34492, "sha512": "7e3156bbddc5f934fde3530879aa5186c9fdccb757ba848fc958e79e96534b336975f2882e413d5c18174628033a422157d25c48f8b5e90f0f1555ff2fa6343f"},
|
||||
{"name": "sed", "version": "4.10-1", "file": "x86_64/release/sed/sed-4.10-1-x86_64.tar.xz", "bytes": 359252, "sha512": "da5475344a1693f90fb560773ccca48eaf13af0e6bbcada9dcea658862bf7f46043b2d7365de0e2e235fb9a874fe784ad83bc29eb2fdbf3207cd8ad5e127b8b9"},
|
||||
{"name": "tar", "version": "1.35-2", "file": "x86_64/release/tar/tar-1.35-2.tar.zst", "bytes": 997616, "sha512": "007c7df12bc27ca14862a925680e2b2ff616a5149262b153889e6f580f3db492f98da49b5f34a8c4234194ee25021b67e9a84c987c96c5d6baa7ee0b3ea02425"},
|
||||
{"name": "terminfo", "version": "6.5+20240427-1", "file": "x86_64/release/ncurses/terminfo/terminfo-6.5+20240427-1.tar.xz", "bytes": 94760, "sha512": "128fb04f188bbf2af3060416193c9879a9cbbf7e5486febf851f35c3d9d00b9d61a0e2bf4be575d2308fd665a224ce5674485dcfd071125c3a8d199a4b88a042"},
|
||||
{"name": "texinfo", "version": "7.3-1", "file": "x86_64/release/texinfo/texinfo-7.3-1-x86_64.tar.zst", "bytes": 1853455, "sha512": "a7a0da042d05bbf2978857fcad1887552db9d77bf745fb8a17e156a2616500cf711adce107610f008ddff5556d02823f148d2bf146bd7eaa8a9466f9300cf2e6"},
|
||||
{"name": "tzcode", "version": "2026c-1", "file": "x86_64/release/tzcode/tzcode-2026c-1-x86_64.tar.xz", "bytes": 185512, "sha512": "85ab0f5d8d7c02e38dbd945c99ee6841774d84c486f857cd8484605068441b2028eea1f42a7e36c8fd6801c454f8f786a16f9caeb422afb30e5fcf324434878b"},
|
||||
{"name": "tzdata", "version": "2026c-1", "file": "noarch/release/tzdata/tzdata-2026c-1-noarch.tar.xz", "bytes": 184092, "sha512": "567adb6da01050a84b3785a1cb518e62a9c838cfe55e8ab33610c6ee64355677486329de5781361d08f03cd355acd64f94c64ec2a2686d48538813cc405b638c"},
|
||||
{"name": "util-linux", "version": "2.40.2-2", "file": "x86_64/release/util-linux/util-linux-2.40.2-2.tar.xz", "bytes": 2053568, "sha512": "4f3473472e32bff586401ec31f1423237c9cb112ae1140cdd8b2797040c5c182632f49f5354eaaa409d2dacba7767d5baa8b8926d7638e2725ad80065b46c10b"},
|
||||
{"name": "vim-minimal", "version": "9.1.1825-1", "file": "x86_64/release/vim/vim-minimal/vim-minimal-9.1.1825-1-x86_64.tar.xz", "bytes": 794064, "sha512": "6a252210e2ef08a7038d6e5bc8e5312e0c25d8328ab0aefd7f292eb79b7a32dd699f15f3f293cfbb83687e87cb3f68a335e969b117f55e6ff99b34ebdfbc8119"},
|
||||
{"name": "which", "version": "2.23-1", "file": "x86_64/release/which/which-2.23-1-x86_64.tar.xz", "bytes": 31108, "sha512": "98dffe802e1137d7b54359314797fd10080e6c261f37668e32e46aa7b1587b4148a1647b4f4a00cd0d23a9e90f153d5c2081d0ffa4ccea657b73aaa31b538d6e"},
|
||||
{"name": "xz", "version": "5.8.3-1", "file": "x86_64/release/xz/xz-5.8.3-1-x86_64.tar.zst", "bytes": 767298, "sha512": "8918389508ade8237226170b6dd02104938ec53b2bb15b310f5005dd64f954dfd67a5391757ba8602afe2a423f901894204771d6ae335402095c074d098daa76"},
|
||||
{"name": "zlib0", "version": "1.3.2-1", "file": "x86_64/release/zlib/zlib0/zlib0-1.3.2-1-x86_64.tar.zst", "bytes": 46254, "sha512": "d79ba6098cadf6bf2f32f35d9cd54729293c64b3c9daabb9d080f52861a19db71544d5710fdbd61ff45e7c2ae4eecb3f2e3b8a1e3bc05695b8cfe01c7639c53a"},
|
||||
{"name": "zstd", "version": "1.5.7-1", "file": "x86_64/release/zstd/zstd-1.5.7-1.tar.zst", "bytes": 394600, "sha512": "5de9a2fdee75345a35592444d467a1b70504f09f3b2ee5aaf8af8a9d9fda1a4e77d37c5c4c4fee9b96995ef78f9708e6c02adea7a70d9f80f1238e507b2bc0fc"}
|
||||
]
|
||||
}
|
||||
80
.github/scripts/voice_windows_tools.py
vendored
Normal file
80
.github/scripts/voice_windows_tools.py
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
"""Expose verified Windows build-tool installations as local Bazel inputs.
|
||||
|
||||
This declares the installed support trees; the caller authenticates their
|
||||
inputs and verifies the installed package inventory first.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import itertools
|
||||
import json
|
||||
from pathlib import Path
|
||||
import stat
|
||||
|
||||
|
||||
def export_repository(root: Path, target: str, pkg_config: Path):
|
||||
if target not in ("x86_64-pc-windows-msvc", "aarch64-pc-windows-msvc"):
|
||||
raise ValueError("unsupported Windows target")
|
||||
root = root.resolve(strict=True)
|
||||
pkg_config = pkg_config.resolve(strict=True)
|
||||
names = {
|
||||
"shell": "cygwin/bin/bash.exe",
|
||||
"make": "cygwin/bin/make.exe",
|
||||
"cygpath": "cygwin/bin/cygpath.exe",
|
||||
"automake": "cygwin/bin/automake-1.18",
|
||||
"pkg_config": pkg_config.relative_to(root).as_posix(),
|
||||
}
|
||||
if not names["pkg_config"].startswith("pkgconf-image/"):
|
||||
raise ValueError("pkg-config must belong to the extracted image")
|
||||
outputs = ("BUILD.bazel", "MODULE.bazel", "voice-tools.json")
|
||||
if any((root / name).exists() for name in outputs):
|
||||
raise ValueError("Bazel tool repository outputs must be fresh")
|
||||
# A nested package boundary would silently remove files from Bazel's glob.
|
||||
# Reparse points could escape the installation or hide support directories.
|
||||
for directory in ("cygwin", "pkgconf-image"):
|
||||
tree = root / directory
|
||||
if not tree.is_dir():
|
||||
raise ValueError(f"missing tool tree: {directory}")
|
||||
for path in itertools.chain((tree,), tree.rglob("*")):
|
||||
info = path.lstat()
|
||||
if (
|
||||
stat.S_ISLNK(info.st_mode)
|
||||
or getattr(info, "st_file_attributes", 0)
|
||||
& stat.FILE_ATTRIBUTE_REPARSE_POINT
|
||||
or not (stat.S_ISDIR(info.st_mode) or stat.S_ISREG(info.st_mode))
|
||||
or path.name.casefold() in ("build", "build.bazel")
|
||||
):
|
||||
raise ValueError(f"unsupported tool-tree entry: {path}")
|
||||
if any(not (root / name).is_file() for name in names.values()):
|
||||
raise ValueError("required Windows build tool missing")
|
||||
definitions = [
|
||||
'package(default_visibility = ["//visibility:public"])',
|
||||
'filegroup(name = "cygwin", srcs = glob(["cygwin/**"], allow_empty = False))',
|
||||
'filegroup(name = "pkgconf", srcs = glob(["pkgconf-image/**"], allow_empty = False))',
|
||||
'filegroup(name = "tools", srcs = [":cygwin", ":pkgconf", "voice-tools.json"])',
|
||||
]
|
||||
definitions.extend(
|
||||
f"filegroup(name = {json.dumps(name)}, srcs = [{json.dumps(path)}])"
|
||||
for name, path in names.items()
|
||||
)
|
||||
metadata = {
|
||||
"schemaVersion": 1,
|
||||
"target": target,
|
||||
"cygwinArchitecture": "x86_64",
|
||||
"tools": names,
|
||||
}
|
||||
for name, contents in (
|
||||
("BUILD.bazel", "\n".join(definitions) + "\n"),
|
||||
("MODULE.bazel", 'module(name = "voice_windows_tools")\n'),
|
||||
("voice-tools.json", json.dumps(metadata, indent=2) + "\n"),
|
||||
):
|
||||
with (root / name).open("x", encoding="utf-8") as output:
|
||||
output.write(contents)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--root", type=Path, required=True)
|
||||
parser.add_argument("--target", required=True)
|
||||
parser.add_argument("--pkg-config", type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
export_repository(args.root, args.target, args.pkg_config)
|
||||
79
.github/scripts/watch_voice_bazel.py
vendored
Normal file
79
.github/scripts/watch_voice_bazel.py
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
"""Capture one bounded diagnostic when the ARM64 voice build goes silent."""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
|
||||
|
||||
def diagnose():
|
||||
root = Path(os.environ.get("BAZEL_OUTPUT_BASE", ""))
|
||||
if not root.is_absolute():
|
||||
print("Bazel output base unavailable; skipping diagnostics", flush=True)
|
||||
return
|
||||
for relative in ("command.log", "server/jvm.out"):
|
||||
try:
|
||||
with (root / relative).open("rb") as source:
|
||||
source.seek(max(0, source.seek(0, 2) - 16384))
|
||||
print(
|
||||
f"Bazel {relative} tail:\n{source.read(16384).decode(errors='replace')}",
|
||||
flush=True,
|
||||
)
|
||||
except OSError as error:
|
||||
print(f"Cannot read {relative}: {error}", flush=True)
|
||||
try:
|
||||
pid = str(int((root / "server/server.pid.txt").read_text().strip()))
|
||||
jstack = shutil.which("jstack")
|
||||
if not jstack:
|
||||
print("jstack unavailable; log tails retained", flush=True)
|
||||
return
|
||||
result = subprocess.run([jstack, pid], capture_output=True, timeout=20)
|
||||
print(
|
||||
f"jstack exit {result.returncode}:\n{(result.stdout + result.stderr)[-65536:].decode(errors='replace')}",
|
||||
flush=True,
|
||||
)
|
||||
except (OSError, ValueError, subprocess.TimeoutExpired) as error:
|
||||
print(f"Cannot capture JVM stacks: {error}", flush=True)
|
||||
|
||||
|
||||
def main():
|
||||
with subprocess.Popen(
|
||||
sys.argv[1:], stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
||||
) as process:
|
||||
last_output = time.monotonic()
|
||||
|
||||
def forward():
|
||||
nonlocal last_output
|
||||
for line in process.stdout:
|
||||
last_output = time.monotonic()
|
||||
sys.stdout.buffer.write(line)
|
||||
sys.stdout.buffer.flush()
|
||||
|
||||
reader = threading.Thread(target=forward)
|
||||
reader.start()
|
||||
captured = False
|
||||
while process.poll() is None:
|
||||
if (
|
||||
not captured
|
||||
and os.environ.get("VOICE_ARCH") == "aarch64"
|
||||
and time.monotonic() - last_output >= 600
|
||||
):
|
||||
captured = True
|
||||
print(
|
||||
"ARM64 Bazel silent for ten minutes; capturing diagnostics",
|
||||
flush=True,
|
||||
)
|
||||
diagnose()
|
||||
time.sleep(1)
|
||||
reader.join()
|
||||
if process.returncode and not captured:
|
||||
print("Bazel command failed; capturing diagnostics", flush=True)
|
||||
diagnose()
|
||||
return process.returncode
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user