Skip to content

[nix] Enable binary and image build #3731

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 5 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ jobs:
go generate -run "go.uber.org/mock/mockgen" ./...
.github/workflows/check-clean-branch.sh
go_mod_tidy:
name: Up-to-date go.mod and go.sum
name: Up-to-date go.mod and go.sum and gomod2nix.toml
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -188,6 +188,10 @@ jobs:
run: go mod tidy
- shell: bash
run: .github/workflows/check-clean-branch.sh
- shell: bash
run: ./scripts/gomod2nix_gen.sh
- shell: bash
run: .github/workflows/check-clean-branch.sh
test_build_image:
name: Image build
runs-on: ubuntu-latest
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,6 @@ vendor
**/testdata

.direnv

# Nix output dir
result
21 changes: 21 additions & 0 deletions container.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{ pkgs, package, rev }:

pkgs.dockerTools.buildImage {
name = "avalanchego";
# TODO(marun) This should be the commit hash
tag = rev;
created = "now";
copyToRoot = pkgs.buildEnv {
name = "image-root";
paths = [
# Ensure the binary is in the expected path
(pkgs.runCommand "copy-binary" {} ''
mkdir -p $out/build/avalanchego
cp ${package}/bin/avalanchego $out/build/avalanchego/
'')
package
];
pathsToLink = [ "/build" ];
};
config.Cmd = [ "/build/avalanchego/avalanchego" ];
}
40 changes: 40 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{ pkgs ? (
let
inherit (builtins) fetchTree fromJSON readFile;
inherit ((fromJSON (readFile ./flake.lock)).nodes) nixpkgs gomod2nix;
in
import (fetchTree nixpkgs.locked) {
overlays = [
(import "${fetchTree gomod2nix.locked}/overlay.nix")
];
}
)
, buildGoApplication ? pkgs.buildGoApplication
, go ? pkgs.go
, rev
}:

buildGoApplication {
pname = "avalanchego";
version = "1.12.2";
src = ./.;
pwd = ./.;
modules = ./gomod2nix.toml;

doCheck = false;

go = go;

CGO_ENABLED = "1";

AVALANCHEGO_COMMIT = rev;
buildPhase = ''
bash -x ./scripts/build_avalanche.sh
'';

# Install the binary from where the build script places it
installPhase = ''
mkdir -p $out/bin
mv build/avalanchego $out/bin/
'';
}
59 changes: 59 additions & 0 deletions flake.lock

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

165 changes: 109 additions & 56 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4,72 +4,125 @@
# - run `nix develop` or use direnv (https://direnv.net/)
# - for quieter direnv output, set `export DIRENV_LOG_FORMAT=`

description = "AvalancheGo development environment";
description = "Go implementation of an Avalanche node";

# Flake inputs
inputs = {
nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.2405.*.tar.gz";
flake-utils.url = "github:numtide/flake-utils";
gomod2nix = {
url = "github:maru-ava/gomod2nix?ref=cc78df101c18e6687f4e7e9d41b2d8c8d070cdb0";
inputs = {
nixpkgs.follows = "nixpkgs";
flake-utils.follows = "flake-utils";
};
};
};

# Flake outputs
outputs = { self, nixpkgs }:
let
# Systems supported
allSystems = [
"x86_64-linux" # 64-bit Intel/AMD Linux
"aarch64-linux" # 64-bit ARM Linux
"x86_64-darwin" # 64-bit Intel macOS
"aarch64-darwin" # 64-bit ARM macOS
];

# Helper to provide system-specific attributes
forAllSystems = f: nixpkgs.lib.genAttrs allSystems (system: f {
pkgs = import nixpkgs { inherit system; };
});
in
{
# Development environment output
devShells = forAllSystems ({ pkgs }: {
default = pkgs.mkShell {
# The Nix packages provided in the environment
packages = with pkgs; [
# Monitoring tools
promtail # Loki log shipper
prometheus # Metrics collector

# Kube tools
kubectl # Kubernetes CLI
kind # Kubernetes-in-Docker
kubernetes-helm # Helm CLI (Kubernetes package manager)
self.packages.${system}.kind-with-registry # Script installing kind configured with a local registry
];
};
});

# Package to install the kind-with-registry script
packages = forAllSystems ({ pkgs }: {
kind-with-registry = pkgs.stdenv.mkDerivation {
pname = "kind-with-registry";
version = "1.0.0";

src = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/kubernetes-sigs/kind/7cb9e6be25b48a0e248097eef29d496ab1a044d0/site/static/examples/kind-with-registry.sh";
sha256 = "0gri0x0ygcwmz8l4h6zzsvydw8rsh7qa8p5218d4hncm363i81hv";
outputs = { self, nixpkgs, flake-utils, gomod2nix }:
(flake-utils.lib.eachDefaultSystem
(system:
let
# Helper functions to derive Go arch from Nix arch
nixArchToGoArch = arch: {
"x86_64" = "amd64";
"aarch64" = "arm64";
}.${arch} or arch;

# Split system into arch and os
parseSystem = system:
let
parts = builtins.split "-" system;
arch = builtins.elemAt parts 0;
os = builtins.elemAt parts 2;
in {
goarch = nixArchToGoArch arch;
goos = os;
# Construct URL path in Go's format
goURLPath = "${os}-${nixArchToGoArch arch}";
};

# Platform-specific SHA256 hashes for Go 1.23.6
goSHA256s = {
"linux-amd64" = "9379441ea310de000f33a4dc767bd966e72ab2826270e038e78b2c53c2e7802d";
"linux-arm64" = "561c780e8f4a8955d32bf72e46af0b5ee5e0debe1e4633df9a03781878219202";
"darwin-amd64" = "782da50ce8ec5e98fac2cd3cdc6a1d7130d093294fc310038f651444232a3fb0";
"darwin-arm64" = "5cae2450a1708aeb0333237a155640d5562abaf195defebc4306054565536221";
};

phases = [ "installPhase" ];
pkgs = nixpkgs.legacyPackages.${system}.extend (final: prev:
let
# Convert the nix system to the golang system
# TODO(marun) Rename to reflect golang-specific nature
targetSystem = parseSystem system;
in {
go_1_23_6 = final.stdenv.mkDerivation rec {
name = "go-1.23.6";
version = "1.23.6";

inherit (targetSystem) goos goarch;
GOOS = targetSystem.goos;
GOARCH = targetSystem.goarch;

installPhase = ''
mkdir -p $out/bin
install -m755 $src $out/bin/kind-with-registry.sh
'';
src = final.fetchurl {
url = "https://go.dev/dl/go${version}.${targetSystem.goURLPath}.tar.gz";
sha256 = goSHA256s.${targetSystem.goURLPath} or (throw "Unsupported system: ${system}");
};

meta = with pkgs.lib; {
description = "Script to set up kind with a local registry";
license = licenses.mit;
maintainers = with maintainers; [ "maru-ava" ];
installPhase = ''
mkdir -p $out
cp -r ./* $out/
chmod +x $out/bin/go
'';
};
}
);

# The current default sdk for macOS fails to compile go projects, so we use a newer one for now.
# This has no effect on other platforms.
callPackage = pkgs.darwin.apple_sdk_11_0.callPackage or pkgs.callPackage;
in
rec {
packages.default = callPackage ./. {
inherit (gomod2nix.legacyPackages.${system}) buildGoApplication;
go = pkgs.go_1_23_6;
rev = self.rev or "dev";
};
};
});
};

packages.container = callPackage ./container.nix {
package = packages.default;
rev = self.rev or "dev";
};

packages.kind-with-registry = pkgs.stdenv.mkDerivation {
pname = "kind-with-registry";
version = "1.0.0";

src = pkgs.fetchurl {
url = "https://raw.githubusercontent.com/kubernetes-sigs/kind/7cb9e6be25b48a0e248097eef29d496ab1a044d0/site/static/examples/kind-with-registry.sh";
sha256 = "0gri0x0ygcwmz8l4h6zzsvydw8rsh7qa8p5218d4hncm363i81hv";
};

phases = [ "installPhase" ];

installPhase = ''
mkdir -p $out/bin
install -m755 $src $out/bin/kind-with-registry.sh
'';

meta = with pkgs.lib; {
description = "Script to set up kind with a local registry";
license = licenses.mit;
maintainers = with maintainers; [ "maru-ava" ];
};
};

devShells.default = callPackage ./shell.nix {
inherit (gomod2nix.legacyPackages.${system}) mkGoEnv;
go = pkgs.go_1_23_6;
kind-with-registry = (self.packages.${system}.kind-with-registry);
};
})
);
}
544 changes: 544 additions & 0 deletions gomod2nix.toml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion scripts/build_avalanche.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ source "$AVALANCHE_PATH"/scripts/constants.sh
source "$AVALANCHE_PATH"/scripts/git_commit.sh

build_args="$race"
echo "Building AvalancheGo..."
echo "Building AvalancheGo with [$(go version)]..."
go build $build_args -ldflags "-X github.com/ava-labs/avalanchego/version.GitCommit=$git_commit $static_ld_flags" -o "$avalanchego_path" "$AVALANCHE_PATH/main/"*.go
5 changes: 5 additions & 0 deletions scripts/gomod2nix_gen.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash

set -euo pipefail

go run github.com/maru-ava/gomod2nix@cc78df101c18e6687f4e7e9d41b2d8c8d070cdb0
40 changes: 40 additions & 0 deletions shell.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{ pkgs ? (
let
inherit (builtins) fetchTree fromJSON readFile;
inherit ((fromJSON (readFile ./flake.lock)).nodes) nixpkgs gomod2nix;
in
import (fetchTree nixpkgs.locked) {
overlays = [
(import "${fetchTree gomod2nix.locked}/overlay.nix")
];
}
)
, mkGoEnv ? pkgs.mkGoEnv
, go ? pkgs.go
, kind-with-registry
}:

let
goEnv = mkGoEnv {
pwd = ./.;
go = go;
CGO_ENABLED = "1";
};
in
pkgs.mkShell {
packages = [
goEnv

# Monitoring tools
pkgs.promtail # Loki log shipper
pkgs.prometheus # Metrics collector

# Kube tools
pkgs.kubectl # Kubernetes CLI
pkgs.kind # Kubernetes-in-Docker
pkgs.kubernetes-helm # Helm CLI (Kubernetes package manager)

# Script installing kind configured with a local registry
kind-with-registry
];
}
Loading