LOC-7291: download darwin-arm64 binary on Apple Silicon - #15
LOC-7291: download darwin-arm64 binary on Apple Silicon#15vivianludrick wants to merge 2 commits into
Conversation
On macOS the binding now selects BrowserStackLocal-darwin-arm64 when the runtime reports arm64/aarch64; x64 runtimes (including x64-under-Rosetta) keep BrowserStackLocal-darwin-x64, preserving current behavior. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
07souravkunda
left a comment
There was a problem hiding this comment.
Detection logic is correct — (POSIX::uname())[4] against arm64/aarch64 is the right call here since $Config{archname} reflects the perl build rather than the host, and adding use POSIX () with the empty import list avoids polluting the namespace. x64-under-Rosetta correctly keeps the x64 binary.
No code objection. The one thing to resolve before release is the legacy-bucket gap you flagged yourself: unlike the bindings that resolve their URL from Rails, this one hardcodes s3.amazonaws.com/browserStack/browserstack-local/, so it regresses on release day rather than degrading later — and because getstore's status is unchecked, the resulting 404 is written to the binary path and short-circuits every later run. Details inline.
| sub platform_url { | ||
| if ($^O =~ "darwin") { | ||
| if ((POSIX::uname())[4] =~ /arm64|aarch64/) { | ||
| return "http://s3.amazonaws.com/browserStack/browserstack-local/BrowserStackLocal-darwin-arm64"; |
There was a problem hiding this comment.
This URL has no object behind it and no publisher, so releasing this turns a working download into a hard 404 on Apple Silicon.
You've documented it in the PR body, but it's worth separating this binding from the others: nodejs/python/ruby/java/csharp resolve their source URL from Rails / bstack-local-prod, so they only degrade once Rosetta is gone. perl and php hardcode the legacy s3.amazonaws.com/browserStack/browserstack-local/ host, so they break immediately on release — an arm64 Mac that works today via the Rosetta x64 binary starts failing at download.
And the failure is sticky. download_binary ignores getstore's return status, so the error response lands at $self->{binary_path} and gets chmod 0777'd. get_binary_path then short-circuits on the -x/-X check on every subsequent run, so the user stays broken until they delete the file by hand.
Fix — either:
- Gate the release on
BrowserStackLocal-darwin-arm64being published to that bucket, and added to whatever publishes the other legacy objects; or - Check
getstore's status and fall back to the x64 URL on failure, so the regression can't fire even if the release ordering slips.
Given the sticky-file behaviour, option 2 looks worth doing regardless of ordering.
There was a problem hiding this comment.
Went with option 2 (plus the sticky-file fix) — done in the latest commit:
getstore's status is now checked (is_success).- A failed
-darwin-arm64download falls back to the-darwin-x64URL (still works on Apple Silicon via Rosetta 2), so release ordering can't turn a working download into a 404. - If every attempt fails, the file is
unlinked and the error is raised —get_binary_path's-xcheck can no longer short-circuit on a saved error body.
Verified with a stubbed-getstore harness: arm64 404 → x64 fallback succeeds; both-fail → dies with no poisoned file left. Option 1 (publishing arm64 to the legacy bucket) stays on the release-ordering list so arm64 users eventually get the native binary here too, but it's no longer a correctness gate.
Per review on PR #15: this binding hardcodes the legacy S3 host, where the arm64 object may not exist yet — and getstore's status was ignored, so an HTTP error body would be saved as the binary and satisfy the -x check forever. Now: getstore status is checked; a failed -darwin-arm64 download falls back to the x64 binary (works on Apple Silicon via Rosetta 2); if everything fails, the file is removed and the error is raised instead of left on disk. Verified with a stubbed-getstore harness: arm64 404 -> x64 fallback succeeds; both-fail -> dies, no poisoned file left. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
What
On macOS, the binding now downloads
BrowserStackLocal-darwin-arm64when the runtime reports arm64; x64 runtimes (including x64-under-Rosetta) keepBrowserStackLocal-darwin-x64, preserving current behavior.Detection: (POSIX::uname())[4] =~ /arm64|aarch64/.
Why
The Local binary now ships a native Apple Silicon build (browserstack/browserStackTunnel#980). macOS 27 (fall 2026) removes Rosetta 2, so arm64 Macs need the native binary.
Testing
perl -c syntax OK; platform_url() returns the arm64 URL on an Apple Silicon Mac.
⚠ Release ordering
Do not release this before:
binaries/master/BrowserStackLocal-darwin-arm64.zip(public ACL line is already in the Jenkins job) — otherwise arm64 Macs get download failures.Related Jira
LOC-7291 / epic LOC-7287 (LOC-7285 = binary PR)
🤖 Generated with Claude Code