Skip to content

fix: install script displays wrong version and doubled binary name #406

@richardjortega

Description

@richardjortega

Problem Statement

The install script reports a different version in the "installed" message than the version it downloaded. It also doubles the binary name ("openshell openshell"). When a user runs the installer, they see "downloading openshell v0.0.8" followed by "installed openshell openshell 0.0.7" — confusing and eroding trust in the install process.

❯ curl -LsSf https://raw.githubusercontent.com/nvidia/openshell/main/install.sh | sh
openshell: resolving latest version...
openshell: downloading openshell v0.0.8 (aarch64-apple-darwin)...
openshell: verifying checksum...
openshell: extracting...
openshell: installed openshell openshell 0.0.7 to /Users/<userHome>/.local/bin/openshell

Two distinct bugs:

  1. Version mismatch: Download says v0.0.8, installed message says v0.0.7
  2. Name doubling: "openshell openshell" instead of "openshell"

Technical Context

The install script resolves the latest version from GitHub releases, downloads the tarball, and then runs the installed binary with --version to report what was installed. The "downloading" message uses the GitHub release tag, but the "installed" message uses the binary's --version output — and these derive versions differently.

The binary's version is determined at build time by build.rs via git describe --tags, which can pick a different (older) tag when multiple tags point to the same commit. The install script's final message format also doesn't account for clap's --version output already including the binary name.

Affected Components

Component Key Files Role
Install script install.sh Downloads CLI, reports installed version
Core version const crates/openshell-core/src/lib.rs VERSION constant used by --version
Build-time version crates/openshell-core/build.rs git_version() sets OPENSHELL_GIT_VERSION
CLI version flag crates/openshell-cli/src/main.rs clap version = openshell_core::VERSION
Release workflow .github/workflows/release-tag.yml Builds CLI, patches version, creates release
Auto-tag workflow .github/workflows/release-auto-tag.yml Creates lightweight tags on schedule
Version computation tasks/scripts/release.py setuptools-scm based version derivation
macOS build deploy/docker/Dockerfile.cli-macos Cross-compile with version patching

Technical Investigation

Architecture Overview

Version flows through two separate paths:

Path A (install script "downloading" message):
GitHub latest release redirectinstall.sh resolves tag → prints "downloading v0.0.8"

Path B (install script "installed" message):
build.rs::git_version()git describe --tags --long --match v* → sets OPENSHELL_GIT_VERSION env var → lib.rs::VERSION picks it up via option_env!() → binary --version output → install script captures it → prints "installed openshell 0.0.7"

The mismatch occurs because git describe picks the oldest tag when multiple lightweight tags point to the same commit, while the GitHub release API returns the newest tag.

Code References

Location Description
install.sh:436-437 Runs --version and formats the "installed" message — source of the doubling bug
install.sh:167-171 Resolves latest version via GitHub redirect — source of the "downloading" version
crates/openshell-core/build.rs:61-93 git_version() function — runs git describe to derive version
crates/openshell-core/build.rs:81-83 When commits=0, returns the tag version directly (e.g., "0.0.7")
crates/openshell-core/build.rs:16 Sets OPENSHELL_GIT_VERSION cargo env var
crates/openshell-core/src/lib.rs:28-31 VERSION const: prefers OPENSHELL_GIT_VERSION over CARGO_PKG_VERSION
crates/openshell-cli/src/main.rs:302 clap version = openshell_core::VERSION
.github/workflows/release-tag.yml:195-237 Linux CLI build — has .git dir, so build.rs git_version() runs
.github/workflows/release-tag.yml:234 Sed-patches Cargo.toml to the release version (correct, but overridden by build.rs)
.github/workflows/release-auto-tag.yml:37-44 Skip logic for same-commit tags (recently added)
tasks/scripts/release.py setuptools-scm version derivation — same git describe tiebreaking issue

Current Behavior

Bug 1 — Version mismatch chain:

  1. Auto-tag workflow creates lightweight tag v0.0.8 on commit bb4545f
  2. Tag v0.0.7 already exists on the same commit
  3. Install script resolves v0.0.8 via GitHub redirect, prints "downloading v0.0.8"
  4. Release workflow builds CLI for v0.0.8 with fetch-depth: 0 and git fetch --tags --force
  5. build.rs runs git describe --tags --long --match v* → returns v0.0.7-0-gbb4545f (git picks older tag)
  6. Since commits=0, build.rs returns "0.0.7" as the version
  7. OPENSHELL_GIT_VERSION=0.0.7 overrides the correctly sed-patched CARGO_PKG_VERSION=0.0.8
  8. Binary reports openshell 0.0.7

Bug 2 — Doubling chain:

  1. install.sh:436 captures --version output: "openshell 0.0.7" (clap includes binary name)
  2. install.sh:437 formats: "installed ${APP_NAME} ${_installed_version}""installed openshell openshell 0.0.7"

What Would Need to Change

Bug 2 (doubling) — install.sh:436-437:
Strip the binary name from --version output before inserting into the message, or restructure the message to not prepend APP_NAME when using --version output.

Bug 1 (version mismatch) — crates/openshell-core/build.rs:
The git_version() function should check for an explicit version override env var (e.g., OPENSHELL_CARGO_VERSION, which is already computed and passed in CI for macOS builds) before falling back to git describe. This way, the release pipeline can authoritatively set the version regardless of git tag ordering.

Additionally, release-tag.yml Linux build steps should pass this env var (they currently only do it for macOS).

Defensive measure — release-tag.yml:
Add a post-build assertion that the binary's --version output matches the release tag before packaging.

Install script fallback — install.sh:436:
The fallback path (echo "${_version}") includes the v prefix (e.g., v0.0.8) while the binary's --version omits it. Strip the prefix for consistency.

Alternative Approaches Considered

Approach Pros Cons
A: Make build.rs honor explicit version env var (recommended) Fixes binary's actual embedded version; CI already computes the value Requires passing env var in Linux build steps
B: Unset OPENSHELL_GIT_VERSION in CI builds Minimal change; sed-patched CARGO_PKG_VERSION wins Fragile — any CI change that restores .git could reintroduce
C: Only use $_version in install script (skip --version) Simplest install.sh change Masks the real problem; binary still has wrong embedded version
D: Use annotated tags instead of lightweight git describe handles annotated tags more predictably Requires changing auto-tag workflow; doesn't fix build.rs root cause

Patterns to Follow

  • The macOS build in Dockerfile.cli-macos already receives and uses OPENSHELL_CARGO_VERSION for sed-patching. The Linux build should follow the same pattern.
  • Version constants in lib.rs already have the option_env! fallback chain — just needs the priority order adjusted or a new authoritative env var added.

Proposed Approach

Fix the install script doubling by stripping the binary name from --version output before formatting the message. Fix the version mismatch by making build.rs honor an explicit version override env var that the release pipeline can set authoritatively, bypassing git describe tiebreaking issues. Add a CI assertion that validates the built binary's embedded version matches the release tag before publishing artifacts.

Scope Assessment

  • Complexity: Low
  • Confidence: High — clear path forward, root causes fully identified
  • Estimated files to change: 3-4 (install.sh, build.rs, release-tag.yml, possibly lib.rs)
  • Issue type: fix

Risks & Open Questions

  • The setuptools-scm version in release.py has the same git describe tiebreaking issue — should it also be fixed, or is the build.rs fix sufficient?
  • The recently added skip logic in release-auto-tag.yml (commit 5439f47) should prevent future same-commit tags, but manual tag creation could still trigger this. The build.rs fix makes the system robust regardless.
  • Local developer builds (without the override env var) will continue using git describe — this is acceptable since local builds don't need precise release versions.

Test Considerations

  • The canary workflow (release-canary.yml:86-92) already runs install.sh and openshell --version but doesn't validate the install message format or version consistency. Adding assertions would catch regressions.
  • Add a post-build CI step in release-tag.yml that asserts the binary's --version output matches the expected release version before packaging.
  • For macOS cross-compiled binaries (can't execute on Linux), validate via strings command or skip the assertion.
  • The doubling fix can be verified by inspecting install.sh output format in the canary workflow.

Created by spike investigation. Use build-from-issue to plan and implement.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions