Skip to content

Star release process and self-install #339

Open

Description

@David-Noble-at-work

Migrated from NobleFactor/noblefactor-ops#61 (star now lives in this repository; GitHub blocks private→public transfers). Original discussion remains there.

Summary

Implement an LKG (Last Known Good) release process for star with automatic updates via self upgrade. This is a prerequisite for the quality gate — every repo needs a working star binary to generate its .pre-commit-config.yaml.

Continues work from #27 (closed without implementation).

Goals

  1. LKG releases: make release validates and creates immutable versioned binaries
  2. Validation gate: Release only succeeds if star passes all behavior tests
  3. Bootstrap install: curl | bash for initial install on machines without star
  4. Self install: star self install generates completions, man pages, config (offline)
  5. Self upgrade: star self upgrade checks for and installs latest LKG (network)

Current State

Component Status Notes
star self install Partial Requires path arg, no --prefix default
star self upgrade Missing No LKG check or download
Man page generation Working Generated by star on demand
Shell completions Working Generated by star (bash, fish, powershell, zsh)
ops/ scripts External Copies .star files (should be embedded)
Default to ~/.local Missing Currently requires path argument
Embedded scripts Missing .star files not embedded in binary
LKG version check Missing No check for newer release
XDG config directory Missing No config.yaml creation
Makefile Missing No build/test/validate/release targets
Release workflow Missing No goreleaser, no release binaries
Bootstrap script Missing No curl | bash install
VERSION file Missing No version tracking file

LKG Release Process

Release candidates cycle until validation passes, then promote to LKG.

Workflow:

make rc          # v0.1.0-rc.1 - bump RC, run tests (fails)
# fix issues
make rc          # v0.1.0-rc.2 - bump RC, run tests (fails)
# fix issues
make rc          # v0.1.0-rc.3 - bump RC, run tests (passes!)
make release     # v0.1.0 - promote to LKG, clean up RCs

Commands:

Command Description
make release-candidate Bump RC number, run tests, report pass/fail
make rc Alias for release-candidate
make release Promote passing RC to LKG, delete RC tags
make clean-rc Delete all RC tags without releasing

Version format (semver compliant):

v0.1.0-rc.20260206T143022-abc1234    # RC: pre-release with timestamp + commit
v0.1.0+20260206T151033.ghi9012       # LKG: release with build metadata
v0.1.0                                # Clean tag (points to same commit as above)

Sorting: v0.1.0-rc.* < v0.1.0 = v0.1.0+metadata

Release artifacts (LKG only):

star_v0.1.0_darwin_amd64.tar.gz
star_v0.1.0_darwin_arm64.tar.gz
star_v0.1.0_linux_amd64.tar.gz
star_v0.1.0_linux_arm64.tar.gz
star_v0.1.0_windows_amd64.zip
checksums.txt

Validation Tests

Release is blocked unless star passes behavior tests:

Test Description
star --version Outputs version string
star lint go Runs golangci-lint successfully
star lint shell Runs shellcheck/shfmt successfully
star lint markdown Runs markdownlint successfully
star setup tools Reports tool status
star setup config Generates configs from star.yaml
star self install --prefix /tmp/test Installs completions, man pages, config

Bootstrap Install

Initial install for machines without star. noblefactor-ops is a private repository — bootstrap scripts require GH_TOKEN with Contents read permission.

macOS/Linux (bash):

curl -sSL https://raw.githubusercontent.com/NobleFactor/noblefactor-ops/develop/scripts/install-star.sh | GH_TOKEN=$(gh auth token) bash

Windows (PowerShell):

$env:GH_TOKEN = (gh auth token); irm https://raw.githubusercontent.com/NobleFactor/noblefactor-ops/develop/scripts/install-star.ps1 | iex

What the scripts do:

  1. Verify GH_TOKEN is set (required for private repo)
  2. Detect OS and architecture
  3. Download latest LKG release from GitHub (via authenticated API)
  4. Verify checksum
  5. Extract to platform-appropriate location (Unix: ~/.local/bin/star, Windows: ~\AppData\Local\star\bin\star.exe)
  6. Run star self install to generate man pages, completions, config
  7. Print PATH instructions

Self Install (Local, Offline)

star self install                   # Default: ~/.local
star self install --prefix /usr/local

Generates and installs to XDG locations:

  • ${XDG_DATA_HOME}/man/man1/star*.1 (man pages)
  • ${XDG_DATA_HOME}/bash-completion/completions/star (bash)
  • ${XDG_DATA_HOME}/fish/vendor_completions.d/star.fish (fish)
  • ${XDG_DATA_HOME}/zsh/site-functions/_star (zsh)
  • ${XDG_DATA_HOME}/powershell/Completions/star.ps1 (PowerShell)
  • ${XDG_CONFIG_HOME}/star/config.yaml (config placeholder)

Key behaviors: works offline, idempotent, XDG compliant.

Self Upgrade (Network)

star self upgrade                    # Requires GH_TOKEN for private repo
  1. Check current version vs latest LKG on GitHub (requires GH_TOKEN)
  2. If newer: download, verify checksum, replace binary
  3. Call self install to regenerate completions/man pages
  4. Report what was updated

Release caching in ${XDG_CACHE_HOME}/star/releases/ to reduce redundant downloads.

Embedded Scripts

All .star scripts embedded in binary via //go:embed:

//go:embed *.star
var Scripts embed.FS

Script search path (first match wins):

Priority Location Purpose
1 ./ops/*.star Project-specific scripts (repo)
2 ${XDG_DATA_HOME}/star/ops/*.star Extracted scripts (debugging)
3 Embedded Fallback (always works)

Extract for debugging: star self install --extract-scripts

Version Bumping

make bump-patch   # 0.1.0 → 0.1.1
make bump-minor   # 0.1.0 → 0.2.0
make bump-major   # 0.1.0 → 1.0.0

scripts/bump-version.sh validates no version gaps against the last released tag.

Implementation Phases

Phase 1: Version Flag and Makefile

  • Create VERSION file (initial: 0.1.0)
  • Create scripts/bump-version.sh with gap validation
  • Add version variables and --version flag to cmd/star/main.go
  • Create Makefile with build, test, validate, bump, rc, release, clean-rc targets

Phase 2: Release Workflow

  • Create .goreleaser.yaml (darwin/linux/windows × amd64/arm64, single binary, checksums, ldflags)
  • Create .github/workflows/release.yaml (trigger on v* tags, test + validate + goreleaser)
  • Model after devlore-cli/.goreleaser.yaml (simpler: single binary, no nfpms/brews)

Phase 3: Embed Scripts with Search Path

  • Create ops/embed.go with //go:embed *.star
  • Update internal/starlark/loader.go with search path: ./ops/ → XDG → embedded
  • Add --extract-scripts flag to self install

Phase 4: Self Command with Install and Upgrade Subcommands

  • Create self parent command with install and upgrade subcommands
  • self install: default ~/.local, --prefix flag, XDG compliant paths
  • self upgrade: GH_TOKEN required, version check, download, checksum verify, replace binary
  • GitHub release API client with caching in ${XDG_CACHE_HOME}/star/releases/
  • Reference implementation: devlore-cli/internal/cli/selfinstall.go

Phase 5: Bootstrap Scripts

  • scripts/install-star.sh (bash for macOS/Linux)
  • scripts/install-star.ps1 (PowerShell for Windows)
  • Reference implementation: devlore-cli/install.sh

Files to Create/Modify

File Action Phase
VERSION Create 1
scripts/bump-version.sh Create 1
cmd/star/main.go Modify — add version flag 1
Makefile Create 1
.goreleaser.yaml Create 2
.github/workflows/release.yaml Create 2
ops/embed.go Create 3
internal/starlark/loader.go Modify — search path + embedded FS 3
internal/cli/selfinstall.go Modify — add --extract-scripts 3
internal/cli/self.go Create — parent command 4
internal/cli/self_install.go Create — install subcommand 4
internal/cli/self_upgrade.go Create — upgrade subcommand 4
internal/cli/release.go Create — GitHub release API client + caching 4
scripts/install-star.sh Create 5
scripts/install-star.ps1 Create 5

Related

Open Questions

  • Should we support brew install via a tap?
  • Should releases be signed? (See noblefactor-ops#60, certificate procurement)
  • What's the minimum Go version for building?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Epic:ReleaseDistributionRelease, distribution, and self-installfeatureDeliverable unit within an epic

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions