Imported from limrun-inc/skills (
skills/limrun-bazel/SKILL.md) via skills.sh. Install upstream withnpx skills add limrun-inc/skills --skill limrun-bazel. Copyright stays with the author.
Bazel on Limrun's build plane
lim bazel setup points a Bazel workspace at Limrun's build plane: Apple
actions run on Limrun's Macs, Android actions on Limrun's Linux workers, and
every build of the organization shares one remote cache. Bazel keeps running
where it already does; no local Xcode or Android SDK is needed for the
remote actions.
Auth and CLI
Install with npm: npm install --global lim (0.44.0 or later). The npm
package also installs lim-bazel-credentials, the credential helper Bazel
calls; the standalone tarball and DotSlash builds do not put it on PATH,
so Bazel cannot authenticate with them. Auth is lim login or LIM_API_KEY
(it may already be set even when the shell does not show it; check before
asking). The helper reads only lim login or LIM_API_KEY, never a key
passed with --api-key. The CLI is the source of truth: if a flag errors,
check lim bazel setup --help instead of guessing.
Set up
Run inside the workspace (it walks up to the directory with MODULE.bazel):
lim bazel setup
It needs Bazel 8 or later and rules_apple or rules_android in the root
MODULE.bazel. It writes a gitignored .limrun/ with the --config=limrun
configuration and adds a try-import to .bazelrc. Nothing secret is
written: Bazel asks the credential helper for a short-lived token.
- Region: setup picks the closest region that runs a build plane.
--region <name>pins one. - Android: Linux workers need
rules_cc,rules_java,protobufandhermetic_android_toolchainsin the rootMODULE.bazel. Setup prints the missing lines and asks;--yesadds them without asking. Without a terminal and without--yesit stops and prints the lines, so pass--yesin scripts and CI. - Java runtime: a
--java_runtime_versionalready in.bazelrcis kept; otherwise the limrun config usesremotejdk_17. - Re-run setup after upgrading the CLI or when the workspace starts using
Apple or Android rules. Do not hand-edit
.limrun/.
Build
bazel build --config=limrun //your:target
Build actions run remotely and Bazel downloads only the top-level outputs
(the .apk or .ipa). Without --config=limrun, Bazel builds as before.
Own flags for the limrun path go in user.limrun.bazelrc at the workspace
root; the generated config imports it last and it survives re-running setup.
In CI: install lim from npm, set LIM_API_KEY as a secret, run
lim bazel setup --yes, then build with --config=limrun.
Run the app
Build for the simulator or emulator, then install the .ipa or .apk path
Bazel prints:
lim ios create && lim ios sync bazel-bin/App/App.ipa
lim android create && lim android install-app bazel-bin/app/app.apk
Re-run lim ios sync after each rebuild; it sends only the difference. To
drive the running app, use limrun-ios-simulator or limrun-android-emulator.
Check results
The console's Bazel page (https://console.limrun.com/bazel) lists the
organization's builds from every region, with live output for running builds
and the remote cache hit rate per build.
When a build fails
- Bazel cannot authenticate or reports a credential helper error: check
that
lim-bazel-credentialsis onPATH(npm install) and thatlim loginorLIM_API_KEYis set where Bazel runs. - "the build plane could not start a worker" or "no linux worker is free": transient capacity; retry the build.
- Missing
@androidsdkor Android toolchain errors: theMODULE.bazellines are missing. Re-runlim bazel setupand accept them. - Each region keeps its own cache: the first build in a new region starts cold.
