# Reusable workflow: verify the macos-x86_64 prebuilt installs +
# loads on a Rosetta'd x86_64 Rakudo. The macos-14 runner is arm64;
# we install Rosetta + source-build x86_64 Rakudo under it (no
# Raku/setup-raku@v1 prebuilt for x86_64 macOS).
#
# Wrapping every Raku/zef invocation in `arch -x86_64` guarantees
# we're testing the x86_64 prebuilt as a real Intel-Mac user would —
# the Rakudo process is x86_64, NativeCall loads x86_64 dylibs, etc.
name: _verify-macos-x86_64
on:
workflow_call:
env:
TERM: xterm
COLORTERM: truecolor
LANG: en_US.UTF-8
LC_ALL: en_US.UTF-8
NOTCURSES_NATIVE_REQUIRE_SHIM: '1'
RAKUDO_VERSION: '2026.03'
jobs:
verify:
runs-on: macos-14
steps:
- uses: actions/checkout@v6
with: { submodules: recursive }
- name: Install Rosetta
run: softwareupdate --install-rosetta --agree-to-license || true
- name: Install x86_64 Homebrew + Rakudo build deps
run: |
set -euxo pipefail
if [[ ! -x /usr/local/bin/brew ]]; then
arch -x86_64 /bin/bash -c \
"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" \
< /dev/null
fi
# Rakudo's Configure.pl + the build itself need perl, git,
# make. macOS already has perl/git via Xcode CLT but those
# are arm64-native; arch -x86_64 on a fat (universal)
# binary uses the x86_64 slice automatically. For safety
# install x86_64 brew versions too.
arch -x86_64 /usr/local/bin/brew install --overwrite python@3.14
arch -x86_64 /usr/local/bin/brew install perl git
echo "/usr/local/bin" >> "$GITHUB_PATH"
- name: Restore source-built Rakudo
# restore + save split (not actions/cache@v4) so a downstream
# test failure doesn't invalidate the ~10-20 min Rakudo build.
# Key has `-rakudo-only-v2` suffix to invalidate caches that
# carried stale zef state in site/ — see the linux-aarch64
# lane for the full root-cause writeup.
id: rakudo-cache
uses: actions/cache/restore@v4
with:
path: ~/.rakubrew
key: rakudo-macos-x86_64-${{ env.RAKUDO_VERSION }}-rakudo-only-v2
- name: Build x86_64 Rakudo under Rosetta (rakubrew)
run: |
# arch -x86_64 wraps the whole rakubrew/Configure.pl/make
# process so NQP+MoarVM+Rakudo all build as x86_64. Even
# if cache restored, the script's idempotent short-circuit
# checks (already-built) skip the expensive part.
arch -x86_64 bash scripts/ci/build-rakudo.sh
- name: Strip zef module state — we cache Rakudo only, not installs
run: rm -rf ~/.rakubrew/versions/moar-*/install/share/perl6/site || true
- name: Save Rakudo cache (build succeeded — independent of tests)
if: steps.rakudo-cache.outputs.cache-hit != 'true'
uses: actions/cache/save@v4
with:
path: ~/.rakubrew
key: rakudo-macos-x86_64-${{ env.RAKUDO_VERSION }}-rakudo-only-v2
- name: Install zef under Rosetta (~30s; not cached — see script header)
run: arch -x86_64 bash scripts/ci/install-zef.sh
- name: Add Rakudo shims + site-bin to PATH
# shims/ for raku/zef (rakubrew-managed). site-bin for
# zef-installed module bins like prove6 (rakubrew doesn't
# auto-rehash after `zef install` so those aren't shimmed).
run: |
echo "$HOME/.rakubrew/shims" >> "$GITHUB_PATH"
echo "$HOME/.rakubrew/versions/moar-${{ env.RAKUDO_VERSION }}/install/share/perl6/site/bin" >> "$GITHUB_PATH"
- name: Verify Rakudo runs as x86_64 under Rosetta
# `which raku` resolves to rakubrew's shim — a Perl-script
# dispatch wrapper, not the binary. `file` on the shim
# reports "Perl script text", which never contains "x86_64".
# Ask raku itself instead: `$*KERNEL.hardware` is sourced
# from uname(2), and Rosetta lies to the x86_64 process to
# report "x86_64" (whereas an arm64 raku here would report
# "arm64"). The `arch -x86_64` wrap is paranoid but matches
# how every subsequent step runs raku/zef/prove6.
run: |
set -e
detected=$(arch -x86_64 raku -e 'print $*KERNEL.hardware')
echo "Rakudo reports hardware: $detected"
[ "$detected" = "x86_64" ] || {
echo "❌ Expected x86_64 (Rosetta), got '$detected' — Rakudo build wasn't wrapped in arch -x86_64?"
exit 1
}
- name: zef install (prebuilt path)
run: arch -x86_64 zef install --/test .
- name: zef install App::Prove6
run: arch -x86_64 zef install --/test App::Prove6
- name: prove6 (prebuilt path)
run: arch -x86_64 prove6 --verbose -I lib -I t/lib t
- name: prove (xt — terminal-dependent, prebuilt path)
# Perl's `prove` (the orchestrator) doesn't need to be
# x86_64 — it just forks the -e command per test file. The
# `raku` invocation IS x86_64 via `arch -x86_64`, which is
# what loads the bundled prebuilt under test.
run: prove -e 'arch -x86_64 raku -I lib -I t/lib' --verbose xt/*.rakutest
- name: Install x86_64 brew deps for source-build pass
run: |
arch -x86_64 /usr/local/bin/brew install \
cmake pkg-config ffmpeg ncurses libunistring libdeflate
- name: zef install (source-build path)
env: { NOTCURSES_NATIVE_BUILD_FROM_SOURCE: '1' }
run: arch -x86_64 zef install --/test --force-install .
- name: prove6 (source-build path)
run: arch -x86_64 prove6 --verbose -I lib -I t/lib t