mirror of
https://github.com/oven-sh/bun
synced 2026-02-14 21:01:52 +00:00
[build images]
This commit is contained in:
@@ -143,7 +143,7 @@ async function azureFetch(method, path, body, apiVersion = "2024-07-01") {
|
||||
throw new Error(`[azure] ${method} ${path} failed after 3 retries`);
|
||||
}
|
||||
|
||||
async function waitForOperation(operationUrl, maxWaitMs = 600_000) {
|
||||
async function waitForOperation(operationUrl, maxWaitMs = 3_600_000) {
|
||||
const start = Date.now();
|
||||
let fetchErrors = 0;
|
||||
|
||||
@@ -337,6 +337,9 @@ async function createVm(opts) {
|
||||
adminUsername: opts.adminUsername,
|
||||
adminPassword: opts.adminPassword,
|
||||
},
|
||||
securityProfile: {
|
||||
securityType: "TrustedLaunch",
|
||||
},
|
||||
networkProfile: {
|
||||
networkInterfaces: [{ id: opts.nicId, properties: { deleteOption: "Delete" } }],
|
||||
},
|
||||
@@ -477,8 +480,12 @@ async function ensureImageDefinition(name, os, arch) {
|
||||
identifier: {
|
||||
publisher: "bun",
|
||||
offer: `${os}-${arch}-ci`,
|
||||
sku: "buildkite-agent",
|
||||
sku: name,
|
||||
},
|
||||
features: [
|
||||
{ name: "DiskControllerTypes", value: "SCSI, NVMe" },
|
||||
{ name: "SecurityType", value: "TrustedLaunch" },
|
||||
],
|
||||
},
|
||||
},
|
||||
GALLERY_API_VERSION,
|
||||
@@ -630,9 +637,10 @@ export const azure = {
|
||||
// This avoids the sshd startup issues on Azure Windows VMs.
|
||||
|
||||
const spawnFn = async (command, opts) => {
|
||||
// Convert command array to a single PowerShell command string
|
||||
const script = command.join(" ");
|
||||
console.log(`[azure] Run: ${script}`);
|
||||
// Note: Azure Run Command output is limited to the last 4096 bytes.
|
||||
// Full output is not available — only the tail is returned.
|
||||
const result = await runCommand(vmName, [script]);
|
||||
const stdout = typeof result === "string" ? result : (result?.value?.[0]?.message ?? "");
|
||||
if (opts?.stdio === "inherit") {
|
||||
@@ -687,40 +695,37 @@ export const azure = {
|
||||
|
||||
await generalizeVm(vmName);
|
||||
|
||||
// Ensure gallery and image definition exist
|
||||
// Ensure gallery and image definition exist.
|
||||
// Use the label as the image definition name — this matches what ci.mjs
|
||||
// emits as the image-name agent tag, so robobun can look it up directly.
|
||||
await ensureGallery();
|
||||
// Use underscore format to match robobun's getAzureGalleryImageName()
|
||||
const release = options.release || (arch === "aarch64" ? "11" : "2019");
|
||||
const safeRelease = release.replace(/\./g, "_");
|
||||
const imageDefName = `${os}_${arch}_${safeRelease}`;
|
||||
const imageDefName = label;
|
||||
await ensureImageDefinition(imageDefName, os, arch);
|
||||
|
||||
// Azure gallery image versions must be semver (Major.Minor.Patch).
|
||||
// Use timestamp-based version, and store the label as a tag so
|
||||
// robobun/CI can look up images by their logical name.
|
||||
const now = new Date();
|
||||
const version = `${now.getFullYear() % 100}.${now.getMonth() * 100 + now.getDate()}.${now.getHours() * 10000 + now.getMinutes() * 100 + now.getSeconds()}`;
|
||||
await createImageVersionWithLabel(imageDefName, version, vmId, label);
|
||||
// Create a single version "1.0.0" under this definition.
|
||||
await createImageVersion(imageDefName, "1.0.0", vmId);
|
||||
|
||||
// Wait for image version to finish provisioning before deleting the source VM
|
||||
// Wait for image replication to complete before returning.
|
||||
// Single-region replication typically takes 5-15 minutes.
|
||||
const { galleryName } = config();
|
||||
const versionPath = `${rgPath()}/providers/Microsoft.Compute/galleries/${galleryName}/images/${imageDefName}/versions/${version}`;
|
||||
console.log(`[azure] Waiting for image to replicate...`);
|
||||
const versionPath = `${rgPath()}/providers/Microsoft.Compute/galleries/${galleryName}/images/${imageDefName}/versions/1.0.0`;
|
||||
console.log(`[azure] Waiting for image replication...`);
|
||||
for (let i = 0; i < 120; i++) {
|
||||
const ver = await azureFetch("GET", versionPath, undefined, GALLERY_API_VERSION);
|
||||
const state = ver?.properties?.provisioningState;
|
||||
if (state === "Succeeded") {
|
||||
console.log(`[azure] Image replicated successfully`);
|
||||
console.log(`[azure] Image ready: ${imageDefName}/1.0.0`);
|
||||
break;
|
||||
}
|
||||
if (state === "Failed") {
|
||||
throw new Error(`[azure] Image replication failed: ${JSON.stringify(ver?.properties?.provisioningProfile)}`);
|
||||
throw new Error(`[azure] Image replication failed: ${JSON.stringify(ver?.properties)}`);
|
||||
}
|
||||
console.log(`[azure] Image state: ${state}, waiting...`);
|
||||
await new Promise(r => setTimeout(r, 15_000));
|
||||
if (i % 6 === 0) {
|
||||
console.log(`[azure] Image replicating... (${i}m elapsed)`);
|
||||
}
|
||||
await new Promise(r => setTimeout(r, 10_000));
|
||||
}
|
||||
|
||||
console.log(`[azure] Image created: ${imageDefName}/${version} (label: ${label})`);
|
||||
return label;
|
||||
};
|
||||
|
||||
|
||||
@@ -26,16 +26,6 @@ $script:IsARM64 = [System.Runtime.InteropServices.RuntimeInformation]::OSArchite
|
||||
# Utility functions
|
||||
# ============================================================================
|
||||
|
||||
function Execute-Command {
|
||||
$command = $args -join ' '
|
||||
Write-Output "$ $command"
|
||||
|
||||
& $args[0] $args[1..$args.Length]
|
||||
|
||||
if ((-not $?) -or ($LASTEXITCODE -ne 0 -and $null -ne $LASTEXITCODE)) {
|
||||
throw "Command failed: $command"
|
||||
}
|
||||
}
|
||||
|
||||
function Which {
|
||||
param ([switch]$Required = $false)
|
||||
@@ -180,7 +170,7 @@ function Install-Scoop-Package {
|
||||
}
|
||||
|
||||
Write-Output "Installing $Name (via Scoop)..."
|
||||
Execute-Command scoop install $Name
|
||||
scoop install $Name
|
||||
Refresh-Path
|
||||
}
|
||||
|
||||
@@ -192,10 +182,10 @@ function Install-Git {
|
||||
Install-Scoop-Package git
|
||||
|
||||
if ($CI) {
|
||||
Execute-Command git config --system --add safe.directory "*"
|
||||
Execute-Command git config --system core.autocrlf false
|
||||
Execute-Command git config --system core.eol lf
|
||||
Execute-Command git config --system core.longpaths true
|
||||
git config --system --add safe.directory "*"
|
||||
git config --system core.autocrlf false
|
||||
git config --system core.eol lf
|
||||
git config --system core.longpaths true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,11 +198,18 @@ function Install-CMake {
|
||||
}
|
||||
|
||||
function Install-Llvm {
|
||||
if ($script:IsARM64) {
|
||||
Install-Scoop-Package llvm-arm64 -Command clang-cl
|
||||
} else {
|
||||
Install-Scoop-Package llvm -Command clang-cl
|
||||
$LLVM_VERSION = "21.1.8"
|
||||
if (Which clang-cl) {
|
||||
return
|
||||
}
|
||||
if ($script:IsARM64) {
|
||||
Write-Output "Installing LLVM $LLVM_VERSION (ARM64 via Scoop)..."
|
||||
scoop install "llvm-arm64@$LLVM_VERSION"
|
||||
} else {
|
||||
Write-Output "Installing LLVM $LLVM_VERSION (x64 via Scoop)..."
|
||||
scoop install "llvm@$LLVM_VERSION"
|
||||
}
|
||||
Refresh-Path
|
||||
}
|
||||
|
||||
function Install-Ninja {
|
||||
@@ -257,8 +254,9 @@ function Install-Pwsh {
|
||||
return
|
||||
}
|
||||
|
||||
Write-Output "Installing PowerShell Core (ARM64)..."
|
||||
$msi = Download-File "https://github.com/PowerShell/PowerShell/releases/download/v7.5.2/PowerShell-7.5.2-win-arm64.msi" -Name "pwsh-arm64.msi"
|
||||
$pwshArch = if ($script:IsARM64) { "arm64" } else { "x64" }
|
||||
Write-Output "Installing PowerShell Core ($pwshArch)..."
|
||||
$msi = Download-File "https://github.com/PowerShell/PowerShell/releases/download/v7.5.2/PowerShell-7.5.2-win-$pwshArch.msi" -Name "pwsh-$pwshArch.msi"
|
||||
$process = Start-Process msiexec -ArgumentList "/i `"$msi`" /quiet /norestart ADD_PATH=1" -Wait -PassThru -NoNewWindow
|
||||
if ($process.ExitCode -ne 0) {
|
||||
throw "Failed to install PowerShell: code $($process.ExitCode)"
|
||||
@@ -304,7 +302,7 @@ function Install-Bun {
|
||||
Write-Output "Installing Bun..."
|
||||
$installScript = Download-File "https://bun.sh/install.ps1" -Name "bun-install.ps1"
|
||||
$pwsh = Which pwsh powershell -Required
|
||||
Execute-Command $pwsh $installScript
|
||||
& $pwsh $installScript
|
||||
}
|
||||
|
||||
function Install-Rust {
|
||||
@@ -316,7 +314,7 @@ function Install-Rust {
|
||||
$rustupInit = Download-File "https://win.rustup.rs/" -Name "rustup-init.exe"
|
||||
|
||||
Write-Output "Installing Rust..."
|
||||
Execute-Command $rustupInit -y
|
||||
& $rustupInit -y
|
||||
|
||||
Write-Output "Moving Rust to $env:ProgramFiles..."
|
||||
$rustPath = Join-Path $env:ProgramFiles "Rust"
|
||||
@@ -358,7 +356,7 @@ function Install-Visual-Studio {
|
||||
}
|
||||
|
||||
function Install-PdbAddr2line {
|
||||
Execute-Command cargo install --examples "pdb-addr2line@0.11.2"
|
||||
cargo install --examples "pdb-addr2line@0.11.2"
|
||||
}
|
||||
|
||||
function Install-Nssm {
|
||||
@@ -403,7 +401,7 @@ function Install-Buildkite {
|
||||
$env:buildkiteAgentToken = "xxx"
|
||||
$installScript = Download-File "https://raw.githubusercontent.com/buildkite/agent/main/install.ps1"
|
||||
$pwsh = Which pwsh powershell -Required
|
||||
Execute-Command $pwsh $installScript
|
||||
& $pwsh $installScript
|
||||
Refresh-Path
|
||||
|
||||
if ($CI) {
|
||||
|
||||
Reference in New Issue
Block a user