Skip to content
Open
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
4 changes: 2 additions & 2 deletions .github/renovate-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ experimental-features = nix-command flakes
# needing to create the nixbld group and users in this ephemeral container.
build-users-group =

# One build at a time, so no build starts before we can clean up /homeless-shelter.
max-jobs = 1
# Build derivations in parallel, one per CPU core.
max-jobs = auto

# Removes /homeless-shelter after each build (see the hook script above).
post-build-hook = /usr/local/bin/nix-clean-homeless-shelter
Expand Down
2 changes: 1 addition & 1 deletion .github/renovate.json5
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@
enabled: true,
},
{
description: 'Regenerate gomod2nix.toml and generated code after upgrading go dependencies',
description: 'Refresh Go vendor hashes and generated code after upgrading go dependencies',
matchDatasources: [
'go',
],
Expand Down
56 changes: 0 additions & 56 deletions flake.lock

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

12 changes: 3 additions & 9 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,13 @@
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixpkgs-unstable";

# TODO(negz): Unpin once https://github.com/nix-community/gomod2nix/pull/231 is released.
gomod2nix = {
url = "github:nix-community/gomod2nix/75c2866d585a75a1b30c634dbd7c2dcce5a6c3a7";
inputs.nixpkgs.follows = "nixpkgs";
};
};

outputs =
{
self,
nixpkgs,
nixpkgs-unstable,
gomod2nix,
}:
let
# Set by CI to override the auto-generated dev version.
Expand Down Expand Up @@ -87,7 +80,6 @@
pkgs = import nixpkgs {
inherit system;
overlays = [
gomod2nix.overlays.default
(_final: prev: {
# Allow use of pkgs.unstable.<package-name> to pull individual
# packages from nixpkgs-unstable.
Expand Down Expand Up @@ -115,6 +107,9 @@
goPlatforms
;
};
# Vendor-dependency derivation, used by `nix run .#tidy` to refresh
# the hash in nix/vendor-hashes.nix.
crossplane-vendor = build.vendor.root;
}
);

Expand Down Expand Up @@ -171,7 +166,6 @@
pkgs.docker-client
pkgs.gotestsum
pkgs.awscli2
pkgs.gomod2nix

# Code generation
pkgs.buf
Expand Down
976 changes: 0 additions & 976 deletions gomod2nix.toml

This file was deleted.

46 changes: 41 additions & 5 deletions nix/apps.nix
Original file line number Diff line number Diff line change
Expand Up @@ -105,25 +105,61 @@
);
};

# Run go mod tidy and regenerate gomod2nix.toml.
# Run go mod tidy and refresh the Go vendor hashes in nix/vendor-hashes.nix.
tidy = _: {
type = "app";
meta.description = "Run go mod tidy and regenerate gomod2nix.toml";
meta.description = "Run go mod tidy and refresh Go vendor hashes";
program = pkgs.lib.getExe (
pkgs.writeShellApplication {
name = "crossplane-cli-tidy";
runtimeInputs = [
pkgs.unstable.go_1_26
pkgs.gomod2nix
pkgs.nix
pkgs.git
pkgs.gnused
pkgs.coreutils
];
inheritPath = false;
text = ''
export CGO_ENABLED=0

echo "Running go mod tidy..."
go mod tidy
echo "Regenerating gomod2nix.toml..."
gomod2nix generate --with-deps

# Refresh a module's vendor hash in nix/vendor-hashes.nix by resetting
# it to a placeholder and reading the real hash back from the build
# error - the same trick nix-update uses for Go vendor hashes.
refresh() {
key="$1" # attribute in nix/vendor-hashes.nix
attr="$2" # flake package that builds that module's vendor dir
orig="" got=""

# Remember the current value so we can restore it if anything fails.
orig=$(sed -n "s|.*$key = \"\(sha256-[^\"]*\)\";.*|\1|p" nix/vendor-hashes.nix | head -n1)

# Set a placeholder so the build is forced to report the real hash.
sed -i "s|$key = \"sha256-[^\"]*\";|$key = \"${pkgs.lib.fakeHash}\";|" nix/vendor-hashes.nix

# --option eval-cache false: we just edited nix/vendor-hashes.nix,
# and Nix's flake eval cache can otherwise serve a stale evaluation
# that ignores the change and reports no/old hash.
got=$(nix build ".#$attr" --no-link --option eval-cache false 2>&1 \
| sed -n 's|.*got:[[:space:]]*\(sha256-[A-Za-z0-9+/=]*\).*|\1|p' \
| head -n1 || true)
if [ -z "$got" ]; then
# Build failed for some other reason (e.g. network); restore the
# previous value rather than leaving the placeholder committed.
sed -i "s|$key = \"sha256-[^\"]*\";|$key = \"$orig\";|" nix/vendor-hashes.nix
echo "ERROR: could not determine vendor hash for '$key' (restored previous value)" >&2
exit 1
fi

sed -i "s|$key = \"sha256-[^\"]*\";|$key = \"$got\";|" nix/vendor-hashes.nix
echo " $key = $got"
}

echo "Refreshing Go vendor hashes..."
refresh root crossplane-vendor

echo "Done"
'';
Expand Down
36 changes: 22 additions & 14 deletions nix/build.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@
# This makes dependencies explicit and keeps flake.nix as a clean manifest.
#
# Key primitives used here:
# pkgs.buildGoApplication - gomod2nix's Go builder (https://github.com/nix-community/gomod2nix)
# pkgs.buildGoModule - nixpkgs' Go builder, vendors deps (https://nixos.org/manual/nixpkgs/stable/#ssec-go-modules)
# pkgs.runCommand - Run a shell script, capture output directory as $out
{ pkgs, self }:
let
# Go builders backed by a single shared per-module vendor cache.
# See nix/go-builders.nix.
inherit (import ./go-builders.nix { inherit pkgs self; })
buildRootFor
rootVendor
;

# Build a Go binary for a specific platform.
goBinary =
{
Expand All @@ -19,26 +26,20 @@ let
let
ext = if platform.os == "windows" then ".exe" else "";
in
pkgs.buildGoApplication {
(buildRootFor platform) {
pname = "${pname}-${platform.os}-${platform.arch}";
inherit version;
src = self;
pwd = self;
modules = "${self}/gomod2nix.toml";
subPackages = [ subPackage ];

# Cross-compile by merging GOOS/GOARCH into Go's attrset (// merges attrsets).
go = pkgs.unstable.go_1_26 // {
GOOS = platform.os;
GOARCH = platform.arch;
};

CGO_ENABLED = "0";
env.CGO_ENABLED = "0";
doCheck = false;

preBuild = ''
ldflags="-s -w -X=github.com/crossplane/crossplane-runtime/v2/pkg/version.version=${version}"
'';
ldflags = [
"-s"
"-w"
"-X=github.com/crossplane/crossplane-runtime/v2/pkg/version.version=${version}"
];

postInstall = ''
if [ -d $out/bin/${platform.os}_${platform.arch} ]; then
Expand Down Expand Up @@ -87,6 +88,13 @@ let

in
{
# Vendored-dependency derivation. Exposed so `nix run .#tidy` can rebuild it
# to capture a fresh vendor hash. Building this realises only the vendor dir,
# not the binaries.
vendor = {
root = rootVendor;
};

# Host-native CLI binary. This is the default package, so nix build and nix
# run give you a binary for your own machine rather than the full release.
binary =
Expand Down
39 changes: 17 additions & 22 deletions nix/checks.nix
Original file line number Diff line number Diff line change
@@ -1,34 +1,37 @@
# CI check builders for Crossplane CLI.
#
# Checks run inside the Nix sandbox without network or filesystem access. This
# makes them fully reproducible but means Go modules must come from gomod2nix.
# makes them fully reproducible but means Go modules must come from the module
# cache pinned by nix/vendor-hashes.nix.
#
# Most checks use buildGoApplication, which sets up the Go environment with
# modules from gomod2nix.toml. This is different from apps, which run outside
# the sandbox and can access Go modules normally.
# Most checks use buildGoModule with proxyVendor, which makes the full module
# graph available offline (so the sandboxed checkPhase can `go test`/`go
# generate`). This is different from apps, which run outside the sandbox and
# can access Go modules normally.
#
# All checks are builder functions that take an attrset of arguments and return
# a derivation. The actual check definitions live in flake.nix.
{ pkgs, self }:
let
# Go builders backed by a single shared per-module vendor cache.
# See nix/go-builders.nix.
inherit (import ./go-builders.nix { inherit pkgs self; }) buildRoot;
in
{
# Run Go unit tests with coverage
test =
{ version }:
pkgs.buildGoApplication {
buildRoot {
pname = "crossplane-cli-test";
inherit version;
src = self;
pwd = self;
modules = ../gomod2nix.toml;
go = pkgs.unstable.go_1_26;

CGO_ENABLED = "0";
env.CGO_ENABLED = "0";

dontBuild = true;

checkPhase = ''
runHook preCheck
export HOME=$TMPDIR
go test -covermode=count -coverprofile=coverage.txt ./...
runHook postCheck
'';
Expand All @@ -42,23 +45,19 @@
# Run golangci-lint (without --fix, since source is read-only)
goLint =
{ version }:
pkgs.buildGoApplication {
buildRoot {
pname = "crossplane-cli-go-lint";
inherit version;
src = self;
pwd = self;
modules = ../gomod2nix.toml;
go = pkgs.unstable.go_1_26;

CGO_ENABLED = "0";
env.CGO_ENABLED = "0";

nativeBuildInputs = [ pkgs.unstable.golangci-lint ];

dontBuild = true;

checkPhase = ''
runHook preCheck
export HOME=$TMPDIR
export GOLANGCI_LINT_CACHE=$TMPDIR/.cache/golangci-lint
golangci-lint run
runHook postCheck
Expand All @@ -73,15 +72,12 @@
# Verify generated code matches committed code
generate =
{ version }:
pkgs.buildGoApplication {
buildRoot {
pname = "crossplane-cli-generate-check";
inherit version;
src = self;
pwd = self;
modules = ../gomod2nix.toml;
go = pkgs.unstable.go_1_26;

CGO_ENABLED = "0";
env.CGO_ENABLED = "0";

nativeBuildInputs = [
pkgs.buf
Expand All @@ -95,7 +91,6 @@

checkPhase = ''
runHook preCheck
export HOME=$TMPDIR

echo "Running go generate..."
go generate -tags generate .
Expand Down
Loading
Loading