Files
pad/nix/package.nix
T
xarmian 0900be6241 chore(deps): bump golang.org/x/crypto to v0.56.0 (BUG-2851)
Two advisories published 2026-09-02 19:12Z (GO-2026-6354, GO-2026-6355; DoS in golang.org/x/crypto/ssh, fixed in v0.56.0) made govulncheck fail the Nix job on runners whose vulnerability database had them — intermittently across runners, not as a threshold: main at 704ba874 and a PR tip based on it passed while another failed on an identical dependency tree, four minutes apart. x/crypto/ssh is not linked into pad (go list -deps ./cmd/pad shows no crypto/ssh; go mod why: bcrypt), so this is a CI unblock, not an exposure. The bump beats an accepted-advisories entry: an exception would encode "not linked today" as permanent and would sit beside a check that disagrees with itself.

go.mod one line, go.sum two lines, nix/package.nix vendorHash one line. No nix on the build box, so the hash was lifted from CI's own mismatch on a lib.fakeHash placeholder, which is why it is a build-sourced value and not a guess:

    specified: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
       got:    sha256-8L7gH7Yy5+Fig3wK2SPLYSJjcY9nF/jumQ7PATJ3RIE=

Squashed so the placeholder commit (fails to build by design) never enters main's history. Gates on the tip: Nix green, Go suite green on SQLite and Postgres uncached (PG legs verified by timing), lint 0, vet clean; CI 7/7 on 51a0efd2.

Claude-Session: https://claude.ai/code/session_01TkxKnJpLgk5UxKS8T896dk
2026-09-02 16:52:22 -04:00

117 lines
3.5 KiB
Nix

{
lib,
stdenv,
buildGoModule,
go_1_26,
nodejs_24,
importNpmLock,
}:
let
version = "0.15.0";
src = lib.fileset.toSource {
root = ../.;
fileset = lib.fileset.gitTracked ../.;
};
# SvelteKit static build (web/build) that gets embedded into the Go
# binary via `//go:embed all:web/build` in embed.go. Built separately
# so the Go derivation only needs a file copy, not a Node toolchain.
# Uses importNpmLock (per-package fetchurl against web/package-lock.json's
# own integrity hashes) rather than buildNpmPackage's npmDepsHash, so npm
# dependency updates never require discovering/updating a separate hash.
webUI = stdenv.mkDerivation {
pname = "pad-web";
inherit version src;
sourceRoot = "source/web";
nativeBuildInputs = [
nodejs_24
importNpmLock.hooks.linkNodeModulesHook
];
npmDeps = importNpmLock.buildNodeModules {
npmRoot = ../web;
nodejs = nodejs_24;
};
buildPhase = ''
runHook preBuild
# Without sandboxing, npm would otherwise write its cache to the
# real $HOME Nix sets for purity-checking (which must stay absent
# between derivations); keep it inside this build's own tmpdir.
export HOME="$TMPDIR"
npm run build
runHook postBuild
'';
installPhase = ''
runHook preInstall
cp -r build $out
runHook postInstall
'';
};
in
buildGoModule {
pname = "pad";
inherit version src;
go = go_1_26;
# Update alongside go.sum. Regenerate via:
# nix build .#default 2>&1 | grep -A2 'got:'
vendorHash = "sha256-8L7gH7Yy5+Fig3wK2SPLYSJjcY9nF/jumQ7PATJ3RIE=";
subPackages = [ "cmd/pad" ];
# subPackages also narrows buildGoModule's default checkPhase to just
# cmd/pad; override it to run the full `go test ./...` (matching CI),
# since cmd/loadtest-collab is an unrelated dev tool we don't ship.
checkPhase = ''
runHook preCheck
# Match buildGoModule's default checkPhase: don't trim source paths
# for tests, since some (e.g. invocation_framing_test.go) locate the
# repo root via runtime.Caller.
export GOFLAGS=''${GOFLAGS//-trimpath/}
# ValidateWebhookURL does a real net.LookupIP as an SSRF guard;
# these four subtests exercise that path against example.com, which
# needs DNS/network the Nix build sandbox deliberately doesn't have.
# Everything else in the package (invalid schemes, private-IP
# rejection, etc.) needs no network and still runs.
# -timeout is explicit for the same reason as CI and the Makefile: the
# 10m default is a budget nobody chose (TASK-2545). This runs in the
# Nix sandbox via .github/workflows/nix.yml.
go test -timeout=45m -skip 'TestValidateWebhookURL/valid_(https|http|with_port|with_path)$' ./...
runHook postCheck
'';
# Populate web/build with the real SvelteKit output before `go build`
# runs, so `//go:embed all:web/build` in embed.go has real files to
# embed. postPatch runs after patchPhase, before configure/build.
postPatch = ''
rm -rf web/build
cp -r ${webUI} web/build
'';
env.CGO_ENABLED = 0;
ldflags = [
"-s"
"-w"
"-X main.version=${version}"
];
doCheck = true;
meta = {
description = "Local-first project management for developers and AI agents";
homepage = "https://github.com/PerpetualSoftware/pad";
changelog = "https://github.com/PerpetualSoftware/pad/releases/tag/v${version}";
license = lib.licenses.asl20;
mainProgram = "pad";
platforms = lib.platforms.unix;
maintainers = [ ];
};
}