Skip to content

feat: one-command Linux installer (install.sh) - #199

Merged
spark2ignite merged 4 commits into
mainfrom
linux-install-script
Oct 16, 2026
Merged

spark2ignite merged 4 commits into
mainfrom
linux-install-script

Conversation

@spark2ignite

Copy link
Copy Markdown
Collaborator

What

A one-command Linux install:

curl -fsSL https://raw.githubusercontent.com/doitintl/dci-cli/main/install.sh | sh

It downloads the release archive for this machine, checks it against the release's checksums.txt, and installs dci to ~/.local/bin with bash, zsh and fish completions. No root is needed.

Why ~/.local/bin: Cloud Shell keeps only $HOME, so a .deb installed with dpkg -i disappears when the VM restarts. The same install also works in WSL, containers and on machines without sudo. dci update already treats a binary there as a standalone install and replaces it in place.

Options (passed after sh -s --):

  • --version <v> / DCI_VERSION installs a specific release.
  • --dir <path> / DCI_INSTALL_DIR picks the install directory.
  • --system installs the .deb/.rpm package with sudo instead.

Design notes

  • No GitHub API calls. With no --version, the version and checksum both come from releases/latest/download/checksums.txt. That avoids the unauthenticated rate limit that shared Cloud Shell and CI IPs run into.
  • A checksum mismatch, or no checksum tool, stops the install. The binary is copied next to its destination and then renamed into place, so the swap is atomic.
  • Truncation-safe. All logic is in functions and main "$@" is the last line, so a script cut off mid-download can't run.
  • Clear failures up front. On musl systems (Alpine) it explains that glibc is needed, instead of leaving a binary that fails with "not found". On macOS it points to Homebrew.
  • PATH and other installs. It prints the exact PATH line when the directory isn't on PATH, and warns when another dci earlier on PATH would take precedence.
  • POSIX sh, so it runs under dash on Debian/Ubuntu. Passes shellcheck -s sh.

CI

New install-script.yml workflow:

  • Runs shellcheck.
  • Installs on ubuntu:24.04, debian:12 and fedora:41 containers, on both amd64 and arm64 runners. Each run covers a non-root user install with completions, a pinned 2.7.5 install, and --system.
  • Runs on Alpine, where the install must fail with the glibc message.
  • Triggers on changes to the script, and weekly so a renamed release asset or a changed archive layout is caught.

Verified locally (Docker)

Scenario Result
Ubuntu 24.04 arm64, curl, non-root ✅ 2.8.0 in ~/.local/bin, bash and fish completions in place
Debian 12 amd64 (emulated), wget only, --version v2.7.5, SHELL=zsh ✅ 2.7.5, plus the zsh fpath hint
Fedora 41 --system ✅ dci-2.8.0-1.aarch64 rpm, /usr/bin/dci
Ubuntu 24.04 --system ✅ deb 2.8.0
Piped cat install.sh | sh -s -- --dir /opt/dci/bin ✅
Install 2.7.5, then dci update --yes ✅ dci updated: 2.7.5 → 2.8.0
Fake sha256sum (checksum mismatch) ✅ aborts with "checksum mismatch … not installing", nothing installed
Alpine 3.20 ✅ glibc error, exit 1
--version 0.0.1 ✅ "version 0.0.1 not found", exit 1
macOS ✅ prints the Homebrew command, exit 1

The README now lists the Linux one-liner first and notes that the Homebrew formula also works on Linux. DISTRIBUTION.md gains a Linux Installer section describing what the script depends on (release asset names and archive layout).

🤖 Generated with Claude Code

spark2ignite and others added 3 commits October 16, 2026 14:02
curl -fsSL https://raw.githubusercontent.com/doitintl/dci-cli/main/install.sh | sh

Downloads the release archive for this machine, verifies it against the
release's checksums.txt, and installs dci to ~/.local/bin with bash/zsh/fish
completions, with no root needed. That location survives Cloud Shell
restarts (only $HOME persists) and dci update replaces it in place.
--version pins a release, --dir picks the directory, and --system installs
the .deb/.rpm with sudo. Musl systems get a clear glibc error up front.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Shellcheck plus installs on ubuntu/debian/fedora containers on amd64 and
arm64 runners (user install as non-root, pinned version, --system), and an
Alpine run that must fail with the glibc message. Runs on changes to the
script and weekly, so a release-asset rename that breaks it is caught.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added documentation Improvements or additions to documentation automation GitHub Actions and repository automation changes labels Oct 16, 2026

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Findings marked 🟡 are optional suggestions and need no follow-up push.

Comment thread install.sh Outdated
Comment thread install.sh
Comment thread install.sh
Comment thread .github/workflows/install-script.yml
- Detect glibc by its presence (getconf, then the arch's glibc loader)
  instead of refusing any host with a musl loader: Debian's musl-tools
  puts one on glibc systems.
- Run the staged binary before it replaces ~/.local/bin/dci; a binary
  that can't start (glibc older than 2.34) is removed with a clear error
  and the existing dci is kept. --system checks the installed binary too.
- rpm -U --oldpackage so a pinned --system --version can roll back.
- release.yml dispatches the Install Script workflow after each release.
- CI covers Alpine, Debian with musl-tools, and Ubuntu 20.04 (old glibc
  keeps the existing dci). README/DISTRIBUTION state the glibc 2.34 floor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the release Release configuration and publishing changes label Oct 16, 2026
@spark2ignite
spark2ignite merged commit aed33ac into main Oct 16, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automation GitHub Actions and repository automation changes documentation Improvements or additions to documentation release Release configuration and publishing changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant