Base is currently Mac-first. Linux support should be added deliberately, with Ubuntu/Debian as the first target because it covers GitHub Actions and a large share of developer machines.
Start with Ubuntu/Debian runtime support:
- Base Python CLIs run under Linux.
base-wrappercan select the project venv under~/.base.d/<project>/.venv.basectl projects list,check,doctor, andciwork when prerequisites are already installed.- Setup installs conservative Ubuntu/Debian apt prerequisites only after the
user reviews
--dry-runoutput and passes--yes.
Use /etc/os-release for Linux distribution detection and expose the result
through BASE_PLATFORM. Keep BASE_OS coarse: BASE_OS=linux on Linux, with
BASE_PLATFORM carrying the supported distribution family.
if [[ -r /etc/os-release ]]; then
source /etc/os-release
fiThe setup layer should classify platforms into:
macoslinux-debianlinux-unknownunsupported
Unsupported platforms should fail with explicit guidance rather than falling through to macOS assumptions.
Do not add public BASE_DISTRO_ID or BASE_ARCH until diagnostics or package
selection need them. Distribution ID and CPU architecture are separate axes:
BASE_PLATFORM answers "which supported platform family is this?", while a
future BASE_ARCH would answer "which binary/package architecture is this?".
BASE_PLATFORM is an input to centralized platform policy, not a general
branch condition for feature code. base_init.sh owns detection and exports
BASE_OS / BASE_PLATFORM; it must not decide installer, package-manager, or
diagnostic behavior.
Setup and check behavior should inspect BASE_PLATFORM only through explicit
platform boundary helpers. The intended shell setup/check shape is:
setup_current_platformresolves the supported platform name from the runtime contract.setup_platform_supportedreports whether the current platform has a supported setup/check path.setup_collect_platform_base_check_resultsdispatches Base environment checks to platform-specific collectors.setup_run_platform_installdispatches setup/install behavior to platform-specific installers.
Leaf helpers should stay platform-specific rather than internally branching on
every platform. Prefer names such as setup_collect_macos_base_check_results,
setup_collect_linux_debian_base_check_results, setup_run_macos_install, and
setup_run_linux_debian_install.
Package-manager selection belongs behind this boundary. macOS setup uses
Homebrew-specific helpers, and Ubuntu/Debian setup uses apt-specific helpers,
but ordinary command, diagnostic, and artifact code should call the platform
boundary instead of checking BASE_PLATFORM directly.
Python project artifact management has a separate future seam. If system packages become project artifacts on Linux, the Python artifact registry should learn platform-aware providers instead of inheriting the shell setup/check dispatch directly.
Initial Ubuntu/Debian mappings:
| Base prerequisite | macOS source | Ubuntu/Debian source |
|---|---|---|
| Bash 4.2+ | Homebrew bash |
apt install bash |
| Python 3 | Homebrew python@3.13 |
apt install python3 |
| Python venv support | Homebrew python@3.13 |
apt install python3-venv |
| Git | Xcode Command Line Tools or Homebrew git |
apt install git |
| BATS | Homebrew bats-core |
apt install bats when available |
| GitHub CLI | Homebrew gh |
official GitHub CLI Debian/Ubuntu apt repository |
| ShellCheck | Homebrew shellcheck |
apt install shellcheck |
| jq | Homebrew jq |
apt install jq |
| Go for source-checkout tests | Homebrew go |
apt install golang-go |
Python remains conservative by platform. macOS setup uses Base-managed
Homebrew Python. Ubuntu/Debian setup uses the platform python3 package after
the apt-backed setup path has installed python3 and python3-venv.
Ubuntu/Debian bootstrap is intentionally conservative. The first-mile
bootstrap.sh entry point detects Ubuntu/Debian Linux and prints the manual
source-checkout path instead of running sudo apt from a piped script:
curl -fsSL https://raw.githubusercontent.com/basefoundry/base/HEAD/bootstrap.sh | bash -s -- --source --dry-runThe printed path includes apt prerequisites, cloning Base and
base-bash-libs, basectl setup --dry-run, basectl setup --yes, and
basectl update-profile.
Ubuntu/Debian setup can install the simple apt prerequisites that Base knows
how to own. The mutation path is intentionally explicit: basectl setup --dry-run prints the apt commands, and basectl setup --yes applies them.
Without --yes, Linux setup fails before invoking apt.
Use native Linux filesystem paths for source checkouts. In Parallels, keep Base
under ~/work, not under mounted macOS shared folders, so file permissions,
line endings, symlinks, and test paths behave like a normal Linux checkout.
mkdir -p ~/work
cd ~/work
git clone https://github.com/basefoundry/base.git
git clone https://github.com/basefoundry/base-bash-libs.git
cd base
./bin/basectl setup --dry-run
./bin/basectl setup --yes
./bin/basectl setup --profile dev --dry-run
./bin/basectl setup --profile devThe Ubuntu/Debian setup path runs:
sudo apt-get update
sudo apt-get install -y bash git python3 python3-venv python3-pip bats shellcheck jq golang-gobasectl check and basectl doctor keep the basic Ubuntu/Debian runtime path
separate from contributor tooling. Missing gh, BATS, ShellCheck, jq, or Go
are advisory warnings unless another runtime prerequisite is also failing.
The gh package should come from GitHub CLI's official Debian/Ubuntu
signed apt repository/keyring when the configured distro repositories do not
provide a current package. Follow the current official instructions at
https://github.com/cli/cli/blob/trunk/docs/install_linux.md#debian, then rerun
./bin/basectl setup --yes.
On Ubuntu/Debian, the dev prerequisite profile uses apt-backed developer
tools for the initial supported set: bats-core maps to bats, gh maps to
gh, and shellcheck maps to shellcheck. Once the apt-backed setup path has
installed those tools, ./bin/basectl setup --profile dev is idempotent and
does not require Homebrew.
Project-level brewfile delegates remain macOS/Homebrew-only. On
Ubuntu/Debian, Base validates the Brewfile path but skips brew bundle setup and
reports a warning from check/doctor instead of asking users to install Homebrew.
Linux project prerequisites should use a platform-native project path. For
projects that declare python.manager: uv or command-level runner: uv,
basectl setup <project> --dry-run shows the planned uv bootstrap when uv
is missing, and basectl setup <project> --yes installs uv before delegating
Python setup to uv sync. Base does not install uv for projects that have not
opted into the uv contract.
Projects that declare a mise config use the same Ubuntu/Debian review gate:
basectl setup <project> --dry-run shows the planned mise bootstrap when
mise is missing, and basectl setup <project> --yes installs mise before
delegating project tool setup to mise install. Base does not automatically
trust project-owned mise configs; if mise reports an untrusted config, review it
and run mise trust <path-to-mise-config> before retrying setup.
Project tool artifacts are still intentionally conservative on Linux. The first
platform-aware mapping is tool:bats-core: the manifest keeps the portable
artifact name, macOS continues to use Homebrew package bats-core, and
Ubuntu/Debian treats the artifact as satisfied by system package bats.
IDE extension checks are developer-workstation polish, not part of the default
Ubuntu/Debian runtime acceptance path. Default basectl check and
basectl ci check runs do not fail solely because editor CLIs such as code
are absent; run with --profile dev when you want Base to validate declared IDE
extensions.
GitHub CLI authentication remains a user-owned step. After gh is installed,
run the browser-backed flow when you need GitHub access:
gh auth login --web --git-protocol httpsBase should check and report GitHub CLI readiness, but it should not handle tokens or credentials. Base does not store GitHub tokens in Base-managed config.
Ubuntu desktop VMs can surface a GNOME keyring prompt such as "The password you
use to log in to your computer no longer matches that of your login keyring."
If the keyring cannot be unlocked and the VM is disposable or otherwise
acceptable for lower-security local storage, gh can use its documented
plain text fallback explicitly:
gh auth login --web --git-protocol https --insecure-storageUse that fallback only when you accept the tradeoff: the credential is written outside the system credential store and should be treated as a local secret. Prefer fixing or unlocking the desktop keyring for long-lived machines.
Then run:
./bin/basectl ci check base --format text
./bin/basectl check base --format text
./bin/basectl doctor base --format text
env -u BASE_HOME ./bin/base-testbase-test expects the sibling base-bash-libs checkout when running from a
source checkout. If it lives somewhere else, export BASE_BASH_LIBS_DIR to the
directory containing its reusable Bash libraries before running the suite.
GitHub Actions hosted Ubuntu runners use the same runtime contract but prepare
prerequisites in the workflow instead of asking basectl setup to mutate the
machine. Apple Silicon Macs running Ubuntu in Parallels should follow the same
basectl setup --dry-run / basectl setup --yes flow; golang-go, bats,
shellcheck, jq, and gh are available from the hosted runner and Ubuntu
ARM64 package archives used by Parallels when the configured apt repositories
provide them.
Mac developers can use the optional linux-lab prerequisite profile to prepare
a local Ubuntu VM host without making Linux support part of the default
developer profile:
basectl setup --profile linux-lab --dry-run
basectl setup --profile linux-lab
basectl check --profile linux-lab
basectl doctor --profile linux-labThe profile checks the multipass CLI and installs Multipass on macOS through
the Homebrew cask path when setup is run without --dry-run. It does not create
or mutate VM instances. After Multipass is installed, create a lab instance
explicitly:
multipass launch 24.04 \
--name ubuntu-dev \
--cpus 8 \
--memory 16G \
--disk 120G \
--mount "$HOME/work:/home/ubuntu/work"
multipass shell ubuntu-devApple Silicon Macs normally run ARM64 Ubuntu guests. That is useful for local
Linux preflight work, but hosted ubuntu-latest GitHub Actions runners remain
a separate validation target.
Linux shell startup differs from macOS:
- interactive Bash usually reads
~/.bashrc - login Bash may read
~/.bash_profile,~/.bash_login, or~/.profile - Zsh behavior is broadly portable but file locations remain user-specific
The existing managed-section model should remain the abstraction. Platform support should change which dotfiles are touched, not the managed-section format.
Existing path behavior already points in the right direction:
- state and venvs:
~/.base.d - runtime cache on Linux:
~/.cache/base
Linux support should preserve those defaults and continue to honor the existing environment overrides.
Linux support should make GitHub Actions a first-class validation target:
basectl ci check base --format json
basectl ci doctor base --format json
env -u BASE_HOME ./bin/base-testThe first CI-compatible milestone is live: workflows install their own
prerequisites before invoking Base, and basectl ci, basectl check, and
basectl doctor run Linux runtime checks without requiring Homebrew or Xcode.
The ubuntu-source-checkout job also runs the full source-checkout suite
through bin/base-test after preparing the Base-managed test virtual
environment and the sibling base-bash-libs checkout expected by source tests.
| Phase | Status | Notes |
|---|---|---|
| 1. Split macOS-only setup checks from portable runtime checks. | Done | Initial support exists through the live basectl ci entry point. |
| 2. Add platform detection and explicit unsupported-platform messages. | Done | BASE_PLATFORM classifies Ubuntu/Debian as linux-debian, keeps BASE_OS=linux, and fails unsupported platforms explicitly. |
3. Make basectl check and doctor report Linux prerequisite status without requiring Homebrew or Xcode. |
Done | check and doctor report Ubuntu/Debian prerequisite findings with apt-oriented recovery hints. |
| 4. Add Ubuntu CI coverage for read-only commands and the source-checkout suite. | Done for source-checkout validation | The ubuntu-source-checkout job installs hosted-runner prerequisites, runs basectl ci check base --format json, and runs env -u BASE_HOME ./bin/base-test. |
| 5. Add conservative Ubuntu setup guidance. | Done | basectl setup --dry-run previews Ubuntu/Debian apt prerequisites before mutation. |
| 6. Add apt-backed setup for simple prerequisites. | Done | basectl setup --yes runs apt-get update, installs the supported apt package list, creates the Base virtual environment, installs Base Python bootstrap packages, invokes the project setup layer, and seeds user config. |
7. Make basectl setup --profile dev use apt-backed developer tools on Ubuntu/Debian. |
Done | The dev profile maps bats-core, gh, and shellcheck to apt-backed tools and skips them when already installed. |
| 8. Polish GitHub CLI install/auth guidance. | Future | Keep token handling user-owned; add clearer setup/check/docs guidance for official gh install sources and login/keyring recovery. |
- Do not support every Linux distribution in the first pass.
- Do not add a second manifest format for Linux.
- Do not use arbitrary
python3silently on macOS to create Base-managed venvs. - Do not attempt GUI IDE installation on Linux until a real project needs it.