I have a derivation using buildGoModule
and a go program that depends on a private repository.
There is a similar discussion from 2019 here: git/buildGoModule + private repositories - #7 by tomberek
The setup is that my go project includes a private repo. This can be directly in the source (import (github.com/TomMD/privatething)
) or indirectly in the go.mod (replace ( github.com/a/b => github.com/TomMD/b-but-private)
).
Ultimately when you build, such as with a default.nix like:
{ pkgs ? import (fetchTarball {url="https://github.com/NixOS/nixpkgs/archive/e9b8b78affb3e881e33680acfd999697493fd38a.tar.gz"; sha256="0vrawckd3khx6rx1sgybppfnrgmsq6d1m7k7jyfw9nakmixxgq7a";}) {}
, gitignoreSourcePure ? pkgs.nix-gitignore.gitignoreSourcePure
}:
pkgs.buildGoModule rec {
pname = "hello";
version = "1";
src = gitignoreSourcePure [ ] ./.;
buildInputs = with pkgs; [
openssh
];
vendorSha256 = pkgs.lib.fakeSha256;
proxyVendor = true;
doCheck = false;
preCheck = ''
export PATH="${pkgs.lib.makeBinPath [ pkgs.openssh ]}:$PATH"
'';
meta = with pkgs.lib; {
description = "Hello";
homepage = src.meta.homepage;
platforms = platforms.linux ++ platforms.darwin;
};
}
The result is unsurprising because it is using unauthenticated HTTP:
go: github.com/foo/bar@v0.19.1: reading github.com/TomMD/resume/go.mod at revision v0.19.1: git ls-remote -q origin in /private/tmp/nix-build-hello-1-go-modules.drv-0/go/pkg/mod/cache/vcs/f0af8278e5b83502c71826605ec31c65511d4081781b022c6c53a17aec908942: exit status 128:
fatal: could not read Username for 'https://github.com': terminal prompts disabled
EDIT: Submitted too soon.
The linked discussion has some suggestions. We can try them. First we tell git to use ssh instead of http second we educate the sandbox about the known_hosts:
{ pkgs ? import (fetchTarball {url="https://github.com/NixOS/nixpkgs/archive/e9b8b78affb3e881e33680acfd999697493fd38a.tar.gz"; sha256="0vrawckd3khx6rx1sgybppfnrgmsq6d1m7k7jyfw9nakmixxgq7a";}) {}
, gitignoreSourcePure ? pkgs.nix-gitignore.gitignoreSourcePure
}:
pkgs.buildGoModule rec {
pname = "hello";
version = "1";
src = gitignoreSourcePure [ ] ./.;
buildInputs = with pkgs; [
openssh
];
vendorSha256 = pkgs.lib.fakeSha256;
proxyVendor = false;
overrideModAttrs = old: {
preBuild = ''
export HOME=$(pwd)
cat <<EOF > $HOME/.gitconfig
[url "git@github.com:TomMD"]
insteadOf = "https://github.com/TomMD"
EOF
mkdir ~/.ssh
chmod 700 ~/.ssh
cat <<EOF >~/.ssh/known_hosts
github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl
EOF
chmod 644 ~/.ssh/known_hosts
export GIT_SSH_COMMAND="${pkgs.openssh}/bin/ssh -o UserKnownHostsFile=$HOME/.ssh/known_hosts"
'';
impureEnvVars = pkgs.lib.fetchers.proxyImpureEnvVars ++ [ "SSH_AUTH_SOCK" ];
};
doCheck = false;
meta = with pkgs.lib; {
description = "Hello";
homepage = src.meta.homepage;
platforms = platforms.linux ++ platforms.darwin;
};
}
This gets us much of the way, ssh doesn’t object to the host SSH key and it tries to pull from the correct repo. nix-build
fails with:
go: errors parsing go.mod:
/private/tmp/nix-build-hello-1-go-modules.drv-0/go-hello-world/go.mod:6:2: replace github.com/TomMD/go-git: git ls-remote -q origin in /private/tmp/nix-build-hello-1-go-modules.drv-0/go/pkg/mod/cache/vcs/24658a01e857650bb9f5c0bd2b11fcf9feb3612f395da37911296c9feb0445d5: exit status 128:
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.
Now in the prior (linked) conversation this is where ssh-agent was hinted at with an impure of SSH_AUTH_SOCK. That doesn’t work and certainly shouldn’t since the socket file isn’t available in the build sandbox. What’s the solution here?