Skip to content

feat: install scripts, Linux packages and a container image - #2

Open
backtrack5r3 (tomflenner) wants to merge 3 commits into
mainfrom
feat/install-and-packaging
Open

backtrack5r3 (tomflenner) wants to merge 3 commits into
mainfrom
feat/install-and-packaging

Conversation

@tomflenner

@tomflenner backtrack5r3 (tomflenner) commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

What does this PR change?

Everything needed to install kaiten with one command on each platform, and to package every release:

  • install/install.sh (Linux, macOS) and install/install.ps1 (Windows): detect OS and architecture, download the release archive, verify its SHA-256 against the release's checksums.txt, install the binary. Both accept a version and an install directory; the shell script uses sudo only when the target directory actually needs it, and the PowerShell one installs under %LOCALAPPDATA%\Programs\kaiten and adds it to the user PATH, no administrator rights.
  • GoReleaser (.goreleaser.yaml) now also produces: .deb, .rpm and .apk packages (binary, completions, LICENSE and NOTICE in each format's convention); a multi-platform ghcr.io/kaitencloud/cli image on a distroless non-root base. The archives now carry shell completions too.
  • Archives and packages are named kaiten_<os>_<arch>.* without the version, so releases/latest/download/<asset> is a stable URL for all twelve of them. The install scripts rely on that.
  • release.yml: GHCR login, QEMU and Buildx for the arm64 image, packages: write. No secret beyond GITHUB_TOKEN.
  • ci.yml (lint job): goreleaser check, shellcheck on the shell installer and a PowerShell parse of the Windows one, so a broken installer or release config fails the PR rather than the tag.
  • Taskfile.yml: task release:snapshot builds the whole release into dist/ without a tag; task release:check now covers the scripts.
  • README: an Installation section per platform (macOS, Linux, Windows, container, Go, binaries, pinning a version, shell completion) and a Releasing subsection for maintainers.

Modeled on dapr/cli (per-OS install scripts, "latest release" resolution) and open-feature/cli (container image, checksum verification in the script).

Why?

A public CLI is only as usable as its install path. Until now the options were go install or unpacking an archive by hand.

Testing

  • goreleaser check (v2.12.7, the pinned version): clean, no deprecation warnings (uses dockers_v2, not the phased-out dockers).
  • goreleaser release --snapshot locally: all six binaries, archives, .deb/.rpm/.apk and both container images build. Verified with dpkg -c, rpm -qlp/rpm -qLp and tar -t that every package carries the binary, the completions, LICENSE and NOTICE; ran the arm64 image.
  • install/install.sh against the snapshot served over local HTTP: installs and prints the version; creates a missing nested install directory as the user, not root; refuses a tampered checksum and a missing checksum entry without writing anything; builds the right GitHub URL for a pinned version.
  • install/install.ps1 under pwsh on macOS against the same server: downloads, verifies, extracts and places kaiten.exe; refuses a tampered checksum before extracting; rejects an unsupported architecture. (Running the .exe is the one step that cannot be exercised off Windows.)
  • shellcheck --shell=sh, PowerShell parser, go build, go vet, go test, golangci-lint: all clean.

Not in this PR

  • Homebrew and Scoop were in the first revision and are dropped for now (second and third commits): neither kaitencloud/homebrew-tap nor kaitencloud/scoop-bucket exists yet. The removed blocks are in commit e417a77 if they come back. Nothing in the release needs a secret beyond GITHUB_TOKEN.
  • No tag yet, so releases/latest/download/… returns 404 until the first vX.Y.Z is pushed.

Checklist

  • I have read CONTRIBUTING.md.
  • Every commit in this PR includes a valid DCO Signed-off-by line.
  • I have the right to submit all material in this PR.
  • I have not included secrets or confidential data.
  • I have updated tests where appropriate.
  • I have updated documentation where appropriate.
  • I have preserved required third-party licenses and attributions.

🤖 Generated with Claude Code

…r image

install/install.sh (Linux, macOS) and install/install.ps1 (Windows) fetch
the release archive for the host's platform, verify it against the release's
checksums.txt and install the binary; both take a version and an install
directory, and the shell script uses sudo only when the target needs it.

GoReleaser now also produces .deb, .rpm and .apk packages with shell
completions, a Homebrew cask and a Scoop manifest for kaitencloud/homebrew-tap
and kaitencloud/scoop-bucket, and a multi-platform ghcr.io/kaitencloud/cli
image on a distroless base. Package and archive names carry no version, so
releases/latest/download/<asset> is a stable URL for every one of them.

The cask and the manifest are pushed only when HOMEBREW_TAP_GITHUB_TOKEN is
set and the tag is not a pre-release; otherwise they are left in dist/. CI
validates the GoReleaser configuration and both install scripts on every
pull request, and `task release:snapshot` builds the whole release locally.

Co-Authored-By: Claude Fable 5 <[email protected]>
Signed-off-by: tomflenner <[email protected]>
@Alexkuva
Alex (Alexkuva) self-requested a review October 1, 2026 11:12
Alexkuva
Alex (Alexkuva) previously approved these changes Oct 1, 2026
The tap does not exist yet, so the cask could not be published anyway. The
token the release passes for package-manager repositories is now named for
its one remaining user, SCOOP_BUCKET_GITHUB_TOKEN.

Co-Authored-By: Claude Fable 5 <[email protected]>
Signed-off-by: tomflenner <[email protected]>
@tomflenner
backtrack5r3 (tomflenner) requested a review from a team as a code owner October 3, 2026 09:22
@tomflenner backtrack5r3 (tomflenner) changed the title feat: install scripts, Linux packages, Homebrew, Scoop and a container image feat: install scripts, Linux packages, Scoop and a container image Oct 3, 2026
Same reason as the Homebrew cask: the bucket does not exist yet. With it goes
the only token the release workflow needed beyond GITHUB_TOKEN.

Co-Authored-By: Claude Fable 5 <[email protected]>
Signed-off-by: tomflenner <[email protected]>
@tomflenner backtrack5r3 (tomflenner) changed the title feat: install scripts, Linux packages, Scoop and a container image feat: install scripts, Linux packages and a container image Oct 3, 2026
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