Files
beads/scripts/update-nix-vendorhash.sh
Bob Cotton c802f27fe5 feat: comprehensive NixOS support improvements (#1024)
* feat: comprehensive NixOS support improvements

This commit adds full NixOS support and automates Nix package maintenance:

## Static Linux Binaries for NixOS

Changes .goreleaser.yml to create static Linux binaries:
- Set CGO_ENABLED=0 for Linux amd64 and arm64 builds
- Remove cross-compiler dependencies (aarch64-linux-gnu-gcc)
- Simplifies build process while fixing NixOS compatibility

Static binaries work on all Linux distributions including NixOS, Alpine,
and musl-based distros without dynamic linker dependencies.

## Automated default.nix Version Management

Adds default.nix to the version bump workflow:
- Updates default.nix version field in bump-version.sh (new step 9)
- Adds default.nix to version verification checks
- Prevents version drift (was 5 releases behind: 0.42.0 vs 0.47.0)
- Updates README.md to remove glibc 2.32+ requirement

## Automated vendorHash Management

Creates scripts/update-nix-vendorhash.sh to automate vendorHash updates:
- Automatically detects correct hash by triggering Nix build error
- Extracts hash from error message and updates default.nix
- Verifies update with clean build
- Eliminates error-prone manual copy-paste workflow
- Works with local Nix OR Docker (uses nixos/nix image automatically)

Integrates vendorHash check into bump-version.sh:
- Detects when go.mod or go.sum have changed
- Prompts to run vendorHash update script interactively
- Catches synchronization issues at release time

## Documentation

Updates AGENTS.md with Nix package maintenance guide:
- Documents when and how to update vendorHash
- Recommends automated script as primary method
- Provides manual and alternative methods as fallback
- Notes Docker fallback for maintainers without Nix

## Impact

- NixOS users can now install via standard methods
- Nix package version stays synchronized automatically
- vendorHash updates work without Nix installed (via Docker)
- vendorHash updates are caught during release workflow
- All Linux users benefit from more portable binaries

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: address PR review feedback for NixOS support

Fixes three issues identified in PR review:

1. Replace undefined log_* functions in bump-version.sh with existing
   echo pattern (log_warning, log_info, log_success, log_error were
   called but not defined)

2. Update default.nix version from 0.42.0 to 0.47.0 to fix version
   drift with cmd/bd/version.go

3. Remove Nix Package Maintenance section from AGENTS.md per beads
   architecture (use bd prime for dynamic context, keep AGENTS.md
   minimal)

* fix: update versions to 0.47.1 after merge with main

- Update claude-plugin plugin.json to 0.47.1
- Update default.nix to 0.47.1
- Fixes version check failures after merging latest main branch

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-12 23:46:33 -08:00

198 lines
6.1 KiB
Bash
Executable File

#!/bin/bash
set -e
# =============================================================================
# UPDATE NIX VENDORHASH SCRIPT
# =============================================================================
#
# Automatically updates the vendorHash in default.nix after go.mod changes.
# This script:
# 1. Sets vendorHash to a known-bad hash to trigger an error
# 2. Runs nix build to get the actual hash from the error message
# 3. Extracts the correct hash from the error
# 4. Updates default.nix with the correct hash
# 5. Verifies the update by rebuilding
#
# Requirements:
# - Either nix installed locally, OR
# - Docker (will automatically use nixos/nix Docker image)
#
# Usage:
# ./scripts/update-nix-vendorhash.sh
#
# =============================================================================
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
log_info() {
echo -e "${BLUE}==>${NC} $1"
}
log_success() {
echo -e "${GREEN}${NC} $1"
}
log_warning() {
echo -e "${YELLOW}${NC} $1"
}
log_error() {
echo -e "${RED}${NC} $1" >&2
}
# Check if we're in the repo root
if [ ! -f "default.nix" ]; then
log_error "Must run from repository root (default.nix not found)"
exit 1
fi
# Determine if we should use Docker for Nix
USE_DOCKER=false
NIX_CMD="nix"
if ! command -v nix &> /dev/null; then
log_warning "nix command not found locally"
# Check if Docker is available
if command -v docker &> /dev/null; then
log_info "Docker detected - will use nixos/nix Docker image"
USE_DOCKER=true
# Pull the Nix Docker image if not present
if ! docker image inspect nixos/nix:latest &> /dev/null; then
log_info "Pulling nixos/nix:latest Docker image..."
docker pull nixos/nix:latest
fi
else
log_error "Neither nix nor docker found."
log_error "Please install one of:"
log_error " - Nix: https://nixos.org/download.html"
log_error " - Docker: https://docs.docker.com/get-docker/"
exit 1
fi
fi
# Function to run nix commands (either locally or via Docker)
run_nix() {
if [ "$USE_DOCKER" = true ]; then
# Get absolute path of current directory
ABS_PWD=$(cd "$(pwd)" && pwd)
# Run nix in Docker container with current directory mounted
# Mount at both /workspace and the original path (for git worktree compatibility)
DOCKER_VOLUMES="-v $ABS_PWD:/workspace -v $ABS_PWD:$ABS_PWD"
# If this is a git worktree, mount the main git directory too
if [ -f .git ] && grep -q "^gitdir: " .git; then
GIT_COMMON_DIR=$(git rev-parse --git-common-dir 2>/dev/null || echo "")
if [ -n "$GIT_COMMON_DIR" ] && [ -d "$GIT_COMMON_DIR" ]; then
# Mount the main git directory at the same path
DOCKER_VOLUMES="$DOCKER_VOLUMES -v $GIT_COMMON_DIR:$GIT_COMMON_DIR"
fi
fi
docker run --rm \
$DOCKER_VOLUMES \
-w /workspace \
nixos/nix:latest \
nix "$@" --extra-experimental-features "nix-command flakes"
else
nix "$@"
fi
}
log_info "Updating vendorHash in default.nix..."
echo ""
# Get current vendorHash
CURRENT_HASH=$(grep 'vendorHash = ' default.nix | sed 's/.*"\(.*\)".*/\1/')
log_info "Current vendorHash: $CURRENT_HASH"
# Step 1: Set to a known-bad hash to trigger an error
log_info "Setting temporary bad hash to trigger error..."
FAKE_HASH="sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
# Backup the file
cp default.nix default.nix.backup
# Detect sed version (GNU vs BSD)
if sed --version 2>/dev/null | grep -q "GNU sed"; then
SED_INPLACE="sed -i"
else
SED_INPLACE="sed -i ''"
fi
# Update to fake hash
$SED_INPLACE "s|vendorHash = \".*\";|vendorHash = \"$FAKE_HASH\";|" default.nix
# Step 2: Run nix build and capture the error
log_info "Building to get actual hash (this will fail intentionally)..."
BUILD_LOG="/tmp/nix-vendorhash-build-$$.log"
run_nix build > "$BUILD_LOG" 2>&1 || true
# Step 3: Extract the actual hash from the error message
# Error format: "error: hash mismatch ... got: sha256-ACTUAL_HASH" (note: multiple spaces)
# Use portable grep + sed instead of grep -P (which requires GNU grep)
ACTUAL_HASH=$(grep -o 'got:[[:space:]]*sha256-[A-Za-z0-9+/=]*' "$BUILD_LOG" | head -1 | sed 's/got:[[:space:]]*//')
if [ -z "$ACTUAL_HASH" ]; then
log_error "Failed to extract hash from nix build output"
log_error "This might mean:"
log_error " - Go dependencies haven't changed (no update needed)"
log_error " - There's a different build error"
echo ""
log_info "Build output (last 30 lines):"
tail -30 "$BUILD_LOG"
echo ""
log_info "Full build log saved to: $BUILD_LOG"
# Restore backup
mv default.nix.backup default.nix
log_info "Restored original default.nix"
# Check if hash is actually the same
if grep -q "hash mismatch" "$BUILD_LOG"; then
log_error "Hash mismatch detected but couldn't extract hash"
log_error "Check the full log: $BUILD_LOG"
exit 1
else
log_success "No hash mismatch - vendorHash is already correct!"
rm -f "$BUILD_LOG"
exit 0
fi
fi
log_success "Extracted actual hash: $ACTUAL_HASH"
# Step 4: Update default.nix with the correct hash
log_info "Updating default.nix with correct hash..."
$SED_INPLACE "s|vendorHash = \".*\";|vendorHash = \"$ACTUAL_HASH\";|" default.nix
# Remove backup
rm default.nix.backup
# Step 5: Verify the update by rebuilding
log_info "Verifying update with a clean build..."
if run_nix build 2>&1 | tee /tmp/nix-build-verify.log; then
log_success "Build successful! vendorHash updated correctly."
echo ""
log_info "Summary:"
echo " Old hash: $CURRENT_HASH"
echo " New hash: $ACTUAL_HASH"
echo ""
log_success "default.nix has been updated"
# Clean up build logs
rm -f "$BUILD_LOG" /tmp/nix-build-verify.log
else
log_error "Build failed after updating hash"
log_error "See /tmp/nix-build-verify.log for details"
log_error "Initial build log: $BUILD_LOG"
exit 1
fi