diff --git a/.github/workflows/browser-demos-pages.yml b/.github/workflows/browser-demos-pages.yml index 6b24955cfc..68e4a38851 100644 --- a/.github/workflows/browser-demos-pages.yml +++ b/.github/workflows/browser-demos-pages.yml @@ -107,8 +107,9 @@ jobs: # bottle member. Repeating selection or extraction here could make # inspection and the bytes actually served by Vite disagree. bootstrap="$PWD/apps/browser-demos/public/homebrew-bootstrap.zip" + portable_ruby="$PWD/apps/browser-demos/public/homebrew-portable-ruby.zip" report="$RUNNER_TEMP/homebrew-main-shell-public-product.json" - for path in "$image" "$bootstrap"; do + for path in "$image" "$bootstrap" "$portable_ruby"; do test -f "$path" test ! -L "$path" done @@ -125,6 +126,7 @@ jobs: scripts/inspect-homebrew-main-shell-public-product.ts \ --image "$image" \ --homebrew-bootstrap-archive "$bootstrap" \ + --homebrew-portable-ruby-archive "$portable_ruby" \ --homebrew-bootstrap-spec \ homebrew/main-shell-brew-package-tree.json \ --homebrew-runtime-support \ @@ -137,6 +139,8 @@ jobs: (.image.bytes > 0) and (.homebrew_bootstrap.sha256 | test("^[0-9a-f]{64}$")) and (.homebrew_bootstrap.bytes > 0) and + (.homebrew_portable_ruby.sha256 | test("^[0-9a-f]{64}$")) and + (.homebrew_portable_ruby.bytes > 0) and .homebrew_bootstrap.activation_root == "/usr/bin/brew" and (.bottle_mirror.plan_url | startswith("https://github.com/") and @@ -146,6 +150,7 @@ jobs: { echo "image=$image" echo "bootstrap=$bootstrap" + echo "portable_ruby=$portable_ruby" echo "image_sha256=$(jq -er '.image.sha256' "$report")" echo "bootstrap_sha256=$(jq -er \ '.homebrew_bootstrap.sha256' "$report")" @@ -165,6 +170,8 @@ jobs: npm run build cmp "${{ steps.shell_product.outputs.bootstrap }}" \ dist/homebrew-bootstrap.zip + cmp "${{ steps.shell_product.outputs.portable_ruby }}" \ + dist/homebrew-portable-ruby.zip # WHY: Vite imports the resolver-selected shell under a hashed asset # name. Verify that exact emitted asset; an unhashed public copy can # be absent or stale without affecting the image the browser boots. diff --git a/.github/workflows/homebrew-main-shell-ci.yml b/.github/workflows/homebrew-main-shell-ci.yml index 1e3161a3fd..d3c6bb3a46 100644 --- a/.github/workflows/homebrew-main-shell-ci.yml +++ b/.github/workflows/homebrew-main-shell-ci.yml @@ -683,9 +683,11 @@ jobs: --output-directory "$prepared_inputs" bootstrap_root="$prepared_inputs/bootstrap" bootstrap="$bootstrap_root/homebrew-bootstrap.zip" + portable_ruby="$bootstrap_root/homebrew-portable-ruby.zip" bootstrap_env="$bootstrap_root/homebrew-brew.env" bootstrap_bottle_report="$bootstrap_root/report.json" test -f "$bootstrap" + test -f "$portable_ruby" test -f "$bootstrap_env" test -f "$bootstrap_bottle_report" artifact_state=$(jq -er '.state' \ @@ -727,6 +729,7 @@ jobs: echo "image=$candidate_root/main-shell.vfs.zst" echo "report=$candidate_root/main-shell-report.json" echo "bootstrap=$bootstrap" + echo "portable_ruby=$portable_ruby" echo "bootstrap_env=$bootstrap_env" echo "bootstrap_bottle_report=$bootstrap_bottle_report" echo "tap_sha=$tap_sha" @@ -975,6 +978,7 @@ jobs: --image "${{ steps.bottle_candidate.outputs.image }}" \ --homebrew-bootstrap-spec homebrew/main-shell-brew-package-tree.json \ --homebrew-bootstrap-archive "${{ steps.bottle_candidate.outputs.bootstrap }}" \ + --homebrew-portable-ruby-archive "${{ steps.bottle_candidate.outputs.portable_ruby }}" \ --homebrew-bootstrap-env "${{ steps.bottle_candidate.outputs.bootstrap_env }}" \ --bottle-mirror "$RUNNER_TEMP/homebrew-main-shell-bottles" \ --fixed-asset-url-root "$fixed_url_root" \ @@ -999,6 +1003,7 @@ jobs: install_browser_fixture_asset "${{ steps.bottle_candidate.outputs.image }}" install_browser_fixture_asset homebrew/main-shell-brew-package-tree.json install_browser_fixture_asset "${{ steps.bottle_candidate.outputs.bootstrap }}" + install_browser_fixture_asset "${{ steps.bottle_candidate.outputs.portable_ruby }}" install_browser_fixture_asset "${{ steps.bottle_candidate.outputs.bootstrap_env }}" echo "fixture=$fixture" >> "$GITHUB_OUTPUT" @@ -1032,6 +1037,8 @@ jobs: if [ "$SHELL_ACTIVATION_MODE" = bottles ]; then cmp "${{ steps.bottle_candidate.outputs.bootstrap }}" \ dist/homebrew-bootstrap.zip + cmp "${{ steps.bottle_candidate.outputs.portable_ruby }}" \ + dist/homebrew-portable-ruby.zip fi - name: Boot the exact installed bytes in Node @@ -1053,6 +1060,7 @@ jobs: --migration-lock homebrew/main-shell-migration-lock.json --homebrew-bootstrap-spec homebrew/main-shell-brew-package-tree.json --homebrew-bootstrap-archive "${{ steps.bottle_candidate.outputs.bootstrap }}" + --homebrew-portable-ruby-archive "${{ steps.bottle_candidate.outputs.portable_ruby }}" --homebrew-bootstrap-env "${{ steps.bottle_candidate.outputs.bootstrap_env }}" --homebrew-bootstrap-state deferred --homebrew-runtime-support homebrew/main-shell-homebrew-runtime-support.json @@ -1091,6 +1099,7 @@ jobs: --image "${{ steps.bottle_candidate.outputs.image }}" \ --homebrew-bootstrap-spec homebrew/main-shell-brew-package-tree.json \ --homebrew-bootstrap-archive "${{ steps.bottle_candidate.outputs.bootstrap }}" \ + --homebrew-portable-ruby-archive "${{ steps.bottle_candidate.outputs.portable_ruby }}" \ --homebrew-bootstrap-env "${{ steps.bottle_candidate.outputs.bootstrap_env }}" \ --transport-mode closed \ --bottle-mirror-plan "${{ steps.mirror.outputs.plan }}" \ @@ -1220,6 +1229,7 @@ jobs: ${{ steps.source_candidate.outputs.manifest }} ${{ steps.bottle_candidate.outputs.report }} ${{ steps.bottle_candidate.outputs.bootstrap }} + ${{ steps.bottle_candidate.outputs.portable_ruby }} ${{ steps.bottle_candidate.outputs.bootstrap_env }} ${{ steps.bottle_candidate.outputs.bootstrap_bottle_report }} ${{ runner.temp }}/homebrew-main-shell-bottles diff --git a/.github/workflows/reusable-homebrew-main-shell-mirror-publish.yml b/.github/workflows/reusable-homebrew-main-shell-mirror-publish.yml index 24d054b4c1..de6b2319e1 100644 --- a/.github/workflows/reusable-homebrew-main-shell-mirror-publish.yml +++ b/.github/workflows/reusable-homebrew-main-shell-mirror-publish.yml @@ -242,8 +242,9 @@ jobs: --require-sealed \ --output-directory "$bootstrap_root" bootstrap="$bootstrap_root/homebrew-bootstrap.zip" + portable_ruby="$bootstrap_root/homebrew-portable-ruby.zip" bootstrap_env="$bootstrap_root/homebrew-brew.env" - for path in "$image" "$bootstrap" "$bootstrap_env"; do + for path in "$image" "$bootstrap" "$portable_ruby" "$bootstrap_env"; do test -f "$path" test ! -L "$path" done @@ -254,6 +255,7 @@ jobs: { echo "image=$image" echo "bootstrap=$bootstrap" + echo "portable-ruby=$portable_ruby" echo "bootstrap-env=$bootstrap_env" } >>"$GITHUB_OUTPUT" @@ -305,6 +307,7 @@ jobs: env: IMAGE: ${{ steps.shell.outputs.image }} BOOTSTRAP: ${{ steps.shell.outputs.bootstrap }} + PORTABLE_RUBY: ${{ steps.shell.outputs.portable-ruby }} BOOTSTRAP_ENV: ${{ steps.shell.outputs.bootstrap-env }} MIRROR: ${{ steps.mirror.outputs.root }} PUBLISH: ${{ steps.mirror.outputs.publish }} @@ -321,6 +324,7 @@ jobs: mkdir "$handoff" cp "$IMAGE" "$handoff/main-shell.vfs.zst" cp "$BOOTSTRAP" "$handoff/homebrew-bootstrap.zip" + cp "$PORTABLE_RUBY" "$handoff/homebrew-portable-ruby.zip" cp "$BOOTSTRAP_ENV" "$handoff/homebrew-brew.env" cp "$PUBLISH" "$handoff/publish.json" cp -R "$MIRROR" "$handoff/mirror" @@ -345,6 +349,8 @@ jobs: --argjson image_bytes "$(bytes "$handoff/main-shell.vfs.zst")" \ --arg bootstrap_sha "$(digest "$handoff/homebrew-bootstrap.zip")" \ --argjson bootstrap_bytes "$(bytes "$handoff/homebrew-bootstrap.zip")" \ + --arg portable_ruby_sha "$(digest "$handoff/homebrew-portable-ruby.zip")" \ + --argjson portable_ruby_bytes "$(bytes "$handoff/homebrew-portable-ruby.zip")" \ --arg env_sha "$(digest "$handoff/homebrew-brew.env")" \ --argjson env_bytes "$(bytes "$handoff/homebrew-brew.env")" \ --arg publish_sha "$(digest "$handoff/publish.json")" \ @@ -367,6 +373,9 @@ jobs: "homebrew-bootstrap.zip": { sha256: $bootstrap_sha, bytes: $bootstrap_bytes }, + "homebrew-portable-ruby.zip": { + sha256: $portable_ruby_sha, bytes: $portable_ruby_bytes + }, "homebrew-brew.env": { sha256: $env_sha, bytes: $env_bytes }, @@ -408,6 +417,7 @@ jobs: env: IMAGE: ${{ steps.shell.outputs.image }} BOOTSTRAP: ${{ steps.shell.outputs.bootstrap }} + PORTABLE_RUBY: ${{ steps.shell.outputs.portable-ruby }} BOOTSTRAP_ENV: ${{ steps.shell.outputs.bootstrap-env }} MIRROR_PLAN: ${{ steps.mirror.outputs.root }}/kandelo-homebrew-bottle-mirror-plan.json KANDELO_REF: ${{ inputs.kandelo-ref }} @@ -431,6 +441,7 @@ jobs: --homebrew-bootstrap-spec \ homebrew/main-shell-brew-package-tree.json \ --homebrew-bootstrap-archive "$BOOTSTRAP" \ + --homebrew-portable-ruby-archive "$PORTABLE_RUBY" \ --homebrew-bootstrap-env "$BOOTSTRAP_ENV" \ --bottle-mirror-plan "$MIRROR_PLAN" \ --kandelo-ref "$KANDELO_REF" \ @@ -627,7 +638,7 @@ jobs: .repository == "kandelo-dev/homebrew-tap-core" and .target_commitish == $tap and .immutable == true and - (.assets | length) == 4 + (.assets | length) == 5 ' "$lifecycle_receipt" >/dev/null { echo "mirror-receipt=$mirror_receipt" @@ -789,6 +800,7 @@ jobs: main-shell.vfs.zst \ main-shell-brew-package-tree.json \ homebrew-bootstrap.zip \ + homebrew-portable-ruby.zip \ homebrew-brew.env do env -u GH_TOKEN -u GITHUB_TOKEN \ @@ -803,11 +815,14 @@ jobs: "$lifecycle/main-shell-brew-package-tree.json" cmp "$handoff/homebrew-bootstrap.zip" \ "$lifecycle/homebrew-bootstrap.zip" + cmp "$handoff/homebrew-portable-ruby.zip" \ + "$lifecycle/homebrew-portable-ruby.zip" cmp "$handoff/homebrew-brew.env" \ "$lifecycle/homebrew-brew.env" { echo "image=$lifecycle/main-shell.vfs.zst" echo "bootstrap=$lifecycle/homebrew-bootstrap.zip" + echo "portable-ruby=$lifecycle/homebrew-portable-ruby.zip" echo "bootstrap-env=$lifecycle/homebrew-brew.env" } >>"$GITHUB_OUTPUT" @@ -825,6 +840,7 @@ jobs: env: IMAGE: ${{ steps.public.outputs.image }} BOOTSTRAP: ${{ steps.public.outputs.bootstrap }} + PORTABLE_RUBY: ${{ steps.public.outputs.portable-ruby }} BOOTSTRAP_ENV: ${{ steps.public.outputs.bootstrap-env }} TAP_CATALOG_REF: ${{ inputs.tap-catalog-ref }} CANARY_REF: ${{ inputs.canary-ref }} @@ -839,6 +855,7 @@ jobs: env: IMAGE: ${{ steps.public.outputs.image }} BOOTSTRAP: ${{ steps.public.outputs.bootstrap }} + PORTABLE_RUBY: ${{ steps.public.outputs.portable-ruby }} BOOTSTRAP_ENV: ${{ steps.public.outputs.bootstrap-env }} TAP_CATALOG_REF: ${{ inputs.tap-catalog-ref }} CANARY_REF: ${{ inputs.canary-ref }} @@ -980,9 +997,11 @@ jobs: lifecycle="$RUNNER_TEMP/homebrew-guest-lifecycle-inputs-handoff" image="$(bash scripts/resolve-binary.sh programs/shell.vfs.zst)" bootstrap="$PWD/apps/browser-demos/public/homebrew-bootstrap.zip" + portable_ruby="$PWD/apps/browser-demos/public/homebrew-portable-ruby.zip" bootstrap_env="$lifecycle/homebrew-brew.env" cmp "$image" "$handoff/main-shell.vfs.zst" cmp "$bootstrap" "$handoff/homebrew-bootstrap.zip" + cmp "$portable_ruby" "$handoff/homebrew-portable-ruby.zip" cmp "$bootstrap_env" "$handoff/homebrew-brew.env" plan="$handoff/mirror/kandelo-homebrew-bottle-mirror-plan.json" plan_url="$(jq -er '.release_root + "/" + .manifest_asset' "$plan")" @@ -994,6 +1013,7 @@ jobs: main-shell.vfs.zst \ main-shell-brew-package-tree.json \ homebrew-bootstrap.zip \ + homebrew-portable-ruby.zip \ homebrew-brew.env do env -u GH_TOKEN -u GITHUB_TOKEN \ @@ -1006,10 +1026,12 @@ jobs: cmp homebrew/main-shell-brew-package-tree.json \ "$lifecycle/main-shell-brew-package-tree.json" cmp "$bootstrap" "$lifecycle/homebrew-bootstrap.zip" + cmp "$portable_ruby" "$lifecycle/homebrew-portable-ruby.zip" cmp "$bootstrap_env" "$lifecycle/homebrew-brew.env" { echo "image=$image" echo "bootstrap=$bootstrap" + echo "portable-ruby=$portable_ruby" echo "bootstrap-env=$bootstrap_env" echo "plan-url=$plan_url" echo "image-sha=$(sha256sum "$image" | awk '{print $1}')" @@ -1027,12 +1049,17 @@ jobs: run: | set -euo pipefail browser_bootstrap=public/homebrew-bootstrap.zip + browser_portable_ruby=public/homebrew-portable-ruby.zip test -f "$browser_bootstrap" test ! -L "$browser_bootstrap" + test -f "$browser_portable_ruby" + test ! -L "$browser_portable_ruby" # WHY: prepare-browser owns this fixed same-origin asset. The build # must consume those admitted bytes instead of silently replacing # them from a second package source. cmp "${{ steps.public.outputs.bootstrap }}" "$browser_bootstrap" + cmp "${{ steps.public.outputs.portable-ruby }}" \ + "$browser_portable_ruby" # WHY: dev-shell intentionally drops ambient variables. Forward the # selector or Vite builds its default pages and omits the proof page. bash ../../scripts/dev-shell.sh env \ @@ -1043,6 +1070,8 @@ jobs: test -f dist/pages/homebrew-vfs-test/index.html cmp "${{ steps.public.outputs.bootstrap }}" \ dist/homebrew-bootstrap.zip + cmp "${{ steps.public.outputs.portable-ruby }}" \ + dist/homebrew-portable-ruby.zip bash ../../scripts/verify-browser-shell-vfs-asset.sh \ dist "${{ steps.public.outputs.image }}" @@ -1065,6 +1094,8 @@ jobs: "$lifecycle/main-shell-brew-package-tree.json" \ --homebrew-bootstrap-archive \ "$lifecycle/homebrew-bootstrap.zip" \ + --homebrew-portable-ruby-archive \ + "$lifecycle/homebrew-portable-ruby.zip" \ --homebrew-bootstrap-env "$lifecycle/homebrew-brew.env" \ --bottle-mirror \ "$RUNNER_TEMP/main-shell-mirror-handoff/mirror" \ diff --git a/apps/browser-demos/pages/homebrew-benchmark/index.html b/apps/browser-demos/pages/homebrew-benchmark/index.html new file mode 100644 index 0000000000..b79cc00752 --- /dev/null +++ b/apps/browser-demos/pages/homebrew-benchmark/index.html @@ -0,0 +1,12 @@ + + +
+ + +Preparing Homebrew query benchmark…+ + + diff --git a/apps/browser-demos/pages/homebrew-benchmark/main.ts b/apps/browser-demos/pages/homebrew-benchmark/main.ts new file mode 100644 index 0000000000..3bc2cefcdf --- /dev/null +++ b/apps/browser-demos/pages/homebrew-benchmark/main.ts @@ -0,0 +1,350 @@ +import { BrowserKernel } from "@host/browser-kernel-host"; +import type { SyscallTraceEvent } from "@host/kernel-worker"; +import type { LazyDownloadEvent } from "@host/vfs/memory-fs"; +import type { ClosedLazyAsset } from "@host/vfs/closed-lazy-assets"; +import { + assertHomebrewQueryFixture, + commandScript, + emptyProcessCounts, + medianMetrics, + summarizeLazyDownloads, + type HomebrewQueryArtifact, + type HomebrewQueryCommand, + type HomebrewQueryCommandResult, + type HomebrewQueryFixtureManifest, + type HomebrewQueryNetworkAudit, + type HomebrewQueryProcessCounts, + type HomebrewQueryScenarioResult, +} from "../../../../benchmarks/homebrew-query/contracts"; +import { + runHomebrewQueryScenario, + type HomebrewQueryMachine, + type HomebrewQueryMachineFactory, +} from "../../../../benchmarks/homebrew-query/scenario"; + +declare global { + interface Window { + __homebrewQueryBenchmarkReady: boolean; + __runHomebrewQueryBenchmark( + rounds: number, + auditNetwork?: boolean, + ): Promise<{ + fixture: HomebrewQueryFixtureManifest; + rounds: HomebrewQueryScenarioResult[]; + median: Record