Skip to content

feat: add Nix flake and package#381

Open
Rooffeell wants to merge 2 commits intopgplex:mainfrom
Rooffeell:codex/nix-package
Open

feat: add Nix flake and package#381
Rooffeell wants to merge 2 commits intopgplex:mainfrom
Rooffeell:codex/nix-package

Conversation

@Rooffeell
Copy link
Copy Markdown

Closes #333

Summary:

  • add flake.nix + default.nix for Nix packaging
  • add nix/pgschema.nix buildGoModule derivation
  • document Nix usage in README

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Mar 27, 2026

Greptile Summary

This PR adds Nix packaging support (flake.nix, default.nix, nix/pgschema.nix) and a brief README section, enabling users to build and run pgschema via nix build / nix run. The overall structure is sound — the flake covers all four major platforms, version is read directly from internal/version/VERSION, and the non-flake default.nix fallback is correct.

Key findings:

  • vendorHash is likely a placeholder (nix/pgschema.nix:18). The inline comment "Replace with the real hash from nix build output" strongly implies the hash was never actually computed against the live dependency set. Because proxyVendor = true requires an exact hash match, nix build will fail immediately for every user until the correct hash is provided. This should be resolved before merging.
  • Go toolchain mismatch: go.mod pins toolchain go1.24.7, but the derivation forces pkgs.go_1_25. Go is backward-compatible so this likely works, but a fallback expression (pkgs.go_1_24 or pkgs.go_1_25) would better respect the upstream toolchain preference.
  • Missing version ldflags: The canonical build (per CLAUDE.md) injects GitCommit and BuildDate. The Nix derivation omits these, so pgschema version will show empty metadata for Nix-built binaries.
  • nixos-unstable input: Pinned in flake.lock today, but future nix flake update calls will roll to the latest unstable commit; a stable channel would be less surprising for maintainers.
  • README nix run example lacks the -- separator needed to pass arguments to pgschema (e.g. nix run . -- plan).

Confidence Score: 4/5

Not safe to merge as-is — nix build will fail for all users until the vendorHash is properly computed.

One P1 issue blocks the primary use-case: the vendorHash in nix/pgschema.nix appears to be an unverified placeholder, meaning nix build will hard-fail immediately. All other findings are P2 style/improvement suggestions that don't affect correctness. Resolving the vendorHash issue would raise this to 5/5.

nix/pgschema.nix — the vendorHash must be computed and verified before the package is usable.

Important Files Changed

Filename Overview
nix/pgschema.nix Core buildGoModule derivation; likely has a placeholder vendorHash that will break nix build, and pins Go 1.25 while go.mod targets 1.24.
flake.nix Well-structured flake supporting four platforms; uses nixos-unstable which is pinned in the lock but could drift on nix flake update.
default.nix Minimal non-flake entry point delegating to nix/pgschema.nix; correct pattern.
flake.lock Auto-generated lock file pinning nixos-unstable to a specific commit; provides reproducibility.
README.md Adds a Nix installation section; the nix run example lacks the -- separator needed to pass arguments to pgschema.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A([User runs nix build / nix run]) --> B{Flake or legacy?}
    B -- flake --> C[flake.nix\nresolves nixpkgs from flake.lock]
    B -- legacy --> D[default.nix\nimports nixpkgs from channel]
    C --> E[callPackage ./nix/pgschema.nix]
    D --> E
    E --> F[Read internal/version/VERSION\nfor version string]
    E --> G[lib.cleanSource ..\nfilters repo source]
    F --> H[buildGoModule]
    G --> H
    H --> I{proxyVendor = true\nFetch Go modules via proxy}
    I --> J{Verify vendorHash}
    J -- hash matches --> K[go build -ldflags '-s -w'\noutput: bin/pgschema]
    J -- hash mismatch --> L([Build fails ❌\nnix prints correct hash])
    K --> M([result/bin/pgschema ✅])
Loading

Reviews (1): Last reviewed commit: "feat: add nix flake/package" | Re-trigger Greptile

nix/pgschema.nix Outdated
Comment on lines +17 to +18
# Replace with the real hash from `nix build` output.
vendorHash = "sha256-3nV7AEsWyEvIbxHetoEsA8PPXJ6ENvU/sz7Wn5aysss=";
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 Unverified placeholder vendorHash will break the build

The inline comment — "Replace with the real hash from nix build output" — strongly indicates this hash was never actually computed from the live dependency set. With proxyVendor = true, Nix fetches all Go modules from the proxy and checks them against vendorHash; a wrong hash causes an immediate, hard build failure:

error: hash mismatch in fixed-output derivation
  wanted: sha256-3nV7AEsWyEvIbxHetoEsA8PPXJ6ENvU/sz7Wn5aysss=
     got: sha256-<actual>

The standard Nix workflow is to set vendorHash = lib.fakeHash; (or ""), run nix build, then replace it with the hash printed in the error. That step appears not to have been done here, so nix build will fail out of the box for every user.

nix/pgschema.nix Outdated
Comment on lines +12 to +13
# go_1_24 is not available in some nixpkgs revisions; use the closest newer toolchain.
go = pkgs.go_1_25;
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 Go toolchain version overrides go.mod toolchain directive

go.mod declares go 1.24.0 (minimum) and toolchain go1.24.7 (preferred). Pinning go = pkgs.go_1_25 overrides that toolchain directive entirely. Go 1.25 is backward-compatible, so this won't break compilation in practice, but it silently ignores the upstream-pinned toolchain.

A more future-proof option is to omit the go attribute entirely and let buildGoModule use nixpkgs' default Go toolchain, or check for pkgs.go_1_24 first:

  go = pkgs.go_1_24 or pkgs.go_1_25;

This way the derivation respects the author-specified toolchain when available and only falls back when it isn't.

Comment on lines +23 to +26
ldflags = [
"-s"
"-w"
];
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 Missing version-injection ldflags

According to CLAUDE.md, the canonical build injects GitCommit and BuildDate into the binary:

-X github.com/pgplex/pgschema/cmd.GitCommit=...
-X 'github.com/pgplex/pgschema/cmd.BuildDate=...'

The Nix derivation only passes -s -w. As a result, pgschema version (or any version display) will show empty values for commit and build date. Nix exposes the revision via self.rev (or self.shortRev) in the flake, which can be threaded through to the derivation, e.g.:

# In flake.nix, pass rev to the package:
pgschema = pkgs.callPackage ./nix/pgschema.nix { rev = self.shortRev or "dirty"; };

# In nix/pgschema.nix, receive and use it:
{ pkgs ? import <nixpkgs> {}, rev ? "unknown" }:
...
ldflags = [
  "-s" "-w"
  "-X github.com/pgplex/pgschema/cmd.GitCommit=${rev}"
];

flake.nix Outdated
description = "pgschema";

inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
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 Tracking nixos-unstable may cause silent regressions on nix flake update

The lock file pins the flake to a specific nixos-unstable commit today, so the build is reproducible now. However, every nix flake update will roll to the latest nixos-unstable, which can change the Go toolchain, library versions, or even remove go_1_25, causing unexpected build breaks for downstream users.

Consider targeting a stable channel (nixos-24.11 or nixos-25.05) in the inputs URL to make future updates more predictable:

Suggested change
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-25.05";

Comment on lines +104 to +105
### Nix (flake)

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 nix run without argument separator won't forward CLI flags

nix run by itself runs the binary with no arguments. To pass arguments to pgschema (e.g. pgschema plan), users need to separate nix flags from program flags with --. The example could be more helpful:

Suggested change
### Nix (flake)
nix run . -- plan

or at minimum a note like:

Use nix run . -- <pgschema args> to pass arguments to the binary (e.g. nix run . -- plan).

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.

Add pgschema to nix package

1 participant