Skip to content

ci: single arm64 debian-13 build host; ThinLTO everywhere; baseline-only x64; rust+link merge; sysroots; WebKit a36c188; rust 2026-07-20 - #34782

Merged
Jarred-Sumner merged 19 commits into
mainfrom
claude/farm/6ea6ece4/ci-pr-lto-off-main-tests
Jul 21, 2026
Merged

ci: single arm64 debian-13 build host; ThinLTO everywhere; baseline-only x64; rust+link merge; sysroots; WebKit a36c188; rust 2026-07-20#34782
Jarred-Sumner merged 19 commits into
mainfrom
claude/farm/6ea6ece4/ci-pr-lto-off-main-tests

Conversation

@robobun

@robobun robobun commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

One image bake covering a set of coupled CI/build changes. Commit subject carries [build images] so the v40 images bake on this PR.

What

Single arm64 debian-12 build host

Every build lane (all 13 targets: linux x64/aarch64 gnu/musl/android/asan, darwin x64/aarch64, freebsd x64/aarch64, windows x64/aarch64) now runs on one linux-aarch64-12-debian host image and cross-compiles to its target via --target + --sysroot. buildHostPlatform in .buildkite/ci.mjs is the single source of truth; getCppAgent() / getLinkBunAgent() always pick c8g.4xlarge / r8g.2xlarge. getBuildArgs() always emits --os/--arch/--abi so resolveConfig() never infers target from the host.

scripts/build/config.ts gains a Linux cross-arch/cross-abi block: when target arch or abi differs from the host's, crossTarget is set to <arch>-unknown-linux-<gnu|musl> and sysroot to the matching /opt/linux-sysroot-{glibc,musl}{,-arm64}. scripts/build/flags.ts adds the matching --target/--sysroot linkerFlags entry. scripts/build/shims.ts points the musl CRT -print-file-name probe at the sysroot when cross-compiling.

bootstrap.sh v40

  • install_linux_glibc_sysroot(): extracts glibc 2.17 headers/libs + devtoolset libstdc++ from quay.io/pypa/manylinux2014_<arch>:latest via skopeo copy dir: + manifest-ordered layer unpack into /opt/linux-sysroot-glibc{,-arm64}. Best-effort during bake (prints a warning, does not abort); the build throws a clear BuildError if missing when cross-compiling.
  • install_linux_musl_sysroot(): extracts <triple>/ + lib/gcc/ from musl.cc/<arch>-linux-musl-cross.tgz into /opt/linux-sysroot-musl{,-arm64}.
  • install_macos_sdk(): fetches scripts/build/xmac.mjs at BUN_BOOTSTRAP_REPO_REF and splats the pinned SDK into /opt/macos-sdk, so the per-job Apple CDN fetch in configure goes away.
  • install_cross_compiler_rt(): best-effort dpkg --add-architecture amd64 + libclang-rt-<v>-dev:amd64 on arm64 debian so x64 asan cross can link. If apt.llvm.org lacks the amd64 packages on arm64 repos, the asan lane is the one candidate for an x64-host exception.
  • install_rust(): adds {x86_64,aarch64}-unknown-linux-{gnu,musl} rustup targets.
  • clean_system(): apt-get clean / dnf clean all / apk cache purge, rm -rf /tmp/*, and fstrim -av before snapshot to shrink the EBS snapshot.
  • Dead install_osxcross path and --osxcross flag removed; lsb-release and qemu-user added to apt installs.

rust-and-link merged step

getBuildRustStep() and getLinkBunStep() collapse into one getBuildBunStep() (key *-build-bun, timeout_in_minutes: 60) that runs ci-rust-and-link: ninja bun-rust, poll buildkite-agent step get outcome --step <target>-build-cpp (60m deadline), download the cpp archive, link, package. build-cpp runs in parallel with no depends_on between them. test/release/verify-baseline/binary-size depends_on stay on *-build-bun.

PR builds skip LTO

getBuildArgs() passes --lto=off on non-main branches. [lto] in the commit subject opts back in. binary-size is annotate-only on non-LTO PRs. main keeps LTO.

Tests on main, canary gated on green

The !isMainBranch() guard around test steps is dropped (asan stays PR-only). getReleaseStep() depends_on every *-test-bun key.

Test shards in their own groups

Test groups are keyed on getPlatformKey/getPlatformLabel (distro + release) instead of getTargetKey/getTargetLabel, so they no longer merge into the build groups by label. Build groups depend only on the buildHostPlatform image; test groups depend on their own native image.

verify-baseline stays arch-matched

getVerifyBaselineHost() picks a per-target-arch native host (debian-13 / windows-2019) so the pinned qemu/SDE binaries keep working. scripts/verify-baseline.ts accepts --arch instead of inferring from process.arch.

x64 is baseline-only

scripts/build/config.ts defaults baseline = true on x64, scripts/build/flags.ts drops -march=haswell. Non-baseline x64 lanes removed from ci.mjs. upload-release.sh gains alias_baseline_artifact() + rezip_as() which rezips each x64 artifact under its old non-baseline name so existing download URLs keep resolving. ENABLE_SIMD and BASELINE env constants removed from src/bun_core/env.rs; bun_warn_avx_missing removed from c-bindings.cpp and lib.rs.

Rust nightly-2026-07-20

Folds #34452. #[allow(suspicious_runtime_symbol_definitions)] on the safe fn libc extern blocks in src/bun_core/Global.rs and src/sys/lib.rs for the new lint.

scripts/packer/build-image.pkr.hcl

New Packer template with docker + amazon-ebs sources both running scripts/bootstrap.sh, so local docker run and CI AMIs share one provisioner. Not yet wired into machine.mjs.

Verification

Generated .buildkite/ci.yml under [build images] / [publish images] / [build linux images] / plain-PR: all YAML-valid, 0 dangling depends_on, 0 duplicate keys. Bake set is 9 images (1 build host + 8 test-platform). sh -n/bash -n on bootstrap.sh and upload-release.sh. bunx tsc --noEmit -p scripts/build/tsconfig.json introduces no new errors. cargo check --workspace --target {x86_64,aarch64}-unknown-linux-{gnu,musl} and {aarch64-apple-darwin, x86_64-unknown-freebsd, aarch64-pc-windows-msvc} all pass. bun bd builds; bun bd test on the four config/flags/shims-touching internal tests passes.

The actual cross-link of x64/musl binaries from an arm64 host is not exercisable locally (needs the baked sysroots); the [build images] run on this PR is the first end-to-end exercise.


no test proof · iteration 32 · Platform-specific test(s) that do not run on this machine. Deferring to CI, which covers all platforms: test/cli/run/require-cache.test.ts test/internal/macos-cross-config.test.ts test/internal/source-lints/windows-cross-config.test.ts test/js/bun/perf/linker-order.test.ts test/napi/napi.test.ts

@robobun

robobun commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator Author
Updated 3:05 AM PT - Jul 21st, 2026

@robobun, your commit 2c1bffe is building: #76764

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Changes

This PR consolidates x64 baseline handling, updates CI release gating and artifact aliases, adds Linux glibc and macOS SDK bootstrap support, pins Rust nightly toolchains, removes AVX2-based platform selection, and applies Rust fixed-size chunk and expression-based refactors.

Possibly related PRs

  • oven-sh/bun#34561: Both changes update baseline-related CI and release artifact aliasing.
  • oven-sh/bun#34207: Both changes modify baseline handling in CI and WebKit prebuilt selection.
  • oven-sh/bun#34009: Both changes update WebKit prebuilt suffix selection.

Suggested reviewers: jarred-sumner, alii

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title is verbose, but it clearly reflects the PR’s main CI/build, x64 baseline, sysroot, and Rust updates.
Description check ✅ Passed The description covers both required sections with detailed change notes and verification results.

Comment @coderabbitai help to get the list of available commands.

@robobun
robobun force-pushed the claude/farm/6ea6ece4/ci-pr-lto-off-main-tests branch from f72bd40 to 710f3fb Compare July 20, 2026 06:49
@robobun robobun changed the title ci: skip LTO on PR builds, run tests on main, gate canary on green tests ci: no-LTO PR builds, tests on main, baseline-only x64, image sysroots, rust 2026-07-20 Jul 20, 2026
@robobun
robobun force-pushed the claude/farm/6ea6ece4/ci-pr-lto-off-main-tests branch from 710f3fb to 84ca491 Compare July 20, 2026 06:52
@robobun

robobun commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator Author

Added unit tests in test/internal/macos-cross-config.test.ts for the two behavioural configure-time changes (x64 baseline default + -march=nehalem flag emission, and detectLinuxGlibcSysroot / cfg.linuxSysroot wiring). They pass on this branch and fail to load against main's scripts/build/config.ts.

Note on the fail-before gate: the src/**.rs changes in this PR are toolchain-compat refactors for the nightly-2026-07-20 lints (chunks_exact -> as_chunks, uninitialized-let -> let-if-else, isolate_lowest_one(), #[allow(suspicious_runtime_symbol_definitions)]) with zero runtime behavioural delta; there is no src/-only fail-before to construct. The configure-time tests above exercise the actual behavioural change, which lives in scripts/.

@robobun
robobun force-pushed the claude/farm/6ea6ece4/ci-pr-lto-off-main-tests branch from 10907c1 to d4d4c5e Compare July 20, 2026 06:55

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional findings (outside current diff — PR may have been updated during review):

  • 🟡 .buildkite/ci.mjs:1626-1633 — The comment says "enforce only on main or [lto] PRs", but the code is sizeRecordOnly = isMainBranch() || !options.forceLto — on main, recordOnly is true so --no-fail is passed and the size threshold is not enforced (it only records the baseline, matching pre-PR behavior and your own verification table). Enforcement happens only on [lto] PRs; consider rewording to something like "enforce only on [lto] PRs; main records the baseline; non-LTO PRs annotate only."

    Extended reasoning...

    What the comment says vs. what the code does

    The newly-added comment at .buildkite/ci.mjs:1626-1628 reads:

    Binary-size tracking. Non-LTO PR binaries are larger than the LTO main canary they compare against, so enforce only on main or [lto] PRs; other PRs still annotate.

    The code immediately below it is:

    const sizeRecordOnly = isMainBranch() || !options.forceLto;
    steps.push(getBinarySizeStep(strippedPlatforms, options, { recordOnly: sizeRecordOnly }));

    getBinarySizeStep() translates recordOnly: true into the --no-fail flag, which makes scripts/binary-size.ts annotate without failing the build. So "enforce" ↔ recordOnly === false, and "annotate only" ↔ recordOnly === true.

    Step-by-step proof

    Scenario isMainBranch() options.forceLto sizeRecordOnly --no-fail passed? Enforced?
    main true (irrelevant — short-circuit) true yes no
    PR without [lto] false false true yes no
    PR with [lto] false true (truthy string) false no yes

    So enforcement happens only on [lto] PRs. Main is record-only — it never enforces the threshold.

    The code is intentional; the comment is wrong

    Three independent sources confirm main is meant to be record-only:

    1. Pre-PR behavior: the old line was recordOnly: isMainBranch() — main was already record-only before this PR touched it.
    2. getBinarySizeStep()'s own docstring (unchanged in this PR): "Runs on PR builds (comparison) and main (record-only, to produce the baseline artifact)."
    3. The PR description's verification table: the main row shows binary-size --no-fail count = 1, i.e. main gets --no-fail.

    So the logic is deliberate and correct; only the comment's phrase "enforce only on main or [lto] PRs" contradicts it.

    Impact

    No runtime effect — this is purely a documentation inaccuracy. But per REVIEW.md, comments must "carry only durable non-obvious content" and be accurate. A future reader of this comment would reasonably conclude that main hard-fails on binary-size regressions, when in fact main only records the baseline artifact and never fails on size. That could lead to confusion when debugging why a size regression on main didn't block the canary, or when someone later revisits this gating.

    Suggested fix

    Reword the comment to match the code, e.g.:

    // Binary-size tracking. Non-LTO PR binaries are larger than the LTO main
    // canary they compare against, so enforce only on [lto] PRs; main records
    // the baseline; non-LTO PRs annotate only.

@robobun

robobun commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator Author

Good catch on the binary-size comment wording: sizeRecordOnly = isMainBranch() || !options.forceLto means only [lto] PRs enforce; main records the baseline (unchanged from before this PR). Reworded the comment to match. Holding that one-line push until the in-flight v40 image bake (build 76092) reports back so it doesn't get cancelled; will squash it into the next push.

@robobun
robobun force-pushed the claude/farm/6ea6ece4/ci-pr-lto-off-main-tests branch from d4d4c5e to 00ea037 Compare July 20, 2026 07:17

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional findings (outside current diff — PR may have been updated during review):

  • 🔴 .buildkite/scripts/upload-release.sh:340-349alias_baseline_artifact() copies the zip verbatim (cp "$artifact" "$alias"), so the inner directory is still bun-linux-x64-baseline/. On AVX2-capable machines install.sh computes target=linux-x64 (no -baseline suffix), downloads the aliased bun-linux-x64.zip, and then mv "$bin_dir/bun-linux-x64/bun" ... fails with "Failed to move extracted bun to destination" — same for install.ps1 (line 191/200 → "Download is corrupt or intercepted Antivirus?") and bun upgrade from every already-installed haswell x64 build (EXE_SUBPATH uses Version::FOLDER_NAME with Environment::BASELINE = false). The alias needs to repack: unzip → rename the inner directory to the aliased stem → re-zip.

    Extended reasoning...

    What the bug is

    upload-release.sh now aliases each *-baseline*.zip to its historical non-baseline name so "existing download URLs keep resolving" (per the code comment and the PR description). But the alias is created with a bare run_command cp "$artifact" "$alias", which renames only the zip file — the top-level directory inside the zip is unchanged.

    The zip layout is ${bunTriplet}.zip → ${bunTriplet}/bun[.exe] where bunTriplet = bun-${os}-${arch}[-musl][-baseline] (scripts/build/ci.ts:330–339, computeBunTriplet() / makeZip()). So bun-linux-x64-baseline.zip contains bun-linux-x64-baseline/bun, and after the cp the aliased bun-linux-x64.zip also contains bun-linux-x64-baseline/bun.

    Every consumer of these zips relies on the invariant that the inner directory name matches the zip filename stem — that convention is exactly what the alias exists to preserve.

    Code paths that break

    src/runtime/cli/install.sh (the curl -fsSL https://bun.sh/install | bash path):

    • Line 83: Linux x86_64target=linux-x64
    • Line 117: appends -baseline only when grep avx2 /proc/cpuinfo is empty — on the vast majority of modern x64 machines AVX2 is present, so target stays linux-x64 (or linux-x64-musl on Alpine)
    • Line 132: downloads .../bun-linux-x64.zip → gets the alias
    • Line 152: unzip -oqd "$bin_dir" "$exe.zip" → creates $bin_dir/bun-linux-x64-baseline/
    • Line 155: mv "$bin_dir/bun-linux-x64/bun" "$exe"No such file or directoryerror 'Failed to move extracted bun to destination'

    src/runtime/cli/install.ps1:

    • Line 143: $Target = "bun-windows-$BunArch" (no -baseline unless $IsBaseline, which is CPU-feature-gated)
    • Line 148: downloads .../bun-windows-x64.zip → gets the alias
    • Line 191: Test-Path "${BunBin}\bun-windows-x64\bun.exe"false (actual path is ${BunBin}\bun-windows-x64-baseline\bun.exe)
    • Line 192: throws "Download is corrupt or intercepted Antivirus?"

    src/runtime/cli/upgrade_command.rs (bun upgrade):

    • EXE_SUBPATH = Version::FOLDER_NAME + "/bun" (line 503–508), where FOLDER_NAME includes -baseline only if Environment::BASELINE is true (line 116–123)
    • Every x64 binary already installed on user machines was built as haswell (non-baseline), so Environment::BASELINE = false in those binaries → they download bun-linux-x64.zip / bun-windows-x64.zip (the alias) and look for bun-linux-x64/bun inside → extraction fails

    Why nothing prevents it

    The PR description says "the install scripts keep resolving." The URLs resolve — GitHub/S3 serve the aliased asset — but resolving the URL is only half the contract. The install scripts, install.ps1, and bun upgrade all hard-code the inner-directory-matches-zip-stem convention, and cp doesn't rewrite zip contents.

    Impact

    On the first canary shipped from main after this merges:

    • curl -fsSL https://bun.sh/install | bash fails for essentially every Linux x64 glibc and musl user with a post-2013 CPU.
    • irm bun.sh/install.ps1 | iex fails for essentially every Windows x64 user with an AVX2-capable CPU.
    • bun upgrade fails for every existing x64 install.

    Users on non-AVX2 CPUs (who get target=…-baseline and download the real -baseline.zip) are unaffected, as are aarch64 users.

    Step-by-step proof

    1. CI builds bun-linux-x64-baseline.zip containing bun-linux-x64-baseline/bun (ci.ts makeZip(cfg, bunTriplet, [...]) stages files under resolve(buildDir, bunTriplet)).
    2. upload-release.sh runs alias_baseline_artifact "bun-linux-x64-baseline.zip" → echoes bun-linux-x64.zip.
    3. run_command cp "bun-linux-x64-baseline.zip" "bun-linux-x64.zip" — byte-identical copy, inner dir still bun-linux-x64-baseline/.
    4. Both are uploaded to S3 + the GitHub release.
    5. A user on an AVX2-capable Ubuntu box runs curl -fsSL https://bun.sh/install | bash.
    6. target=linux-x64 (line 83); /proc/cpuinfo contains avx2 so line 117 does not append -baseline.
    7. bun_uri=.../releases/latest/download/bun-linux-x64.zip — downloads the alias.
    8. unzip -oqd "$HOME/.bun/bin" bun.zip → creates $HOME/.bun/bin/bun-linux-x64-baseline/bun.
    9. mv "$HOME/.bun/bin/bun-linux-x64/bun" "$HOME/.bun/bin/bun"mv: cannot stat …: No such file or directory.
    10. Script exits with error: Failed to move extracted bun to destination.

    Fix

    Repack the alias so the inner directory matches the aliased stem, e.g.:

    local alias="$(alias_baseline_artifact "$artifact")"
    if [ -n "$alias" ]; then
      local src_dir="${artifact%.zip}"
      local dst_dir="${alias%.zip}"
      rm -rf "$src_dir" "$dst_dir"
      run_command unzip -q "$artifact"
      run_command mv "$src_dir" "$dst_dir"
      run_command zip -qr "$alias" "$dst_dir"
      rm -rf "$dst_dir"
      upload_one "$alias"
    fi

    (unzip/zip are already available on the release agent — install_aws_linux installs unzip, and Amazon Linux 2023 ships zip; add a command -v zip || package_manager_install zip guard if desired.)

Comment thread scripts/build/config.ts Outdated
Comment thread scripts/build/flags.ts
@robobun
robobun force-pushed the claude/farm/6ea6ece4/ci-pr-lto-off-main-tests branch from 00ea037 to a903927 Compare July 20, 2026 07:24
Comment thread .buildkite/scripts/upload-release.sh
Comment thread scripts/build/deps/webkit.ts Outdated
@robobun
robobun force-pushed the claude/farm/6ea6ece4/ci-pr-lto-off-main-tests branch from a903927 to 0b859d1 Compare July 20, 2026 07:52

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/runtime/cli/install.ps1 (1)

133-135: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

Add one hermetic regression suite for baseline-free artifact resolution. The installer and upgrader now share unsuffixed x64 artifact naming, but the supplied tests only exercise build configuration.

  • src/runtime/cli/install.ps1#L133-L135: test plain Windows x64 archive selection for current and legacy requested versions.
  • src/runtime/cli/install.sh#L108-L110: test Unix x64 resolution through fixture-backed redirect behavior, without public-network access.
  • src/runtime/cli/upgrade_command.rs#L116-L124: test normal and profile ZIP/folder names selected by upgrade metadata parsing.

As per coding guidelines, every behavioral change must include an automated regression test in the same change.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/runtime/cli/install.ps1` around lines 133 - 135, Add a hermetic
regression suite covering baseline-free artifact resolution: in
src/runtime/cli/install.ps1 lines 133-135, test plain Windows x64 archive
selection for both current and legacy requested versions; in
src/runtime/cli/install.sh lines 108-110, test Unix x64 resolution using
fixture-backed redirects without network access; and in
src/runtime/cli/upgrade_command.rs lines 116-124, test normal and profile
ZIP/folder names produced by upgrade metadata parsing. Use the existing test
conventions and keep all cases automated within this change.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.buildkite/ci.mjs:
- Around line 158-162: Condense the Windows LTO rationale comment in
.buildkite/ci.mjs lines 158-162 to three lines or fewer while retaining the key
constraint and reference to ltoDefault. Also condense the baseline-alias
compatibility rationale comment in .buildkite/scripts/upload-release.sh lines
317-320 to three lines or fewer, preserving its essential meaning.

In @.buildkite/scripts/upload-release.sh:
- Around line 340-346: Update the archive repacking flow around src_zip and
dst_zip to derive absolute workspace paths for all rm, unzip, mv, and zip file
operations, while passing relative paths to zip as needed to preserve archive
entry names. Ensure cleanup and repacking remain anchored to the intended
workspace regardless of the caller’s current directory.

In `@scripts/bootstrap.sh`:
- Around line 1408-1474: Require checksum verification in
install_linux_glibc_sysroot before any tar extraction by populating
linux_sysroot_sha256_x86_64 and linux_sysroot_sha256_aarch64 with the matching
published digests and removing the empty-checksum fallback. Ensure each
architecture uses download_and_verify_file and aborts rather than extracting
when its checksum is missing or invalid.

In `@scripts/build/config.ts`:
- Around line 564-583: Update detectLinuxGlibcSysroot so the aarch64 candidates
cannot include the generic /opt/linux-sysroot-glibc path used for x86_64; retain
only the arm64-specific path for aarch64 and preserve the existing x86_64
candidate behavior. Keep the environment override and undefined result
unchanged.

In `@src/js_parser/parse/parse_typescript.rs`:
- Around line 637-638: Update the comment in the TypeScript parsing code to
remove the temporary reference to duplicated slice8 implementations and retain
only the durable invariant that to_utf8_e_string guarantees is_utf16 == false,
explaining why accessing .data directly is safe.

In `@src/js_printer/lib.rs`:
- Around line 7926-7932: Compress the comment immediately above module_scope
into no more than three lines, preserving both points: Scope is not Copy, and
compute_reserved_names_for_scope only traverses members/generated/children, so
referencing the in-place tree.module_scope preserves the required lifetime.

In `@test/internal/macos-cross-config.test.ts`:
- Line 76: Remove the redundant “explicit override still wins” comment from the
regression test, leaving the adjacent assertion unchanged; retain only an issue
URL comment if one is required by the project guidelines.

---

Outside diff comments:
In `@src/runtime/cli/install.ps1`:
- Around line 133-135: Add a hermetic regression suite covering baseline-free
artifact resolution: in src/runtime/cli/install.ps1 lines 133-135, test plain
Windows x64 archive selection for both current and legacy requested versions; in
src/runtime/cli/install.sh lines 108-110, test Unix x64 resolution using
fixture-backed redirects without network access; and in
src/runtime/cli/upgrade_command.rs lines 116-124, test normal and profile
ZIP/folder names produced by upgrade metadata parsing. Use the existing test
conventions and keep all cases automated within this change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2ec5289a-54b3-44cf-a26a-9793a1f92fd9

📥 Commits

Reviewing files that changed from the base of the PR and between 86fc072 and 0b859d1.

📒 Files selected for processing (48)
  • .buildkite/ci.mjs
  • .buildkite/scripts/upload-release.sh
  • .github/workflows/clippy.yml
  • .github/workflows/format.yml
  • .github/workflows/miri.yml
  • rust-toolchain.toml
  • scripts/bootstrap.sh
  • scripts/build/buildOptionsRs.ts
  • scripts/build/ci.ts
  • scripts/build/config.ts
  • scripts/build/deps/webkit.ts
  • scripts/build/flags.ts
  • scripts/build/rust.ts
  • scripts/build/source.ts
  • scripts/build/tools.ts
  • src/ast/char_freq.rs
  • src/boringssl/lib.rs
  • src/bun_alloc/lib.rs
  • src/bun_bin/lib.rs
  • src/bun_core/Global.rs
  • src/bun_core/build.rs
  • src/bun_core/env.rs
  • src/bun_core/lib.rs
  • src/collections/bit_set.rs
  • src/collections/multi_array_list.rs
  • src/crash_handler/lib.rs
  • src/css/values/color.rs
  • src/http_jsc/websocket_client/WebSocketUpgradeClient.rs
  • src/install/PackageManager/CommandLineArguments.rs
  • src/install/resolvers/folder_resolver.rs
  • src/js_parser/parse/parse_typescript.rs
  • src/js_printer/lib.rs
  • src/jsc/bindings/ANSIHelpers.h
  • src/jsc/bindings/c-bindings.cpp
  • src/jsc/bindings/xxhash3.cpp
  • src/options_types/compile_target.rs
  • src/react_compiler/ssa/enter_ssa.rs
  • src/router/lib.rs
  • src/runtime/cli/install.ps1
  • src/runtime/cli/install.sh
  • src/runtime/cli/upgrade_command.rs
  • src/runtime/image/codecs.rs
  • src/runtime/node/path.rs
  • src/runtime/socket/udp_socket.rs
  • src/runtime/valkey_jsc/valkey.rs
  • src/runtime/webcore/encoding.rs
  • src/sql_jsc/mysql/MySQLValue.rs
  • test/internal/macos-cross-config.test.ts
💤 Files with no reviewable changes (2)
  • scripts/build/buildOptionsRs.ts
  • src/jsc/bindings/c-bindings.cpp

Comment thread .buildkite/ci.mjs Outdated
Comment thread .buildkite/scripts/upload-release.sh Outdated
Comment thread scripts/bootstrap.sh Outdated
Comment thread scripts/build/config.ts
Comment thread src/js_parser/parse/parse_typescript.rs
Comment thread src/js_printer/lib.rs
Comment thread test/internal/macos-cross-config.test.ts Outdated
@robobun
robobun force-pushed the claude/farm/6ea6ece4/ci-pr-lto-off-main-tests branch from 0b859d1 to 40bcd4d Compare July 20, 2026 08:08
Comment thread src/options_types/compile_target.rs
Comment thread .buildkite/scripts/upload-release.sh Outdated
Comment thread src/bun_core/env.rs Outdated
@robobun
robobun force-pushed the claude/farm/6ea6ece4/ci-pr-lto-off-main-tests branch 2 times, most recently from 9045f7b to 2039218 Compare July 20, 2026 08:23
Comment thread scripts/build/config.ts Outdated
Comment thread src/runtime/cli/install.sh Outdated
@robobun
robobun force-pushed the claude/farm/6ea6ece4/ci-pr-lto-off-main-tests branch from 2039218 to ec0ca0f Compare July 20, 2026 08:53

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/bootstrap.sh`:
- Around line 1604-1640: Harden install_macos_sdk by eliminating execution of an
implicitly mutable xmac.mjs ref: default BUN_BOOTSTRAP_REPO_REF to the pinned
commit or tag associated with this bootstrap.sh, and add checksum verification
for the downloaded xmac_mjs before invoking it via bun. Reuse the existing
trusted-reference or sha256 validation patterns in the script, and abort before
execution when validation fails.

In `@src/jsc/bindings/ANSIHelpers.h`:
- Around line 50-53: Condense the comments at ANSIHelpers.h lines 50-53 and
77-82, and xxhash3.cpp lines 4-8, to no more than three lines each while
preserving their explanations of Highway runtime dispatch, the long-scan fast
path, and file-level dispatch rationale.

In `@src/runtime/cli/install.sh`:
- Around line 108-112: Restore the Darwin x64 branch in the target-selection
case handling so pinned Haswell releases on non-AVX2 macOS hosts probe AVX2 and
fall back to the baseline artifact. Keep the current behavior for newer releases
unchanged, and condense the associated comment to no more than three lines so it
accurately describes the preserved fallback.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1a52bebf-9a65-4677-967c-66b842860c72

📥 Commits

Reviewing files that changed from the base of the PR and between 0b859d1 and ec0ca0f.

📒 Files selected for processing (50)
  • .buildkite/ci.mjs
  • .buildkite/scripts/upload-release.sh
  • .github/workflows/clippy.yml
  • .github/workflows/format.yml
  • .github/workflows/miri.yml
  • packages/bun-release/src/platform.ts
  • rust-toolchain.toml
  • scripts/bootstrap.sh
  • scripts/build/buildOptionsRs.ts
  • scripts/build/ci.ts
  • scripts/build/config.ts
  • scripts/build/deps/webkit.ts
  • scripts/build/flags.ts
  • scripts/build/rust.ts
  • scripts/build/source.ts
  • scripts/build/tools.ts
  • src/ast/char_freq.rs
  • src/boringssl/lib.rs
  • src/bun_alloc/lib.rs
  • src/bun_bin/lib.rs
  • src/bun_core/Global.rs
  • src/bun_core/build.rs
  • src/bun_core/env.rs
  • src/bun_core/lib.rs
  • src/bun_core/string/immutable/unicode.rs
  • src/collections/bit_set.rs
  • src/collections/multi_array_list.rs
  • src/crash_handler/lib.rs
  • src/css/values/color.rs
  • src/http_jsc/websocket_client/WebSocketUpgradeClient.rs
  • src/install/PackageManager/CommandLineArguments.rs
  • src/install/resolvers/folder_resolver.rs
  • src/js_parser/parse/parse_typescript.rs
  • src/js_printer/lib.rs
  • src/jsc/bindings/ANSIHelpers.h
  • src/jsc/bindings/c-bindings.cpp
  • src/jsc/bindings/xxhash3.cpp
  • src/options_types/compile_target.rs
  • src/react_compiler/ssa/enter_ssa.rs
  • src/router/lib.rs
  • src/runtime/cli/install.ps1
  • src/runtime/cli/install.sh
  • src/runtime/cli/upgrade_command.rs
  • src/runtime/image/codecs.rs
  • src/runtime/node/path.rs
  • src/runtime/socket/udp_socket.rs
  • src/runtime/valkey_jsc/valkey.rs
  • src/runtime/webcore/encoding.rs
  • src/sql_jsc/mysql/MySQLValue.rs
  • test/internal/source-lints/windows-cross-config.test.ts
💤 Files with no reviewable changes (3)
  • scripts/build/buildOptionsRs.ts
  • src/jsc/bindings/c-bindings.cpp
  • src/bun_core/env.rs

Comment thread scripts/bootstrap.sh
Comment thread src/jsc/bindings/ANSIHelpers.h
Comment thread src/runtime/cli/install.sh Outdated
@robobun
robobun force-pushed the claude/farm/6ea6ece4/ci-pr-lto-off-main-tests branch from ec0ca0f to 890c0cd Compare July 20, 2026 09:07
Comment thread scripts/build/deps/webkit.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.buildkite/ci.mjs:
- Around line 1592-1613: Remove the unused forceTests destructuring and simplify
the test-step condition in the relevant pipeline setup to rely only on
skipTests, since getPipelineOptions does not populate forceTests. Preserve the
existing behavior of running tests when tests are not skipped and omitting them
when skipTests is enabled.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2fbfdef8-8008-438e-bfaf-99bb9668f498

📥 Commits

Reviewing files that changed from the base of the PR and between ec0ca0f and 890c0cd.

📒 Files selected for processing (51)
  • .buildkite/ci.mjs
  • .buildkite/scripts/upload-release.sh
  • .github/workflows/clippy.yml
  • .github/workflows/format.yml
  • .github/workflows/miri.yml
  • packages/bun-release/src/platform.ts
  • rust-toolchain.toml
  • scripts/bootstrap.sh
  • scripts/build/buildOptionsRs.ts
  • scripts/build/ci.ts
  • scripts/build/config.ts
  • scripts/build/deps/webkit.ts
  • scripts/build/flags.ts
  • scripts/build/rust.ts
  • scripts/build/source.ts
  • scripts/build/tools.ts
  • src/ast/char_freq.rs
  • src/boringssl/lib.rs
  • src/bun_alloc/lib.rs
  • src/bun_bin/lib.rs
  • src/bun_core/Global.rs
  • src/bun_core/build.rs
  • src/bun_core/env.rs
  • src/bun_core/lib.rs
  • src/bun_core/string/immutable/unicode.rs
  • src/collections/bit_set.rs
  • src/collections/multi_array_list.rs
  • src/crash_handler/lib.rs
  • src/css/values/color.rs
  • src/http_jsc/websocket_client/WebSocketUpgradeClient.rs
  • src/install/PackageManager/CommandLineArguments.rs
  • src/install/resolvers/folder_resolver.rs
  • src/js_parser/parse/parse_typescript.rs
  • src/js_printer/lib.rs
  • src/jsc/bindings/ANSIHelpers.h
  • src/jsc/bindings/c-bindings.cpp
  • src/jsc/bindings/xxhash3.cpp
  • src/options_types/compile_target.rs
  • src/react_compiler/ssa/enter_ssa.rs
  • src/router/lib.rs
  • src/runtime/cli/install.ps1
  • src/runtime/cli/install.sh
  • src/runtime/cli/upgrade_command.rs
  • src/runtime/image/codecs.rs
  • src/runtime/node/path.rs
  • src/runtime/socket/udp_socket.rs
  • src/runtime/valkey_jsc/valkey.rs
  • src/runtime/webcore/encoding.rs
  • src/sql_jsc/mysql/MySQLValue.rs
  • test/internal/source-lints/webkit-prebuilt-url.test.ts
  • test/internal/source-lints/windows-cross-config.test.ts
💤 Files with no reviewable changes (3)
  • src/jsc/bindings/c-bindings.cpp
  • src/bun_core/env.rs
  • scripts/build/buildOptionsRs.ts

Comment thread .buildkite/ci.mjs
Comment thread scripts/build/deps/webkit.ts Outdated
Comment thread scripts/build/flags.ts
Comment thread scripts/bootstrap.sh
@robobun
robobun force-pushed the claude/farm/6ea6ece4/ci-pr-lto-off-main-tests branch from 890c0cd to bcae883 Compare July 20, 2026 10:02

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.buildkite/ci.mjs:
- Around line 1592-1621: Add automated pipeline-generation regression tests
covering the relevantTestPlatforms filtering for main without ASAN, release test
dependency wiring through testStepKeys, and getBinarySizeStep behavior for main
versus non-LTO and LTO builds. Keep the assertions focused on generated steps
and dependencies, and place the coverage alongside the existing
.buildkite/ci.mjs pipeline-generation tests.
- Line 1643: Filter ASAN platforms out of the buildPlatforms list before passing
it to getReleaseStep in the steps.push release-step construction, while
preserving all other platform dependencies and existing release options.

In `@packages/bun-release/src/platform.ts`:
- Around line 133-136: Add automated postinstall platform-selection coverage for
supportedPlatforms, using the x64 Linux-musl scenario to assert that the plain
package is selected, the compatibility alias is excluded, and the Linux-musl
match remains included. Place the regression test alongside the existing
platform-selection tests and preserve the current filtering behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: edb90c0a-02db-498d-9986-c2a654e275ac

📥 Commits

Reviewing files that changed from the base of the PR and between 890c0cd and bcae883.

📒 Files selected for processing (52)
  • .buildkite/ci.mjs
  • .buildkite/scripts/upload-release.sh
  • .github/workflows/clippy.yml
  • .github/workflows/format.yml
  • .github/workflows/miri.yml
  • packages/bun-release/src/platform.ts
  • rust-toolchain.toml
  • scripts/bootstrap.sh
  • scripts/build/buildOptionsRs.ts
  • scripts/build/ci.ts
  • scripts/build/config.ts
  • scripts/build/deps/brotli.ts
  • scripts/build/deps/webkit.ts
  • scripts/build/flags.ts
  • scripts/build/rust.ts
  • scripts/build/source.ts
  • scripts/build/tools.ts
  • src/ast/char_freq.rs
  • src/boringssl/lib.rs
  • src/bun_alloc/lib.rs
  • src/bun_bin/lib.rs
  • src/bun_core/Global.rs
  • src/bun_core/build.rs
  • src/bun_core/env.rs
  • src/bun_core/lib.rs
  • src/bun_core/string/immutable/unicode.rs
  • src/collections/bit_set.rs
  • src/collections/multi_array_list.rs
  • src/crash_handler/lib.rs
  • src/css/values/color.rs
  • src/http_jsc/websocket_client/WebSocketUpgradeClient.rs
  • src/install/PackageManager/CommandLineArguments.rs
  • src/install/resolvers/folder_resolver.rs
  • src/js_parser/parse/parse_typescript.rs
  • src/js_printer/lib.rs
  • src/jsc/bindings/ANSIHelpers.h
  • src/jsc/bindings/c-bindings.cpp
  • src/jsc/bindings/xxhash3.cpp
  • src/options_types/compile_target.rs
  • src/react_compiler/ssa/enter_ssa.rs
  • src/router/lib.rs
  • src/runtime/cli/install.ps1
  • src/runtime/cli/install.sh
  • src/runtime/cli/upgrade_command.rs
  • src/runtime/image/codecs.rs
  • src/runtime/node/path.rs
  • src/runtime/socket/udp_socket.rs
  • src/runtime/valkey_jsc/valkey.rs
  • src/runtime/webcore/encoding.rs
  • src/sql_jsc/mysql/MySQLValue.rs
  • test/internal/source-lints/webkit-prebuilt-url.test.ts
  • test/internal/source-lints/windows-cross-config.test.ts
💤 Files with no reviewable changes (4)
  • scripts/build/deps/brotli.ts
  • scripts/build/buildOptionsRs.ts
  • src/jsc/bindings/c-bindings.cpp
  • src/bun_core/env.rs

Comment thread .buildkite/ci.mjs Outdated
Comment thread .buildkite/ci.mjs
Comment thread packages/bun-release/src/platform.ts
@robobun

robobun commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator Author

The debian-13 x64-asan lane surfaced a latent 200ms guard-timer flake in socket.io-connection-state-recovery.test.ts (the work takes ~220ms there); fixed in #35132.

Jarred-Sumner pushed a commit that referenced this pull request Jul 22, 2026
…#35132)

Fixes
`test/js/third_party/socket.io/socket.io-connection-state-recovery.test.ts`
going red on the debian-13 x64-asan lane.

## Failure

```
error: timeout
      at <anonymous> (test/js/third_party/socket.io/socket.io-connection-state-recovery.test.ts:46:26)
✗ connection state recovery > should restore session and missed packets [219.96ms]
```

Seen on builds [77055](https://buildkite.com/bun/bun/builds/77055)
(219.84ms) and [77789](https://buildkite.com/bun/bun/builds/77789)
(219.96ms), both debian-13 x64-asan.

## Cause

Each test in this file carries a `setTimeout(() => fail(...), 200)`
guard that was added when the suite was ported from upstream socket.io
in fe74c94. The [upstream
test](https://github.com/socketio/socket.io/blob/main/packages/socket.io/test/connection-state-recovery.ts)
has no such timers.

These tests drive the Engine.IO long-polling transport by hand via
supertest: the first test performs 8 sequential HTTP round trips. On
release that is ~50ms; on release+ASAN it is ~220ms. #34782 moved the
x64-asan build lane from amazonlinux-2023 to debian-13 on Jul 21, and
the failures started immediately after, with the work landing just past
the 200ms guard every time.

The guard is not a behavioral assertion. It races real work against a
wall clock and turns a slow-but-correct run into a failure. The test
runner already applies its own per-test timeout (90s, tripled under ASAN
in CI).

## Fix

Drop the guard timers and align with the upstream structure: plain
`async` tests that await the protocol events, with `io.close()` in a
`finally` block so the server is always released. Every assertion is
preserved; the same code paths are exercised.

## Verification

```
# before, bun bd (debug+asan), 5 runs: 0 pass / 7 fail every time
# after, bun bd (debug+asan), 5 runs:
7 pass / 0 fail (×5)

# release bun, 3 runs:
7 pass / 0 fail (×3)
```

<!-- robobun:evidence:begin -->

---

**[stamp-90s]** gate passed · iteration 0 · 1 files touched

<details><summary>passes on PR (with fix)</summary>

```console
Test-only change.

Debug/ASAN (expected pass):
$ bun bd test 'test/js/third_party/socket.io/socket.io-connection-state-recovery.test.ts'
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test test/js/third_party/socket.io/socket.io-connection-state-recovery.test.ts
bun test v1.4.0 (70a1c05)

test/js/third_party/socket.io/socket.io-connection-state-recovery.test.ts:
(pass) connection state recovery > should restore session and missed packets [2559.28ms]
(pass) connection state recovery > should restore rooms and data attributes [1087.52ms]
(pass) connection state recovery > should not run middlewares upon recovery by default [1125.18ms]
(pass) connection state recovery > should run middlewares even upon recovery [1000.73ms]
(pass) connection state recovery > should fail to restore an unknown session [421.80ms]
(pass) connection state recovery > should be disabled by default [434.45ms]
(pass) connection state recovery > should not call adapter#persistSession or adapter#restoreSession if disabled [405.80ms]

 7 pass
 0 fail
 43 expect() calls
Ran 7 tests across 1 file. [14.50s]
Exit: 0
```

</details>

<details><summary>diff hotspot</summary>

```
.../socket.io-connection-state-recovery.test.ts    | 318 +++++++++------------
 1 file changed, 134 insertions(+), 184 deletions(-)
```

</details>

**gate history** · 1 passed · 0 rejected · iteration 0

<details><summary>evidence per changed file</summary>

```
file                                                      reads  edits  tests
…y/socket.io/socket.io-connection-state-recovery.test.ts      2      3      0
```

</details>

**self-review** · no surviving concerns

25 concerns were raised and did not survive verification.

**root cause** · written by the author bot

The test wrapped its async work in a hardcoded 200ms setTimeout guard
that was not a behavioral assertion, and on slow ASAN builds the real
protocol steps outran that window, so the guard fired and failed the
test even though the code under test behaved correctly. The fix removes
the wall-clock guards entirely and converts each test to a plain async
function that awaits the protocol steps directly, with server cleanup
moved into a try/finally block. Hangs are now bounded by the test
runner's per-test timeout rather than an arbitrary 200ms race, and all
original assertions are preserved.

<!-- robobun:evidence:end -->
@robobun

robobun commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator Author

Heads up: under queue backlog the rust-and-link poll in waitForStepOutcome() bails on a stale errored outcome while build-cpp's retry is still scheduled; fix in #36339.

Jarred-Sumner pushed a commit that referenced this pull request Aug 12, 2026
…ailure (#37915)

### Problem
- Build lanes die in a dep fetch: `error: Failed to download after 5
attempts:
https://github.com/oven-sh/lol-html/archive/725ce499....tar.gz`, `cause:
fetch failed`. Build 93382 lost linux x64-asan on lolhtml. Build 93392
(a one-file PR) lost four lanes: x64-musl and x64-android on cares,
mimalloc and the WebKit tarball, freebsd aarch64 on lolhtml, windows
aarch64 on cares, libuv, mimalloc and WebKit.
- Those are the downloads that miss the image's prefetch cache
(everything else in the same logs says `using prefetch cache`): the deps
whose pins moved after the images were baked in #34782 (lolhtml #36733,
mimalloc #36431, c-ares #34007, libuv #36839, WebKit several times a
week), plus WebKit on every lane other than linux arm64, because
`prefetch-deps.ts` only enumerates the bake host's own target (handed
off separately). Each build makes on the order of a hundred live
github.com downloads.
- `downloadWithRetry` (`scripts/build/download.ts:156`) made 5 attempts
with 2+4+8+16s of backoff, about 30s in total. The logs show agent-wide
outages longer than that: on the x64-musl lane three downloads that
started together failed on all five attempts over roughly two minutes,
after lolhtml had succeeded on the same agent seconds earlier; on the
freebsd lane lolhtml failed five times in a row while cares and mimalloc
went through and WebKit succeeded on its second try.
- `BuildError.format()` (`scripts/build/error.ts:33`) prints one level
of cause. node's fetch throws `TypeError: fetch failed` and keeps the
real error (DNS, connect timeout, reset) in `.cause`, so every one of
these logs says only `cause: fetch failed`, and the retry lines say
nothing about what failed.

### Fix
- `downloadRetry`: 10 attempts, backoff doubling from 2s and capped at
30s, 180s of backoff in total instead of 30s. Exported as a
`RetryPolicy` (optional last parameter of `downloadWithRetry`) so the
test can run the production attempt count with the backoff zeroed.
- 408 and 429 are retried along with 5xx and network errors. Other 4xx
still fail on the first attempt and are still thrown unwrapped, which
`prefetch-deps.ts` relies on to tell a 404 (variant not published) from
a transient failure.
- Each retry line names the failure it is retrying, e.g. `retry 2/10 in
2000ms (fetch failed: other side closed)`, and `format()` prints the
whole cause chain through the new `describeError()`, so the next one of
these says what the network did.
- Why here: the prefetch cache goes stale by design as soon as a pin
moves, and WebKit moves faster than images get rebaked (the images were
rebaked on July 21 and this came back within two weeks; #30095 was an
earlier rebake for the same symptom), so the live path is permanently on
every build's critical path and has to outlast the outages CI actually
sees. The wider window only costs time while github.com is actually
down, when the lane would otherwise have failed; build-bun's step
timeout is 60 minutes.
- Verified with `test/internal/build-download-retry.test.ts` (`bun bd
test`, 7 pass). It drives the real `downloadWithRetry` against a local
server that drops connections or returns scripted statuses, checks the
retry lines and `format()` output, and pins the schedule's total backoff
at two minutes or more. Against the previous `download.ts`/`error.ts`
the file fails at import (`downloadRetry` and `describeError` did not
exist); each behavioral case is something the old loop did not do (10
attempts, 429 retried, reason on the retry line, cause chain in
`format()`).
- Also ran the loop under node, the runtime CI builds with, against a
dropping server: retry lines read `(fetch failed: other side closed)`
and the final report prints `cause: fetch failed: other side closed`.
`bunx tsc -p scripts/build/tsconfig.json` reports nothing for these
files.

### Background
- Dep fetching: configure emits one ninja `dep_fetch` edge per vendored
dep, which runs `scripts/build/fetch-cli.ts`; that calls
`downloadWithRetry` on
`https://github.com/<repo>/archive/<commit>.tar.gz`, and `fetchPrebuilt`
uses the same function for release tarballs such as WebKit. Both URL
kinds start with a 302 from github.com (to codeload.github.com and
objects.githubusercontent.com respectively), which is why one github.com
problem takes out both kinds at once.
- Prefetch cache: CI images run `scripts/prefetch-deps.ts` at bake time,
storing each tarball under `/opt/bun-prefetch/by-url/<sha256(url)>`.
`downloadWithRetry` looks there before touching the network, so a dep is
served from the image only while its pinned URL is the one that was
current at bake time; anything bumped later downloads live until the
next `[publish images]` rebake.
- `BuildError` is the build system's error type; `fetch-cli.ts` and
`build.ts` print failures through its `format()`, which produces the
`error:` / `hint:` / `cause:` lines seen in the build log.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants