Skip to content

feat: add Nix flake for installation via nix run/profile install#2279

Open
levonk wants to merge 1 commit into
j178:masterfrom
levonk:feat-nix-package-manager-install
Open

feat: add Nix flake for installation via nix run/profile install#2279
levonk wants to merge 1 commit into
j178:masterfrom
levonk:feat-nix-package-manager-install

Conversation

@levonk

@levonk levonk commented Jun 30, 2026

Copy link
Copy Markdown

What

Adds a flake.nix so prek can be installed and run directly from GitHub at the latest release:

nix run github:j178/prek
nix profile install github:j178/prek

The flake tracks master and is auto-bumped to the latest release by a daily workflow, so github:j178/prek always serves the current release.

Addressing the maintenance concern (re: #2260)

@j178's objection to #2260 was that it added per-release maintenance — every release would need version and four sha256 hashes updated by hand, with no automation. This PR adds that automation.

New in this PR: .github/workflows/nix-release.yml — a GitHub Action that:

  1. Runs daily (and on manual workflow_dispatch) and compares flake.nix's pinned version to the latest GitHub release.
  2. When they differ, prefetches each platform asset's SRI hash via nix store prefetch-file --json --hash-type sha256.
  3. Rewrites version and the per-platform file/sha256 in flake.nix with an inline Python script.
  4. Opens a PR (chore(nix): bump flake to vX.Y.Z) with the 5-line diff.

The maintainer cuts a release exactly as today; within 24h the workflow opens a PR with the bumped flake.nix. Reviewing a 5-line diff (version + 4 hashes) needs no Nix knowledge. Merge → nix run github:j178/prek serves the new release. Zero manual flake editing, zero Nix knowledge required.

Why scheduled, not release: published

prek's releases are created with secrets.GITHUB_TOKEN (.github/workflows/release.yml, line 267/299 — gh release create with GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}). GitHub deliberately does not start new workflow runs from events authored by GITHUB_TOKEN (to prevent recursive loops), so a release: published trigger would silently never fire. A daily lag-check is fully decoupled from how releases are created, needs no PAT, and requires no edits to the cargo-dist release pipeline. It also self-heals: if a run is missed, the next day's run catches up.

The ASSET_MAP is the only project-specific input (four system|asset-substring lines). Sibling .sha256 checksum files are filtered out automatically so substrings match the tarball, not its checksum companion.

Why no tag-pinning (github:j178/prek/vX.Y.Z)

Release tags are cut by cargo-dist before the lag-check workflow bumps flake.nix on master. So a tag ref either lacks the flake entirely (tags before this PR merges) or contains the previous version's hashes (tags after merge, since the tag captures master before the bump PR lands). Tag-pinning is fundamentally incompatible with a post-release bump workflow. The flake serves the current release via github:j178/prek (tracks master, always has the latest bumped version). For reproducibility, pin to a specific commit SHA after a bump PR merges, or use the nixpkgs package.

Why

prek is already packaged in nixpkgs, but the nixpkgs unstable channel lags behind upstream releases (currently shipping 0.3.11 vs the latest 0.4.5). A flake in this repo gives users the current release directly from GitHub without waiting for nixpkgs to catch up, and provides:

  • One-command install / runnix run github:j178/prek with no clone or manual build steps.
  • Pure / Hermetic builds — every input (the prebuilt binary, glibc/libiconv) is pinned in flake.lock. If it builds today, it builds in ten years.
  • Reproducible — the exact same derivation always produces the exact same output bit-for-bit. No "works on my machine."
  • Idempotent installs — running nix profile install twice is a no-op.
  • Rollback-ablenix profile rollback restores the previous profile generation instantly.
  • Cross-platform — same invocation on macOS (Apple Silicon & Intel) and Linux. The flake handles platform-specific linking.
  • Atomic upgrades / downgrades — profiles are switched atomically. No half-upgraded state.
  • Clean uninstallnix profile remove leaves no residue.

Changes

  • flake.nix: Nix flake wrapping the v0.4.5 prebuilt release tarball as packages.<system>.default and apps.<system>.default for x86_64/aarch64 linux+darwin. Uses autoPatchelfHook on Linux for glibc linking.
  • flake.lock: pinned nixpkgs-unstable input.
  • .github/workflows/nix-release.yml: scheduled lag-check automation that auto-bumps version + per-platform sha256 hashes and opens a PR when flake.nix falls behind the latest release — no manual flake maintenance, no PAT, no release-pipeline edits.
  • .gitignore: added /result and /result-* Nix build symlinks.
  • README.md: extended the existing Nix install section (<!-- --8<-- [start: nix-install] -->) with flake-based install/run commands alongside the existing nixpkgs path. docs/installation.md picks this up automatically via its --8<-- "README.md:nix-install" include.

Testing

Verified locally on x86_64-darwin:

nix flake check --no-build   # passed
nix build .                  # passed
result/bin/prek --version    # prek 0.4.5 (bb3108283 2026-06-15)
nix run . -- --help          # passed

The workflow YAML validates and its lag-check logic was dry-run against the actual v0.4.5 release: version comparison and asset-substring matching (with .sha256 filtering) confirmed for all four systems. The workflow correctly reports "up to date" when flake.nix matches the latest release, and would set LAGGING=yes + open a PR when they diverge.

No source files in crates/ are touched — the diff is flake.nix, flake.lock, .github/workflows/nix-release.yml, .gitignore, and a README snippet, so the existing test suite is unaffected.

Notes

  • The flake wraps the prebuilt release tarball (preferred path per the upstream release artifacts) rather than building from source, so it stays in sync with cargo-dist releases and avoids a full Rust toolchain in the closure.
  • Only the 4 standard Nix systems are exposed; upstream also ships musl/arm/armv7/riscv64/s390x tarballs but those map to no stdenv system. To expose more, add entries to assets in flake.nix and a matching line to the workflow's ASSET_MAP.
  • Actions are pinned to commit SHAs to match the repo's existing workflow conventions.
  • PRs opened by GITHUB_TOKEN do not trigger downstream CI workflows; the bump PR is a 5-line hash change with no source impact, safe to merge without checks.
  • No breaking changes to existing build paths.

Scope

The PR scope is well-contained — additive only, no existing functionality affected.

Related

Supersedes #2260 (closed) — adds the release-triggered hash automation that was missing there.

@codecov

codecov Bot commented Jun 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.10%. Comparing base (b0f9261) to head (c907568).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2279      +/-   ##
==========================================
- Coverage   93.11%   93.10%   -0.01%     
==========================================
  Files         127      127              
  Lines       27991    27991              
==========================================
- Hits        26063    26062       -1     
- Misses       1928     1929       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f305efa94c

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread .github/workflows/nix-release.yml Outdated
Comment on lines +4 to +5
release:
types: [published]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Trigger the flake bump without GITHUB_TOKEN-created releases

In the existing release workflow I checked, .github/workflows/release.yml creates releases with GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} and gh release create (lines 266-299). GitHub does not start new workflow runs from most events created by GITHUB_TOKEN, including release, so this release: published workflow will not run for normal project releases and the promised flake bump PR will never be opened. Use a PAT/GitHub App token for release creation or invoke this workflow via workflow_call/workflow_dispatch from the release pipeline.

Useful? React with 👍 / 👎.

Comment thread README.md Outdated
nix profile install github:j178/prek

# Pin a specific release
nix run github:j178/prek/v0.4.5

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove tag-pinning example that cannot work

This command pins to the repository contents at tag v0.4.5, but that tag was cut before this flake existed, so it will fail to find a flake. The same problem persists for future tags under the added post-release bump workflow: a release tag captures whatever flake.nix existed before the workflow updates main, so github:j178/prek/vX.Y.Z will either lack the flake or run the previous version rather than the pinned release.

Useful? React with 👍 / 👎.

@levonk levonk force-pushed the feat-nix-package-manager-install branch from f305efa to d4c4c2a Compare June 30, 2026 20:47

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d4c4c2a847

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

echo "TAG=$tag" >> "$GITHUB_ENV"
python3 <<'PYEOF'
import json, os, re, subprocess, urllib.request
tag = os.environ["TAG"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Export TAG before reading it in the same step

When flake.nix lags behind a release, this Python block runs in the same run: step that only appended TAG=$tag to $GITHUB_ENV. GitHub makes $GITHUB_ENV entries available to subsequent steps, not to processes already running in the current step, so os.environ["TAG"] raises KeyError before any hashes are prefetched or PR is opened. Export TAG in the shell before invoking Python, or pass it via the step env.

Useful? React with 👍 / 👎.

@levonk levonk force-pushed the feat-nix-package-manager-install branch from d4c4c2a to 00e6128 Compare June 30, 2026 20:57
Exposes the latest prebuilt release tarball as `packages.<system>.default`
and `apps.<system>.default` for x86_64/aarch64 linux and darwin, so users
can `nix run github:j178/prek` for the current release instead of waiting
for nixpkgs (currently lagging at 0.3.11). README Nix section updated with
flake instructions alongside the existing nixpkgs path.

Includes `.github/workflows/nix-release.yml`, a scheduled lag-check GitHub
Action that compares `flake.nix`'s pinned `version` to the latest GitHub
release daily; when they differ it prefetches the new per-platform SRI
hashes via `nix store prefetch-file`, rewrites `flake.nix`, and opens a PR
— so maintaining the flake needs zero Nix knowledge and no per-release
manual editing.

Scheduled (not `release: published`) because prek's releases are created
with `secrets.GITHUB_TOKEN`, and GitHub does not start new workflow runs
from `GITHUB_TOKEN`-authored events — a `release: published` trigger would
silently never fire. The daily lag-check is fully decoupled from how
releases are created and needs no PAT.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@levonk levonk force-pushed the feat-nix-package-manager-install branch from 00e6128 to c907568 Compare June 30, 2026 21:21
@j178

j178 commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Thanks for putting this together. I'm open to adding a flake.nix to this repo. But I still need more time to get familiar enough with Nix and this workflow before I can responsibly merge and maintain it, so I won't merge it immediately. I'll keep this open while I review it.

@levonk

levonk commented Jul 2, 2026

Copy link
Copy Markdown
Author

Thanks for your contribution to making this open source and consideration for the patch.

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.

2 participants