chore(dev): reproducible dev container with Android + Flatpak toolchains (#237) #241
No reviewers
Labels
No labels
area:auth
area:ci
area:db
area:infra
area:native
area:pwa
area:service
epic
feature
foundation
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
james/carol!241
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "237-devcontainer"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
.devcontainer/) that gets a fresh contributor to workingpnpm -F @carol/api dev,pnpm -F @carol/client export:web,pnpm -F @carol/client build:android, andpnpm -F @carol/client build:flatpakin onedocker pull..forgejo/workflows/release-devcontainer.yml) that builds, signs (cosign), and publishes the image, then opens a bot PR to update the digest pin.CONTRIBUTING.mdand the "Dev container publish flow" paragraph indocs/ci.md.What changed
.devcontainer/Dockerfile— Ubuntu 24.04 base (manifest-list digest pinned), preinstalls every toolchain Carol ships:.tool-versionsat first attach for Node, pnpm, gitleaks, actionlint).platforms;android-35,build-tools;35.0.0(matchesrelease-android.yml).release-flatpak.yml); rust-toolchain.toml doesn't exist yet so this is the floor.libwebkit2gtk-4.1-dev,libsoup-3.0-dev,libjavascriptcoregtk-4.1-dev,librsvg2-dev,libayatana-appindicator3-dev,libgtk-3-dev,libxdo-dev,libssl-dev,build-essential,pkg-config.flatpak+flatpak-builder+ GNOME Platform 48 + Sdk 48 (installed--usersince--systemfails in an unprivileged container).gh,jq,ripgrep,fd.vscodeuser with passwordless sudo (Dev Containers convention)..devcontainer/devcontainer.json— workspace mount at/workspaces/carol, forwarded ports 3000 / 8081 / 19000-19002,postCreateCommand: mise install && pnpm install --frozen-lockfile && pnpm -F @carol/client export:web, VS Code extension recommendations (ESLint, Prettier, Vitest, Expo Tools, rust-analyzer, Tauri, sqlite-viewer, markdown, yaml). Ships with theimageline commented + a localbuildblock so the spec is usable from this branch before the first registry publish..devcontainer/README.md— what's inside, expected size (8-10 GB uncompressed), how to use it (VS Code /devcontainerCLI /docker run), the publish flow, and out-of-scope items (no Android emulator inside the container, no GitHub Codespaces specifics, etc.)..forgejo/workflows/release-devcontainer.yml— triggers on.devcontainer/**changes, monthly cron (0 0 1 * *), andworkflow_dispatch. Builds withdocker buildxforlinux/amd64, pushes toforge.wynning.tech/james/carol-devcontainer:YYYY-MM-DD+:latest, signs the digest via cosign keypair (same onerelease.ymluses), then opens a bot PR to update the digest pin via the helper script.scripts/ci/pin-devcontainer.mjs— idempotent in-place pin updater. Handles both the first-publish case (uncomment the sentinel + drop the localbuildblock) and subsequent re-pins. Locally runnable.CONTRIBUTING.md— new "Dev container (recommended)" section at the top of Prerequisites. Existing host-install path stays as the explicit fallback.docs/ci.md— new "Dev container publish flow" section under Release pipeline.Base image choice + rationale
Ubuntu 24.04 LTS over Fedora 42. The deciding factor was the install-surface parity with
release-android.yml(apt-get + sdkmanager) andrelease-flatpak.yml(Tauri's system deps namedlibwebkit2gtk-4.1-dev/libsoup-3.0-dev/ etc. — Fedora'swebkit2gtk4.1-devel/libsoup3-develwould force a parallel install list to maintain). Mirroring the release workflows' install surface keeps "what the dev container ships" and "what CI installs" identical, so a future Android SDK / Flatpak runtime bump is one PR, not two. The Ubuntu 24.04 multi-arch manifest digest is pinned by digest in the sameARGstyle the productionDockerfileuses fornode:24-slim.Expected image size
~8-10 GB uncompressed. Breakdown:
Documented in
.devcontainer/README.mdso contributors know what they're pulling.Test plan
pnpm install --frozen-lockfilepnpm -F @carol/api typecheck/lint/test(556 passed, 107 skipped — Postgres leg)pnpm -F @carol/client typecheck/lint/test(29 passed) /export:webpnpm -F @carol/api-client typecheck/lintactionlint .forgejo/workflows/*.yml— cleanjqparse of.devcontainer/devcontainer.json(with JSONC comments stripped) — validdocker buildx build --check .devcontainer—Check complete, no warnings found.node scripts/ci/pin-devcontainer.mjssmoke-tested for first-publish swap (template → real digest + build-block removal), subsequent re-pin, and idempotency (same digest → exit 0 with no diff).gitleaks detecton the diff — clean.lefthookpre-commit + commit-msg hooks — all pass..forgejo/workflows/release-devcontainer.yml— needs the workflow to run at least once to populate the digest pin. Until then, contributors get thebuild:block path (Dockerfile + context) instead of the pinned image.docker pullfrom the published registry →devcontainer up→pnpm -F @carol/client build:androidsmoke. Waits on first publish.Out of scope
.devcontainer/README.mdanddocs/ci.md.Notes / surprises
flatpak install --systemfails inside an unprivileged container because of bind-mount restrictions on/var/lib/flatpak; switched to--user. Same install lives at$HOME/.local/share/flatpak, works forflatpak-builderinvocations from thevscodeuser. Release workflows use--system(the runner is privileged), so the dev container and CI diverge on this one flag.yes 2>/dev/null | sdkmanager --licenses || truedancerelease-android.ymldoes. Works deterministically as long as Google doesn't reshape the EULA surface.ghis preinstalled and Carol's docs use it as the generic API client.//comments embedded throughout are spec-conformant. Validated by stripping comments and piping tojq empty.imageline indevcontainer.jsonis commented out with a<TBD-FILLED-BY-FIRST-PUBLISH>sentinel; the publish workflow rewrites it viascripts/ci/pin-devcontainer.mjson the first successful run.Closes #237. See ADR-0014 for the release-pipeline shape this mirrors.
📊 Test coverage
Patch coverage: no testable lines changed.
Overall (
app/,lib/,db/, excluding UI per ADR-0019):Soft thresholds per ADR-0019. Coverage is informational and does not block merge.
Trivy (container image)
Threshold:
high· Total findings: 121 · At/above threshold: 16.27.0, 7.28.0, 8.5.0View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.Merge
Merge the changes and update on Forgejo.Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.