[Feature] Reusable CI harness / GitHub Action to boot a Beetroot instance and drive it (adb + Frida + LSPosed) on GitHub runners
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 38/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Quiet
- Tech stack
- android, docker, docker-compose, github-actions, linux, python
- Domain
- ci-cd, devops, infrastructure, mobile-dev
Research direction
Start with docs/design/stealth-posture.md §7 and issue #6, then inspect the existing Beetroot create, up, doctor, and destroy entry points. Verify the redroid boot requirements on the intended GitHub or self-hosted runner before designing the reusable action. Done means an external workflow can boot an x86_64 instance, use adb and Frida, collect logs, and always tear it down, with the runner findings documented and linked from #6.
Written by the indexing model from the issue text.
Description
Summary
Make Beetroot consumable as a reusable CI harness — ideally a published composite/Docker GitHub Action (and/or a documented workflow job) — that boots a Beetroot instance on a GitHub-hosted runner, waits for it to be ready, exposes adb + Frida to subsequent steps, and tears it down. The goal is that a downstream repo can stand up an on-device e2e against a real rooted Android-14 phone without hand-rolling emulator plumbing.
Why (the concrete driver)
The Rosetta project wants exactly this. In Xiddoc/rosetta-xposed#25 (load the real DexKit native .so in the emulator e2e), the owner commented:
stand this dynamic-path e2e up on Beetroot, our own GitHub-Actions emulator framework, rather than hand-rolling more
android-e2e.ymlemulator plumbing. Beetroot owns the "boot an emulator on a GH runner and drive it" layer; this issue's actual work … then runs inside a Beetroot-provisioned emulator job.
Today rosetta-xposed's .github/workflows/android-e2e.yml hand-rolls reactivecircus/android-emulator-runner + LSPatch. That workflow's own comment explains why it avoids the path Beetroot is built for:
Why LSPatch and not LSPosed: running LSPosed in CI needs Magisk root + a Zygisk module on the AVD (no turnkey action, very flaky).
Beetroot is the turnkey "Magisk root + Zygisk" box. A reusable Beetroot CI harness is the missing piece that lets rosetta retire the bespoke plumbing and run against real root.
Known blocker (be honest up front)
Beetroot boots redroid, and redroid-on-GitHub-hosted-runners is not yet solved. This is already flagged in-repo:
docs/design/stealth-posture.md§7 PR7: "Complexity: L (mostly: getting redroid to boot in GHA is the hard part)."- #6 (Stealth PR7: CI fingerprint audit) hits the same wall: "The hard part is getting redroid to boot inside a GitHub Actions runner … the real redroid base can't be pulled/booted on GHA runners."
- #21 lists "booting real redroid in CI" as out of scope, "blocked on a KVM-capable runner story."
So this issue is partly the boot story itself (redroid needs binder/ashmem kernel modules; GitHub's ubuntu-latest enables nested KVM but the redroid kernel-module prerequisites are the real question), and partly the ergonomics on top once boot works. It shares the redroid-boot blocker with #6 — solving it here unblocks both. A self-hosted/KVM-capable runner is the likely fallback if GitHub-hosted can't carry it.
Proposed shape
- A composite action (e.g.
Xiddoc/beetroot/.github/actions/boot@v0) or a documented reusable workflow that:- builds/pulls the base image,
beetroot create+beetroot upa throwaway instance, andbeetroot doctor-waits for boot-complete; - surfaces the instance's
adbserial and Frida port to later steps; - streams
docker compose logsas a job artifact andbeetroot destroys on teardown (always()).
- builds/pulls the base image,
- Pin to an x86_64 image so a committed
lib/x86_64/*.somatches the runtime ABI (a hard requirement for the rosetta-xposed DexKit case). - Document the runner requirements (KVM / kernel modules / self-hosted fallback) discovered while solving the boot story.
Acceptance
- A documented, copy-pasteable way for an external repo's workflow to boot a Beetroot instance, run
adb/Frida steps against it, and tear down — green on whatever runner class we land on. - The redroid-boot-in-GHA findings folded back into
docs/and cross-linked from #6.
Downstream consumers (cross-repo)
- Xiddoc/rosetta-xposed#25 — real DexKit native load via a true LSPosed install (see the companion Beetroot issue for the LSPosed recipe).
- Xiddoc/rosetta-frida (#23) — Frida self-healing / on-device parity; Beetroot already ships Frida per-instance, so this is the natural home for a Frida-side on-device e2e (rosetta-frida currently has no device harness at all).
- Xiddoc/rosetta-maps (#41, #34, trust-ladder) — a "trusted runner" / device-telemetry tier that proves a generated map actually resolves against the real app on-device (the off-public-CI correctness tier their
AGENTS.mdHard rule 3 reserves).
- Dominant language
- Python
- Stars
- 1
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from Xiddoc/Beetroot
-
ci
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
backend design
Difficulty 5/5 Over a week Newbie friendliness 38/100
-
backend design
Difficulty 4/5 3-5 days Newbie friendliness 48/100
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 25/100
-
ci enhancement
Difficulty 5/5 Over a week Newbie friendliness 35/100
Similar issues
-
area/auth bug comp/agent P3 platform/discord type/security
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
NousResearch/hermes-agent#117848 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
bancolombia/sentinel#23 ·
-
test md OpenCI
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
-
integration:quickjs org:external priority:backlog topic:code-interpreter topic:middleware type:feature
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
langchain-ai/deepagents#6450 ·
-
bug client
Difficulty 2/5 1-3 hours Newbie friendliness 88/100