-
Notifications
You must be signed in to change notification settings - Fork 1.3k
feat: add nix flake support (sorry for this duplicate) #459
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
09d39d6
add nix flake support
mipmip 5d123ce
feat: add Nix flake maintenance automation
mipmip d316390
Add Nix Flake CI Validation
mipmip 13cb91d
Merge branch 'main' into main
TabishB 23b9067
fix updatescript, update flake
mipmip 8437f57
make update-script compatible with macos
mipmip File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| -P ubuntu-latest=catthehacker/ubuntu:act-latest |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| # Github Workflows | ||
|
|
||
| ## Testing CI Locally | ||
|
|
||
| Test GitHub Actions workflows locally using [act](https://nektosact.com/): | ||
|
|
||
| ```bash | ||
| # Test all PR checks | ||
| act pull_request | ||
|
|
||
| # Test specific job | ||
| act pull_request -j nix-flake-validate | ||
|
|
||
| # Dry run to see what would execute | ||
| act pull_request --dryrun | ||
| ``` | ||
|
|
||
| The `.actrc` file configures act to use the appropriate Docker image. | ||
|
|
||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -148,3 +148,4 @@ CLAUDE.md | |
|
|
||
| # Pnpm | ||
| .pnpm-store/ | ||
| result | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,87 @@ | ||
| { | ||
| description = "OpenSpec - AI-native system for spec-driven development"; | ||
|
|
||
| inputs = { | ||
| nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; | ||
| }; | ||
|
|
||
| outputs = { self, nixpkgs }: | ||
| let | ||
| supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; | ||
|
|
||
| forAllSystems = f: nixpkgs.lib.genAttrs supportedSystems (system: f system); | ||
| in | ||
| { | ||
| packages = forAllSystems (system: | ||
| let | ||
| pkgs = nixpkgs.legacyPackages.${system}; | ||
| in | ||
| { | ||
| default = pkgs.stdenv.mkDerivation (finalAttrs: { | ||
| pname = "openspec"; | ||
| version = "0.20.0"; | ||
|
|
||
| src = ./.; | ||
|
|
||
| pnpmDeps = pkgs.fetchPnpmDeps { | ||
| inherit (finalAttrs) pname version src; | ||
| pnpm = pkgs.pnpm_9; | ||
| fetcherVersion = 3; | ||
| hash = "sha256-m/7IdY1ou9ljjYAcx3W8AyEJvIZfCBWIWxproQ/INPA="; | ||
| }; | ||
|
|
||
| nativeBuildInputs = with pkgs; [ | ||
| nodejs_20 | ||
| npmHooks.npmInstallHook | ||
| pnpmConfigHook | ||
| pnpm_9 | ||
| ]; | ||
|
|
||
| buildPhase = '' | ||
| runHook preBuild | ||
|
|
||
| pnpm run build | ||
|
|
||
| runHook postBuild | ||
| ''; | ||
|
|
||
| dontNpmPrune = true; | ||
|
|
||
| meta = with pkgs.lib; { | ||
| description = "AI-native system for spec-driven development"; | ||
| homepage = "https://github.com/Fission-AI/OpenSpec"; | ||
| license = licenses.mit; | ||
| maintainers = [ ]; | ||
| mainProgram = "openspec"; | ||
| }; | ||
| }); | ||
| }); | ||
|
|
||
| apps = forAllSystems (system: { | ||
| default = { | ||
| type = "app"; | ||
| program = "${self.packages.${system}.default}/bin/openspec"; | ||
| }; | ||
| }); | ||
|
|
||
| devShells = forAllSystems (system: | ||
| let | ||
| pkgs = nixpkgs.legacyPackages.${system}; | ||
| in | ||
| { | ||
| default = pkgs.mkShell { | ||
| buildInputs = with pkgs; [ | ||
| nodejs_20 | ||
| pnpm_9 | ||
| ]; | ||
|
|
||
| shellHook = '' | ||
| echo "OpenSpec development environment" | ||
| echo "Node version: $(node --version)" | ||
| echo "pnpm version: $(pnpm --version)" | ||
| echo "Run 'pnpm install' to install dependencies" | ||
| ''; | ||
| }; | ||
| }); | ||
| }; | ||
| } |
2 changes: 2 additions & 0 deletions
2
openspec/changes/archive/2026-01-07-add-nix-flake-support/.openspec.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| schema: spec-driven | ||
| created: 2026-01-07 |
94 changes: 94 additions & 0 deletions
94
openspec/changes/archive/2026-01-07-add-nix-flake-support/design.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| ## Context | ||
|
|
||
| OpenSpec is a TypeScript CLI tool using pnpm for dependency management. The project requires Node.js ≥20.19.0. Nix uses its own build system that needs to understand how to fetch dependencies and build the project reproducibly. | ||
|
|
||
| The Nix ecosystem has specific patterns for packaging Node.js/pnpm projects that differ from the traditional npm ecosystem. | ||
|
|
||
| ## Goals | ||
|
|
||
| - Enable OpenSpec to be run directly via `nix run github:Fission-AI/OpenSpec` | ||
| - Support all major platforms (Linux x86/ARM, macOS x86/ARM) | ||
| - Use existing pnpm-lock.yaml for reproducible builds | ||
| - Provide development environment for Nix users | ||
|
|
||
| ## Non-Goals | ||
|
|
||
| - Replace existing npm/pnpm publishing workflow | ||
| - Publish to nixpkgs (can be done later as separate effort) | ||
| - Support Windows (Nix doesn't run natively on Windows) | ||
|
|
||
| ## Decisions | ||
|
|
||
| ### Use stdenv.mkDerivation instead of buildNpmPackage | ||
|
|
||
| **Decision**: Package OpenSpec using `stdenv.mkDerivation` with pnpm hooks. | ||
|
|
||
| **Rationale**: The zigbee2mqtt package in nixpkgs demonstrates the current best practice for pnpm projects. Using `buildNpmPackage` with pnpm requires complex configuration, while `mkDerivation` with the right hooks is more straightforward and better supported. | ||
|
|
||
| **Alternative considered**: Using `buildNpmPackage` with `npmConfigHook = pkgs.pnpmConfigHook` - this is the older pattern and causes issues with dependency fetching. | ||
|
|
||
| ### Use fetchPnpmDeps with explicit pnpm version | ||
|
|
||
| **Decision**: Use `pkgs.fetchPnpmDeps` with `pnpm = pkgs.pnpm_9` and `fetcherVersion = 3`. | ||
|
|
||
| **Rationale**: | ||
| - pnpm lockfile version 9.0 requires fetcherVersion 3 | ||
| - Explicit pnpm_9 ensures consistency between fetch and build | ||
| - This is the documented way to handle pnpm projects in nixpkgs | ||
|
|
||
| ### Multi-platform support without flake-utils | ||
|
|
||
| **Decision**: Implement multi-platform support using plain Nix with `nixpkgs.lib.genAttrs`. | ||
|
|
||
| **Rationale**: Per user request, avoid extra dependencies. The `genAttrs` pattern is simple and well-understood in the Nix community. | ||
|
|
||
| ### Node.js 20 instead of latest | ||
|
|
||
| **Decision**: Pin to nodejs_20 to match package.json engines requirement. | ||
|
|
||
| **Rationale**: Ensures consistency with development environment and npm package requirements. Avoids potential compatibility issues with newer Node versions. | ||
|
|
||
| ## Key Implementation Details | ||
|
|
||
| ### Dependency Hash Management | ||
|
|
||
| The `pnpmDeps.hash` field must be updated whenever dependencies change. The workflow: | ||
| 1. Set hash to fake value (all zeros) | ||
| 2. Run `nix build` | ||
| 3. Nix fails with actual hash | ||
| 4. Update flake.nix with correct hash | ||
|
|
||
| This is standard Nix workflow for fixed-output derivations. | ||
|
|
||
| ### Build Inputs | ||
|
|
||
| Required nativeBuildInputs: | ||
| - `nodejs_20` - runtime | ||
| - `npmHooks.npmInstallHook` - handles installation phase | ||
| - `pnpmConfigHook` - configures pnpm environment | ||
| - `pnpm_9` - pnpm executable | ||
|
|
||
| The `dontNpmPrune = true` is important to keep all dependencies after build. | ||
|
|
||
| ## Risks / Trade-offs | ||
|
|
||
| **[Risk]** Hash needs updating when dependencies change → **Mitigation**: Document this clearly; error message from Nix provides correct hash | ||
|
|
||
| **[Risk]** Nix builds might lag behind npm releases → **Mitigation**: This is fine; Nix users can still use npm if they need bleeding edge | ||
|
|
||
| **[Trade-off]** Additional maintenance burden for hash updates → **Benefit**: Better experience for Nix ecosystem users | ||
|
|
||
| ## Migration Plan | ||
|
|
||
| 1. Add flake.nix to repository | ||
| 2. Test builds on multiple platforms (can use GitHub Actions with Nix) | ||
| 3. Update README with Nix installation instructions | ||
| 4. Optionally add to CI pipeline to catch hash mismatches early | ||
|
|
||
| No breaking changes - this is purely additive. | ||
|
|
||
| ## Open Questions | ||
|
|
||
| - Should we add automatic hash updating to CI? (Could use nix-update-script) | ||
| - Should we submit to nixpkgs after validation? (Separate decision) | ||
| - Do we want to support older Node versions in flake? (Probably no - stick to package.json requirement) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: Fission-AI/OpenSpec
Length of output: 2736
🏁 Script executed:
Repository: Fission-AI/OpenSpec
Length of output: 1512
🏁 Script executed:
Repository: Fission-AI/OpenSpec
Length of output: 233
🏁 Script executed:
Repository: Fission-AI/OpenSpec
Length of output: 142
🏁 Script executed:
Repository: Fission-AI/OpenSpec
Length of output: 45
🏁 Script executed:
Repository: Fission-AI/OpenSpec
Length of output: 45
🏁 Script executed:
Repository: Fission-AI/OpenSpec
Length of output: 1198
Use proper markdown headings instead of bold text to maintain document hierarchy.
Lines 143 and 154 should use h5 headings (
#####) rather than bold emphasis, as they represent subsections under "Step 1: Install the CLI globally" (which is h4). Using proper headings improves semantic structure, accessibility, and automated document processing.📝 Proposed fix
Apply the same fix to line 154:
📝 Committable suggestion
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
143-143: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
🤖 Prompt for AI Agents