Skip to content

Borrow three patterns from omaterm: release-asset install URL, mise SDKs, named home volume#80

Open
BrettKinny wants to merge 4 commits into
mainfrom
bootstrap-mise-volume
Open

Borrow three patterns from omaterm: release-asset install URL, mise SDKs, named home volume#80
BrettKinny wants to merge 4 commits into
mainfrom
bootstrap-mise-volume

Conversation

@BrettKinny
Copy link
Copy Markdown
Collaborator

Summary

Three independent improvements inspired by reading omaterm, each on its own commit so they can be reverted independently:

  1. Release-asset install URLinstall.sh and install.ps1 ship as GitHub Release assets. The README quick-install URL points at releases/latest/download/install.sh, so pushes to main no longer affect new installs until a release is cut. (No bootstrap.sh shim — install.sh already self-bootstraps when curl-piped.)

  2. mise as the single SDK manager — drops nvm, astral.sh/uv, go.dev tarball, dotnet-install.sh, and rustup. ~/.config/mise/config.toml is now the source of truth; mise activate {bash,zsh,fish} wires shims onto PATH in all three shells. mise itself joins the Dockerfile-pinned tier (checksums.txt, ARG, sqrbx-update aware).

  3. Named volume for /home/dev — adds squarebox-home as a named Docker volume. Shell history, gh auth, claude-code state, and mise toolchains survive container recreates without the /workspace/.squarebox/gh kludge. Image-managed config (.bashrc extracted to dotfiles/bashrc) bind-mounts over the volume so repo updates flow through — same pattern starship.toml already used.

Commits

942af86 docs/uninstall/test: align with mise + named-volume changes
ccfa222 sdk: replace nvm/uv/Go/.NET/rustup with mise
451ab54 home: back /home/dev with a named volume + bind-mounted bashrc
d7e7f50 ci: publish install.sh/install.ps1 as release assets

Behaviour changes worth knowing

  • First-run users are unaffected; the wizard UX is unchanged.
  • Existing users rebuilding will see a one-time gh re-auth (legacy /workspace/.squarebox/gh is migrated automatically on first run if no ~/.config/gh exists). Their old ~/.nvm, ~/.cargo, ~/.local/go directories live on harmlessly in the named volume but are no longer on PATH; re-running sqrbx-setup sdks re-installs cleanly via mise.
  • Disk: mise binary adds ~30 MB to the image. Per-SDK install size is similar to before. gpg and libatomic1 are now installed at the apt layer (mise needs gpg to verify Node release signatures; Node's official Linux binary needs libatomic1).
  • Trust model: SDK security now anchored to mise's pinning rather than each language's installer. Updated SECURITY.md trust table reflects this.

Test plan

  • docker build clean
  • e2e suites in CI invocation shape: shell 18/18, tools 11/11, setup 3/3, update 4/4
  • bash -n clean across changed shell scripts
  • End-to-end persistence: setup with sdks=node,gomise ls --current shows both → recreate container → marker file, history, mise config, node toolchain all persist
  • Bashrc bind mount: aliases (ls/cat/g), starship, MOTD load on first attach
  • AI-tool auto-install path (ensure_node_for_npm): Claude Code installs cleanly; Node provided on demand by mise
  • Push tag v0.x.y-rc1 to verify release.yml uploads install.sh + install.ps1 as assets and the README URL resolves
  • CI shell/tools/setup/update suites green
  • arm64 build green
  • Manual sqrbx-uninstall --purge removes the named volume; default sqrbx-uninstall keeps it

Notes for the merger

  • Cut a tag promptly after merge. The README's quick-install URL points at releases/latest/download/install.sh. Until the first tag exists on this branch's code, the URL 404s. An -rc tag is enough — the release workflow uploads the assets either way.
  • The unrelated demo/squarebox-setup-linkedin.gif was sitting untracked from before this branch and is not included in this PR (left as untracked locally).
  • Out of scope (deferred): squarebox.dev DNS for a prettier install URL; separating dotfiles into their own repo (omaterm's omadots pattern).

🤖 Generated with Claude Code

BrettKinny and others added 4 commits May 9, 2026 21:45
Adds .github/workflows/release.yml so tagged releases (v*) attach
install.sh and install.ps1 to the GitHub Release. install.sh already
self-bootstraps when curl-piped (clones the repo, then runs from
there), so no separate bootstrap shim is needed.

Switch the README quick-install URLs from
raw.githubusercontent.com/.../main/install.sh (always serves HEAD)
to releases/latest/download/install.sh. Pushes to main no longer
break new installs until a release is cut.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Switch /home/dev from in-image-only to the squarebox-home named Docker
volume. Shell history, GitHub CLI auth, claude-code data, and (in a
follow-up) mise toolchains now survive container recreates without the
/workspace/.squarebox kludge.

Image-managed config that previously lived inside the container -
.bashrc - is moved to dotfiles/bashrc in the repo and bind-mounted
read-only into /home/dev/.bashrc. The bind mount overrides the named
volume's copy at that sub-path (same pattern starship.toml and lazygit
already use), so repo updates propagate without touching user state.

gh auth: stop copying to /workspace/.squarebox/gh on every change. The
default ~/.config/gh location is now persistent via the named volume.
The legacy path is migrated once on first run for upgraders, then
ignored. The skip marker moves to ~/.squarebox-gh-skip.

Verified: docker build clean; container with squarebox-home volume +
bashrc bind mount loads aliases (ls/cat/g), starship, MOTD, and writes
to $HOME successfully.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drops five separate per-language installers (nvm, astral.sh/uv,
go.dev tarball, dotnet-install.sh, rustup) and the
~/.squarebox-sdk-paths shell-init kludge. mise now manages all SDKs
through ~/.config/mise/config.toml; `mise activate {bash,zsh,fish}`
in the relevant rc file wires shims onto PATH.

mise itself joins the Dockerfile-pinned tier (tools.yaml dockerfile
group, ARG MISE_VERSION, checksums.txt entry, sqrbx-update aware).
update-versions.sh now bumps MISE_VERSION alongside the others.

setup.sh: install_node/python/go/dotnet/rust collapse to thin wrappers
around _install_mise_sdk. ensure_node_for_npm uses mise too. Selection
flow (gum + /workspace/.squarebox/sdks) is unchanged so re-runs and
the AI-tools auto-Node path keep working.

Apt deps: gpg (for mise's signature verification of Node releases) and
libatomic1 (required by official Node Linux binaries) are now installed
unconditionally; the post-install gnupg purge is dropped since mise
needs it at runtime.

Verified end-to-end: setup.sh non-interactive run with sdks=node,go
installs both via mise; `mise ls --current` shows them; `node` and
`go` are on PATH after `mise activate bash --shims`. Build CI's tools
list and e2e-test's SDK assertions updated accordingly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
After auditing the rest of the repo for stale references:

- e2e-test.sh: replace the ~/.squarebox-sdk-paths assertion (4.6d)
  with a check for `mise activate bash` in ~/.bashrc.
- CONTRIBUTING.md: drop nvm/Go from the optional-tools list and note
  that SDKs now ride on mise (Dockerfile-tier pinned).
- CLAUDE.md: SDK row in the first-run setup list now says "via mise";
  removed nvm/Go from the optional-tools paragraph.
- SECURITY.md: install URL points at the release asset; trust-model
  table swaps the per-SDK installer rows for a single mise row and
  bumps the binary-tools count to 9.
- uninstall.sh / uninstall.ps1: detect the squarebox-home named
  volume and remove it on --purge / -Purge (kept by default, parallel
  to ~/squarebox/workspace). Summary lines and "kept" hints updated.
- README "Uninstall" section: mention the named volume in --purge.

Verified: e2e suites shell (18/18), tools (11/11), setup (3/3),
update (4/4) all pass against squarebox:test.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 9, 2026 12:12
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates squarebox’s installation and persistence model by (1) pinning quick-install entrypoints to GitHub Release assets, (2) consolidating language SDK management under mise, and (3) persisting /home/dev via a named Docker volume so user state survives container recreation.

Changes:

  • Switch README/SECURITY install URLs to releases/latest/download/install.{sh,ps1} and add a tag-triggered release workflow that publishes the install scripts as assets.
  • Replace per-language SDK installers (nvm/uv/go tarball/dotnet-install/rustup) with mise, and wire mise activate into bash/zsh/fish plus updater/version tooling.
  • Back /home/dev with a named volume (squarebox-home) and update install/uninstall + docs/tests accordingly.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
uninstall.sh Adds awareness/removal of the squarebox-home named volume on --purge.
uninstall.ps1 Windows equivalent named-volume detection/removal on -Purge.
setup.sh Migrates gh persistence logic + replaces SDK installation with mise.
SECURITY.md Updates install URL and trust-model documentation for release assets + mise.
scripts/update-versions.sh Extends Dockerfile-tier version bump automation to include mise.
scripts/squarebox-update.sh Adds mise to the in-container updater tool registry.
scripts/lib/tools.yaml Registers mise as a Dockerfile-tier pinned binary tool.
scripts/e2e-test.sh Updates E2E expectations for mise activation and SDK installation checks.
README.md Documents release-asset install URLs, mise-based SDKs, and named home volume persistence.
install.sh Mounts squarebox-home at /home/dev and bind-mounts repo-managed bashrc/config files.
install.ps1 Windows equivalent /home/dev named-volume + bashrc bind-mount.
dotfiles/bashrc New repo-managed bashrc that activates mise and triggers first-run setup.
Dockerfile Adds runtime deps for mise-managed SDKs, installs pinned mise, and copies new bashrc.
CONTRIBUTING.md Updates contributor guidance to reflect mise/SKD changes (some tool lists need refresh).
CLAUDE.md Updates project overview/docs for named volume + mise (some tool lists need refresh).
checksums.txt Adds vetted checksums for mise release artifacts (amd64/arm64).
.github/workflows/release.yml New workflow creating releases and uploading install scripts as assets on tags.
.github/workflows/build.yml Ensures mise exists in the base image during CI verification.
Comments suppressed due to low confidence (1)

install.ps1:191

  • Same /home/dev named-volume concern as install.sh: because sqrbx-setup runs ~/setup.sh, persisting /home/dev in a named volume can freeze setup.sh/motd.sh at whatever version first populated the volume. Bind-mount the repo’s setup.sh (and motd.sh) into /home/dev or relocate them outside the volume so upgrades take effect.
# --- Create container ---
Write-Host "Creating container..."

# Volume strategy: a single named volume backs /home/dev so shell history,
# claude-code state, mise toolchains, and gh auth survive container recreates.
# Bind mounts at sub-paths inside /home/dev override the volume - that's how
# we keep image-managed config (bashrc, starship.toml, lazygit) in lockstep
# with the repo while user state stays in the volume.
$homeVolume = if ($env:SQUAREBOX_HOME_VOLUME) { $env:SQUAREBOX_HOME_VOLUME } else { 'squarebox-home' }
$bashrcPath = Join-Path $InstallDir 'dotfiles\bashrc'

$rtVolumes = @(
    '-v', "$workspaceDir`:/workspace"
    '-v', "$homeVolume`:/home/dev"
    '-v', "${bashrcPath}:/home/dev/.bashrc:ro"
    '-v', "$gitCfgDir`:/home/dev/.config/git"
    '-v', "${starshipDest}:/home/dev/.config/starship.toml"
    '-v', "${lazygitDir}:/home/dev/.config/lazygit"
)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

zellij_current() { zellij --version 2>/dev/null | head -1 | awk '{print $2}' || echo "not installed"; }
just_current() { just --version 2>/dev/null | awk '{print $2}' || echo "not installed"; }
difftastic_current() { difft --version 2>/dev/null | head -1 | awk '{print $2}' || echo "not installed"; }
mise_current() { mise --version 2>/dev/null | awk '{print $1}' || echo "not installed"; }
Comment thread SECURITY.md
Comment on lines +47 to +48
| **install.sh** | Git repo from GitHub | HTTPS | Git transport verification | Tracks the latest tag (or `--edge` for `main`) |
| **bootstrap script** | `install.sh` itself, served as a release asset | HTTPS | Pinned to a tagged release; pushes to `main` don't affect new installs | Yes (tagged release) |
Comment thread install.sh
Comment on lines 398 to 412
echo "Creating container..."
RT_OPTS=()
# Volume strategy: a single named volume backs /home/dev so shell history,
# claude-code state, mise toolchains, and gh auth survive container recreates.
# Bind mounts at sub-paths inside /home/dev override the volume — that's how
# we keep image-managed config (bashrc, starship.toml, lazygit) in lockstep
# with the repo while user state stays in the volume.
HOME_VOLUME="${SQUAREBOX_HOME_VOLUME:-squarebox-home}"
RT_VOLUMES=(
-v "${INSTALL_DIR}/workspace:/workspace"
-v "${HOME_VOLUME}:/home/dev"
-v "${INSTALL_DIR}/dotfiles/bashrc:/home/dev/.bashrc:ro"
-v "${USER_HOME}/.config/git:/home/dev/.config/git"
-v "${INSTALL_DIR}/.config/starship.toml:/home/dev/.config/starship.toml"
-v "${INSTALL_DIR}/.config/lazygit:/home/dev/.config/lazygit"
Comment thread setup.sh
Comment on lines +176 to +183
# GitHub CLI config lives at ~/.config/gh (the gh default) and is preserved
# by the squarebox-home named volume. The legacy persistence path
# (/workspace/.squarebox/gh) is migrated once for users upgrading from a
# pre-named-volume install; new installs never touch it.
GH_PERSIST_LEGACY="/workspace/.squarebox/gh"
GH_SKIP_MARKER="$HOME/.squarebox-gh-skip"
GH_SKIP_MARKER_LEGACY="/workspace/.squarebox/gh-skip"
if [ -d "$GH_PERSIST_LEGACY" ] && [ ! -d ~/.config/gh ]; then
Comment thread CLAUDE.md
@@ -79,7 +83,7 @@ sqrbx-update

`scripts/update-versions.sh` only touches the Dockerfile tier (delta, yq, xh, glow, gum, starship, just, difftastic). It fetches latest GitHub releases, downloads artifacts for both architectures, computes SHA256 checksums, and updates `checksums.txt` and the Dockerfile ARGs.
Comment thread CONTRIBUTING.md
Comment on lines +78 to +85
Optional tools (editors, TUIs, opencode, zellij) track upstream latest at
install time. To add a new optional tool, add an entry to
`scripts/lib/tools.yaml` and call `sb_install <tool> latest` from `setup.sh`.
No checksum file update is required.

SDKs (Node, Python, Go, .NET, Rust) are installed by mise itself, which is
part of the Dockerfile-pinned tier — so SDK availability is gated by mise's
own pinning, not the SDK installers individually.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants