Skip to content

feat: universal Nix setup with phase architecture, testing, and CI#244

Open
szymonos wants to merge 46 commits into
mainfrom
feat/universal-nix-setup
Open

feat: universal Nix setup with phase architecture, testing, and CI#244
szymonos wants to merge 46 commits into
mainfrom
feat/universal-nix-setup

Conversation

@szymonos

@szymonos szymonos commented Apr 18, 2026

Copy link
Copy Markdown
Owner

Summary

Introduces Nix as a cross-platform package manager for reproducible dev environment setup on Linux and macOS, with a phase library architecture, comprehensive testing framework, CI workflows, and repository restructuring.

Commits

1. refactor: reorganize provision scripts into check, fix, and setup dirs

Reorganizes .assets/provision/ into purpose-specific directories:

  • check_*.sh.assets/check/
  • fix_*.sh.assets/fix/
  • setup_*.sh, set_*.sh.assets/setup/

Removes deprecated scripts (install_brew.sh, install_pixi.sh, fix_certifi_certs.sh). Updates all path references in Vagrantfiles, Dockerfiles, linux_setup.sh, and source.sh.

2. feat: Nix-based cross-platform setup with declarative package management

Core infrastructure for managing dev tools via Nix:

  • Phase library architecture (nix/lib/phases/) — setup.sh is a slim ~120-line orchestrator that sources 8 phase libraries (bootstrap, platform, scopes, nix_profile, configure, profiles, post_install, summary). Each phase uses _io_* wrappers (_io_nix, _io_run, _io_curl_probe) for testability.
  • nix/setup.sh — main entry point for all platforms (macOS, Linux, WSL, containers). User-scope, rootless, idempotent.
  • nix/flake.nix — declarative package set using buildEnv
  • 19 scope files (nix/scopes/*.nix) — base, shell, python, k8s, az, docker, terraform, etc.
  • Scope system.assets/lib/scopes.json defines valid scopes, dependency rules, and install order; .assets/lib/scopes.sh provides resolution logic (bash 3.2 compatible)
  • nx CLI — declarative package management commands: install, remove, list, scope add/remove, pin, rollback, overlay, doctor
  • Configure scripts (nix/configure/) — per-scope setup for profiles, starship, omp, gh, git, conda, docker, az
  • Certificate handlingfix_{azcli,gcloud,nodejs}_certs.sh for corporate proxy environments
  • WSL integrationwsl_setup.ps1 extended with Nix path support
  • Install records.assets/lib/install_record.sh for provenance tracking

3. test: bats and Pester unit testing with pre-commit hooks

Bats tests (13 test files):

  • test_nix_setup.bats — config generation, scope merging, arg parser, prompt exclusivity, nix profile operations
  • test_scopes.bats — scope helpers, validation, dependency resolution
  • test_nx_commands.bats, test_nx_scope.bats, test_nx_pkgs.bats — nx CLI operations
  • test_nx_doctor.bats, test_overlay.bats — diagnostics and overlay system
  • test_profile_block.bats, test_profile_migration.bats — profile injection
  • test_source.bats, test_functions.bats, test_git_aliases.bats, test_fixcertpy_discovery.bats

Pester tests (9 test files):

  • NxCommands.Tests.ps1, NxHelpers.Tests.ps1, Scopes.Tests.ps1 — PowerShell nx and scope logic
  • ConvertCfg.Tests.ps1, ConvertPEM.Tests.ps1, GetLogLine.Tests.ps1, InvokeCommandRetry.Tests.ps1, JoinStr.Tests.ps1, WslSetup.Tests.ps1

Pre-commit hooks (via prek):

  • check_bash32.py — enforces bash 3.2 compatibility on nix-path files
  • validate_scopes.py — scope definition consistency between JSON and .nix files
  • run_bats.py / run_pester.py — auto-detect and run affected tests
  • align_tables.py — markdown table alignment
  • gremlins.py — unwanted Unicode character detection

4. ci: Linux and macOS integration test workflows with Docker smoke tests

  • test_linux.yml — runs nix/setup.sh in daemon and no-daemon (Coder) modes
  • test_macos.yml — tests on macOS 14/15 with bash 3.2 and BSD sed
  • repo_checks.yml — pre-commit hooks via prek
  • Docker smoke test images (Dockerfile.test-nix, Dockerfile.test-legacy)
  • Makefile targets: lint, test, test-unit, test-nix, test-legacy

5. docs: ARCHITECTURE.md, CONTRIBUTING.md, and project documentation

  • ARCHITECTURE.md — file classification, call tree, runtime layout, bash 3.2/BSD sed constraints, phase library convention
  • CONTRIBUTING.md — dev workflow, pre-commit hooks, testing patterns (_io_* stubs), style reference
  • CLAUDE.md — updated project overview and coding guidelines
  • AGENTS.md, SUPPORT.md, CHANGELOG.md
  • docs/corporate_proxy.md, docs/customization.md — user-facing guides

6. chore: update configs, aliases, PS module fixes, and minor script tweaks

  • Bash aliases: nix-aware paths, improved git/kubectl aliases
  • OMP configs: updated prompt segments
  • PowerShell fixes: IDictionary param types, LogContext variable rename, Join-Str default parameter set
  • Provision scripts: minor fixes to install scripts

Test plan

  • make lint passes (all pre-commit hooks clean)
  • make test-unit passes (bats + Pester)
  • make test-nix passes (Docker smoke test)
  • CI workflows trigger via PR labels (test:linux, test:macos)
  • Manual test: nix/setup.sh --shell --python on a clean environment

🤖 Generated with Claude Code

@szymonos
szymonos force-pushed the feat/universal-nix-setup branch 5 times, most recently from 8673920 to e13f03c Compare April 18, 2026 14:13
@szymonos
szymonos force-pushed the feat/universal-nix-setup branch from 6e8a83e to 4d792b6 Compare April 19, 2026 06:17
szymonos and others added 4 commits April 19, 2026 21:50
Move check_*, fix_*, and setup_* scripts from .assets/provision/ into
dedicated .assets/check/, .assets/fix/, and .assets/setup/ directories.
Update all path references in Vagrantfiles, Dockerfiles, linux_setup.sh,
and source.sh. Remove obsolete cert-fix and brew/pixi install scripts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…agement

Introduce nix/setup.sh as the primary entry point for all platforms (macOS,
Linux, WSL, containers). Uses a buildEnv flake for user-scope, rootless,
idempotent package management with JSON-driven scope system, dependency
resolution, and install ordering.

Key components:
- Phase library architecture (nix/lib/phases/) with _io_* test stubs
- Scope system (.assets/lib/scopes.sh/json) with dep resolution and sorting
- nx CLI for pin, rollback, scope, overlay, and doctor commands
- Per-scope configure scripts, profile injection, and install records
- Starship and oh-my-posh prompt engine support with mutual exclusivity
- WSL orchestration updates for Nix path integration
- Certificate trust chain support for corporate proxies

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add comprehensive unit tests for the Nix setup system:
- 13 bats test files covering scopes, phases, nx CLI, overlays, profiles
- 9 Pester test files covering PowerShell modules and nx commands
- Pre-commit hooks: check-bash32, validate-scopes, run-bats, run-pester,
  align-tables, gremlins-check (via prek, not pre-commit)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tests

- test_linux.yml: runs nix/setup.sh in daemon and no-daemon (Coder) modes
- test_macos.yml: tests on macOS 14/15 with bash 3.2 and BSD sed
- repo_checks.yml: runs pre-commit hooks via prek
- Docker smoke test images for legacy and nix setup paths
- Makefile targets: lint, test, test-unit, test-nix, test-legacy

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@szymonos
szymonos force-pushed the feat/universal-nix-setup branch from e05b3f1 to 347495f Compare April 19, 2026 19:56
@szymonos szymonos changed the title feat: universal Nix setup with declarative package management and testing feat: universal Nix setup with phase architecture, testing, and CI Apr 19, 2026
szymonos and others added 10 commits April 21, 2026 11:02
build_ca_bundle on macOS silently did nothing when the nix CA bundle
at ~/.nix-profile/etc/ssl/certs/ca-bundle.crt was missing (e.g. nix
profile add failed). Now checks a second nix path and falls back to
exporting system root CAs from macOS Keychain via security command.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
On macOS the Keychain is the authoritative trust store and already
contains corporate/MITM proxy certs (installed by MDM or pkg).
Export all trusted certificates from SystemRootCertificates and
System keychains via `security find-certificate`. This removes the
dependency on cert_intercept and the MITM probe for macOS — the
bundle is always created when build_ca_bundle runs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
On macOS, call build_ca_bundle (Keychain export) unconditionally
before the MITM probe — it doesn't need cert_intercept. Then set
NIX_SSL_CERT_FILE, SSL_CERT_FILE, and git http.sslCAInfo right
away so they're available for git.sh and profiles.zsh. The MITM
probe + cert_intercept now only runs as a fallback when no bundle
exists (Linux, or macOS edge cases).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Profile renderers used `command -v` to detect nix-installed tools, which
fails on fresh macOS where ~/.nix-profile/bin may not be in PATH during
setup. Replaced with `[ -x "$HOME/.nix-profile/bin/<tool>" ]` checks
(matching the approach PowerShell profiles already use successfully).

Moved zsh plugins section before completions in .zshrc block -
zsh-autocomplete calls compinit (which defines compdef), and uv/kubectl/fzf
completions depend on compdef being available.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The guard `[ -z "$BASH_VERSION" ] && return 0` was originally added to
prevent dash (via /etc/profile.d/) from sourcing bash-specific syntax.
In the nix path, these files are only sourced from managed .bashrc/.zshrc
blocks — never from profile.d — so the guard is unnecessary and breaks
all aliases and functions (including nx, devenv, cert_intercept) in zsh.

Removed from: aliases_nix.sh, aliases_git.sh, aliases_kubectl.sh,
functions.sh. Kept in aliases.sh (legacy Linux path, not nix-sourced).

The bash-only completion block in aliases_nix.sh (COMP_WORDS, compgen,
complete) is now wrapped in its own `[ -n "$BASH_VERSION" ]` check.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add executive-focused documentation site using mkdocs-material with
mermaid diagrams, covering architecture, extensibility, platform support,
and enterprise readiness. Includes GitHub Actions workflow for automated
deployment via uv.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add mkdocs-build pre-commit hook to validate documentation builds on
every commit. Add mkdocs-serve Makefile target for local development
with live reload. Move pre-existing docs to docs/legacy/ and remove
them from navigation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Port cspell-cli spell checking and validate-docs-words hooks from
reference repo. Fix letter/digit boundary splitting in tokenizer to
match cspell behavior. Fix three typos caught by cspell in legacy docs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrite index.md with quality proof points and sharper problem framing.
Add design decisions (why Nix, why not golden images, why bash 3.2, why
bootstrapper), quality & testing showcase, enterprise readiness
assessment, corporate proxy handling, and customization guide.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Show three setup paths (WSL via wsl_setup.ps1, macOS with auto Nix
install, Coder/containers with pre-installed Nix) using admonition
tabs instead of a single manual Nix install block.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@szymonos
szymonos force-pushed the feat/universal-nix-setup branch from ee342d0 to 2667565 Compare April 21, 2026 21:32
…edential helper

Request admin:public_key during gh auth login to avoid a second auth
prompt for SSH key registration. Add gh auth setup-git after authentication
to fix git credential issues on macOS with dual gh installs (brew + nix).
Retain scope refresh fallback for users with pre-existing tokens that
lack the scope.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@szymonos
szymonos force-pushed the feat/universal-nix-setup branch from 5186d20 to 5f25953 Compare April 22, 2026 05:22
@szymonos
szymonos force-pushed the feat/universal-nix-setup branch 3 times, most recently from 3c6e33e to 9ee299e Compare April 22, 2026 06:40
@szymonos
szymonos force-pushed the feat/universal-nix-setup branch from 9ee299e to 0043d18 Compare April 22, 2026 06:40
…ions

Split design decisions into high-level architecture choices (Why Nix,
Why not golden images, Why bootstrapper) and implementation decisions
(bash 3.2 compatibility, oh-my-posh/starship vs oh-my-zsh, managed
blocks, phase-based orchestration, JSON shared schema).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
szymonos and others added 5 commits April 22, 2026 09:21
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…e pages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.

1 participant