mirror of
https://github.com/runbear-io/beardrive.git
synced 2026-08-25 08:08:08 +02:00
Some things cannot be tested from a Go test on your Mac. A real `claude`
session needs the real permission classifier and a $HOME it may write agent
hooks into. The systemd user unit only exists on Linux. A reboot needs
processes to die while the filesystem survives. Until now those were tested by
hand, against the real ~/.bdrive and ~/.claude — so testing onboarding from
scratch meant polluting the machine you were testing from, and `bdrive init`
registering hooks user-level made that worse.
This is an ENVIRONMENT, not a suite. It provides a hub on file:// storage, a
seeded account, browserless sign-in (bdrive-signin drives both halves of the
device flow), Claude Code, the binary under test, and a $HOME thrown away with
the container. Scenarios still live where they belong: deterministic ones in
internal/webapp/cli_e2e_test.go, the conversational one in the onboarding-e2e
skill. The rule, written into the Dockerfile so it survives me: if it doesn't
need a conversation or an OS, it's a Go test.
The two scripts it ships are the scenarios with nowhere else to go.
onboarding.sh runs a real `claude -p` following the LOCAL
INSTALL_FOR_AGENTS.md and checks the scope hard gate, hooks-via-init, and that
nothing reaches for a plugin or skill. daemon-linux.sh covers the systemd unit
and the daemon.pid/stop race.
Notes for whoever reads this next:
- The binary is bind-mounted, not built in, so a code change rebuilds the
binary and not the image. BDRIVE_SRC=<checkout> tests a branch without
touching your working tree; BDRIVE_BIN=<binary> skips the build.
- No `# syntax=` directive in the Dockerfile on purpose: it makes every
build resolve the frontend from the registry, which turns a slow network
into a build that hangs with no output. That also rules out RUN heredocs,
hence boot.sh being a file.
- Claude auth comes from CLAUDE_CODE_OAUTH_TOKEN (`claude setup-token`).
The Keychain is deliberately not read: the container would refresh that
token and rotate it out from under your Mac, logging you out there.
- The hub lives only as long as the container's command, so the project
link init prints is dead once a scripted run exits. Use the interactive
shell to browse it.
Claude-Session: https://claude.ai/code/session_01DgF8JsoeNPVShGYWdooE72
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
48 lines
2.0 KiB
Docker
48 lines
2.0 KiB
Docker
# A disposable Linux machine to run a scenario in when it needs one.
|
|
#
|
|
# This is an ENVIRONMENT, not a test suite. Scenarios live where they belong:
|
|
# deterministic ones in internal/webapp/cli_e2e_test.go and internal/syncer,
|
|
# the conversational one in the onboarding-e2e skill. Reach for the sandbox
|
|
# only when a scenario needs something a Go test cannot give it:
|
|
#
|
|
# - a fresh $HOME, so `bdrive init` writes its device identity and its agent
|
|
# hooks (~/.claude/settings.json) somewhere thrown away instead of yours
|
|
# - a real `claude` session, with the real permission classifier
|
|
# - Linux, for the systemd user unit
|
|
# - a reboot, simulated by killing processes while the filesystem survives
|
|
#
|
|
# It provides a hub, a seeded account, Claude Code, browserless sign-in
|
|
# (bdrive-signin / bdrive-approve) and the binary under test. The two scripts
|
|
# it ships are the scenarios that cannot live anywhere else.
|
|
#
|
|
# The bdrive binary is bind-mounted at run time rather than built in, so
|
|
# testing a code change rebuilds the binary, not the image. Use run.sh, which
|
|
# is the intended entry point.
|
|
#
|
|
# No `# syntax=` directive on purpose: it makes every build resolve the
|
|
# Dockerfile frontend from the registry, which turns a cold or slow network
|
|
# into a build that hangs with no output. That also rules out RUN heredocs,
|
|
# hence boot.sh being its own file.
|
|
FROM node:22-slim
|
|
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends ca-certificates curl git less \
|
|
&& rm -rf /var/lib/apt/lists/* \
|
|
&& npm install -g @anthropic-ai/claude-code \
|
|
&& npm cache clean --force
|
|
|
|
ENV HOME=/home/tester \
|
|
BDRIVE_HOME=/home/tester/.bdrive \
|
|
HUB=http://localhost:8080 \
|
|
HUB_EMAIL=me@example.com \
|
|
HUB_PASSWORD=hunter2hunter2
|
|
WORKDIR /work
|
|
|
|
COPY boot.sh /usr/local/bin/boot
|
|
COPY onboarding.sh /usr/local/bin/onboarding
|
|
COPY daemon-linux.sh /usr/local/bin/daemon-linux
|
|
RUN chmod +x /usr/local/bin/boot /usr/local/bin/onboarding /usr/local/bin/daemon-linux
|
|
|
|
ENTRYPOINT ["/usr/local/bin/boot"]
|
|
CMD ["bash"]
|