Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,15 @@ Visit https://www.pgschema.com/installation
> [!NOTE]
> Windows is not supported. Please use WSL (Windows Subsystem for Linux) or a Linux VM.

### Nix (flake)

Comment on lines +104 to +105
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).

```bash
nix build
nix run
```

If the build fails with a `vendorHash` mismatch, update `nix/pgschema.nix` with the hash printed by Nix.

## Getting help

- [Docs](https://www.pgschema.com)
Expand Down
3 changes: 3 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{ pkgs ? import <nixpkgs> {} }:

pkgs.callPackage ./nix/pgschema.nix {}
27 changes: 27 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
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";

};

outputs = { self, nixpkgs }:
let
systems = [
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
];
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f system);
in
{
packages = forAllSystems (system:
let
pkgs = import nixpkgs { inherit system; };
pgschema = pkgs.callPackage ./nix/pgschema.nix {};
in
{
inherit pgschema;
default = pgschema;
});

apps = forAllSystems (system: {
default = {
type = "app";
program = "${self.packages.${system}.pgschema}/bin/pgschema";
};
});
};
}
35 changes: 35 additions & 0 deletions nix/pgschema.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{ pkgs ? import <nixpkgs> {} }:

let
lib = pkgs.lib;
version = lib.strings.removeSuffix "\n" (builtins.readFile ../internal/version/VERSION);
in
pkgs.buildGoModule {
pname = "pgschema";
inherit version;

src = lib.cleanSource ../.;
# 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.

subPackages = [ "." ];
Comment on lines +12 to +14
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

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

The Go toolchain fallback isn’t safe: if pkgs doesn’t provide go_1_24, this expression unconditionally references pkgs.go_1_25, which may not exist in many nixpkgs revisions (especially when using default.nix with an arbitrary <nixpkgs>), causing an evaluation failure. Consider falling back to pkgs.go (or checking pkgs ? go_1_25 as well), and ensure the selected Go version is compatible with go.mod’s go 1.24/toolchain go1.24.7 settings (often also requiring GOTOOLCHAIN=local to prevent network toolchain downloads in sandboxed builds).

Copilot uses AI. Check for mistakes.
proxyVendor = true;
Comment thread
Rooffeell marked this conversation as resolved.

# 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.


env = {
CGO_ENABLED = "0";
};
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

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

buildGoModule runs go test ./... by default, and this repo has many integration tests that start embedded Postgres unless testing.Short() is enabled. In Nix sandbox builds this can be very slow and may fail (e.g., due to embedded-postgres downloading binaries). Consider setting checkFlags = [ "-short" ] (preferred to still run unit tests) or doCheck = false to make nix build reliable.

Suggested change
};
};
# Run Go tests in short mode to avoid slow or flaky integration tests
# (e.g., those that start embedded Postgres) during Nix builds.
checkFlags = [ "-short" ];

Copilot uses AI. Check for mistakes.
ldflags = [
"-s"
"-w"
];
Comment on lines +27 to +34
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}"
];


meta = with lib; {
description = "PostgreSQL schema management tool";
homepage = "https://www.pgschema.com";
license = licenses.asl20;
mainProgram = "pgschema";
platforms = platforms.unix;
};
}
Loading