Skip to content

feat: single apify-cli bundle + native Windows ARM64 (supersedes #1057)#1169

Open
vladfrangu wants to merge 4 commits into
masterfrom
feat/single-cli-bundle
Open

feat: single apify-cli bundle + native Windows ARM64 (supersedes #1057)#1169
vladfrangu wants to merge 4 commits into
masterfrom
feat/single-cli-bundle

Conversation

@vladfrangu
Copy link
Copy Markdown
Member

What & why

Reworks how the CLI bundles are built, installed, and upgraded, and adds native Windows ARM64 support.

Previously the bundle install shipped three full ~70 MB binaries (apify, actor, apify-cli) — the same binary dropped three times into the install dir. This builds one apify-cli bundle; apify and actor become tiny wrapper scripts that invoke it with APIFY_CLI_ENTRYPOINT set, which the entrypoint uses to pick the command set.

Note

This supersedes #1057 (native Windows ARM bundles) — those changes are included here, adapted on top of the single-bundle work. See the "Windows ARM64" section for one deliberate deviation.

Single-bundle layout

  • Build (build-cli-bundles.ts): build only the apify-cli entrypoint; additionally publish apify-*/actor-* copies as backwards-compatible backups so installs using the old two-bundle upgrade flow can still pull the new bundle during the transition.
  • Entrypoint: new single apify-cli.ts entrypoint + resolveEntrypoint() (reads APIFY_CLI_ENTRYPOINT, falls back to the executable's basename).
  • Install (install.sh / install.ps1): drop the apify-cli binary and generate apify/actor (.cmd on Windows) wrapper scripts instead of three binaries.
  • Self-migration (bundleMigration.ts): on the first run after upgrading from a legacy 3-bundle install, copy the running bundle to apify-cli and replace apify/actor with wrapper scripts. Writes are atomic (temp + rename) so we never truncate a running executable — an in-place overwrite fails with ETXTBSY on Linux (verified in a container; this matters because the actor CLI runs in Linux Actor images). On Windows the running .exe is renamed (can't be deleted) and cleaned up on a later run.
  • Upgrade (upgrade.ts): download the single apify-cli bundle, write it + the wrappers atomically.

Windows ARM64 (supersedes #1057)

Bun now ships native Windows ARM64 builds, so the old hack (compile an x64 bundle on the ARM runner and relabel it arm64) is gone.

  • Build a native bun-windows-arm64 target; drop the pwsh SystemType detection + APIFY_BUNDLE_ARCH override.
  • install.ps1: detect arch from PROCESSOR_ARCHITECTURE; ARM64 never downloads a -baseline bundle (baseline is x64/AVX2-only).
  • useCLIVersionAssets: Windows ARM64 now matches the native (non-baseline) asset — a fix chore: native windows arm bundles #1057 lacks; without it the upgrade command finds zero assets on Windows ARM64.
  • CI (check/pre_release/release): build on windows-11-arm with native setup-bun (dropped the manual install workaround) via a bun-target-arch matrix var.

Deviation from #1057: asset names keep the arm64 suffix (matching the produced artifacts, useCLIMetadata's process.arch, and the asset matcher) rather than renaming to aarch64, which in #1057 mismatches the -arm64 artifacts the build actually emits.

Bundle target cleanup

  • Removed the as never casts on the bun compile targets. Per Bun's supported-targets matrix, @types/bun's CompileTarget only accepts the SIMD-then-libc order, so bun-linux-x64-musl-baselinebun-linux-x64-baseline-musl (bun accepts either order at build time). The target parser now reads the trailing modifiers order-independently and still emits the canonical -musl-baseline asset suffix, so every published asset name is unchanged.
  • Stopped building bun-{darwin,linux}-arm64-baseline (and the arm64 musl-baseline): baseline is x64-only, so these just duplicated the non-baseline arm64 builds. They're unreachable via the install/upgrade path, and download counts confirm no real usage (~205 total / max 3 per release — scraper-noise floor — vs darwin-arm64 at 1557 / max 260).

Testing

  • pnpm run build, oxlint, oxfmt, and the local test suite all pass.
  • Verified the full legacy→migrated flow end-to-end on Linux (arm64 container): 3 binaries → single apify-cli + wrapper scripts, idempotent, actor runs in actor mode.
  • Confirmed ETXTBSY on in-place overwrite vs success with atomic rename on Linux.
  • Confirmed Bun accepts bun-windows-arm64 and the reordered bun-linux-x64-baseline-musl targets and appends .exe for Windows.

Added dev-test-install-legacy.sh to reproduce the old 3-binary layout locally for testing the migration.

The CLI previously shipped three full bundles (apify, actor, apify-cli),
dropping the same ~70MB binary three times into the install directory.
Now we build one apify-cli bundle; apify and actor are tiny wrapper
scripts that invoke it with APIFY_CLI_ENTRYPOINT set, which the entrypoint
uses to pick the command set.

- build-cli-bundles: build only apify-cli; publish apify-*/actor-* copies
  as backwards-compatible backups for the old upgrade flow
- entrypoints: new apify-cli entrypoint + resolveEntrypoint()
- install.sh / install.ps1 / dev-test-install.sh: drop the apify-cli binary
  and generate apify/actor (.cmd on Windows) wrapper scripts
- upgrade: download the single apify-cli bundle; write it and the wrappers
  atomically (temp + rename) to avoid ETXTBSY on a running binary (Linux)
- bundleMigration: on first run after upgrading from a legacy 3-bundle
  install, copy the running bundle to apify-cli and replace apify/actor
  with wrappers (rename-not-delete on Windows for the running exe)
- useCLIVersionAssets: match only apify-cli-* assets, ignoring backups
- add dev-test-install-legacy.sh to reproduce the old layout for testing
Bun now ships native Windows ARM64 builds, so drop the hack that compiled
an x64 bundle and relabelled it as arm64.

- build-cli-bundles: build a native bun-windows-arm64 target (full list and
  the win32 branch); remove the pwsh SystemType detection + APIFY_BUNDLE_ARCH
  override and the per-target metadata reset
- install.ps1: detect the arch from PROCESSOR_ARCHITECTURE; only x64 has
  baseline (non-AVX2) builds, so ARM64 never downloads a -baseline bundle
- install.sh: map MINGW64 ARM64 to the windows-arm64 target
- useCLIVersionAssets: Windows ARM64 has a native (non-baseline) bundle, so
  stop requiring -baseline assets there (otherwise upgrade finds no asset)
- CI (check/pre_release/release): build on windows-11-arm with native bun via
  setup-bun (drop the manual install workaround) and a bun-target-arch matrix

Unlike #1057, asset names keep the arm64 suffix (matching the build output,
useCLIMetadata's process.arch, and the asset matcher) rather than renaming to
aarch64, which in #1057 mismatches the produced -arm64 artifacts.
Per Bun's supported-targets matrix (https://bun.com/docs/bundler/executables#supported-targets),
baseline/modern (SIMD) variants only exist for x64, and @types/bun's CompileTarget
union only accepts the SIMD-then-libc order (`bun-linux-x64-baseline-musl`).

- reorder `bun-linux-x64-musl-baseline` -> `bun-linux-x64-baseline-musl` so it
  matches the type (no cast needed); bun accepts either order at build time
- drop `bun-linux-arm64-musl-baseline`: arm64 has no baseline variant, so it was a
  meaningless duplicate of the arm64 musl build and nothing ever requested it
- parse the target's trailing modifiers order-independently and still emit the
  asset suffix in the canonical `-musl-baseline` order the install/upgrade
  matchers expect, so every published asset name is unchanged
Baseline (non-AVX2) builds are an x64-only concept, so bun-darwin-arm64-baseline
and bun-linux-arm64-baseline just duplicated their non-baseline arm64 builds. The
install/upgrade flow never requests them (baseline is only ever appended for x64),
and GitHub download counts confirm no real usage: across all releases the arm64
baseline assets sit at the scraper-noise floor (~205 total, max 3/release) versus
darwin-arm64 at 1557 (max 260) and linux-arm64 at 262 (max 15).
@github-actions github-actions Bot added this to the 141st sprint - Tooling team milestone May 29, 2026
@github-actions github-actions Bot added the t-tooling Issues with this label are in the ownership of the tooling team. label May 29, 2026
@vladfrangu vladfrangu requested review from Copilot and l2ysho and removed request for Copilot May 29, 2026 14:30
@vladfrangu vladfrangu added the adhoc Ad-hoc unplanned task added during the sprint. label May 29, 2026
@vladfrangu vladfrangu requested a review from Copilot May 29, 2026 14:39
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

bun build --compile --target=bun-windows-x64 --outfile test index.ts
bun build --compile --target=bun-windows-x64-baseline --outfile test index.ts
bun build --compile --target=bun-windows-${{ matrix.bun-target-arch }} --outfile test index.ts
bun build --compile --target=bun-windows-${{ matrix.bun-target-arch }}-baseline --outfile test index.ts
bun build --compile --target=bun-windows-x64 --outfile test index.ts
bun build --compile --target=bun-windows-x64-baseline --outfile test index.ts
bun build --compile --target=bun-windows-${{ matrix.bun-target-arch }} --outfile test index.ts
bun build --compile --target=bun-windows-${{ matrix.bun-target-arch }}-baseline --outfile test index.ts
bun build --compile --target=bun-windows-x64 --outfile test index.ts
bun build --compile --target=bun-windows-x64-baseline --outfile test index.ts
bun build --compile --target=bun-windows-${{ matrix.bun-target-arch }} --outfile test index.ts
bun build --compile --target=bun-windows-${{ matrix.bun-target-arch }}-baseline --outfile test index.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

adhoc Ad-hoc unplanned task added during the sprint. t-tooling Issues with this label are in the ownership of the tooling team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants