diff --git a/.github/workflows/cli-tests.yaml b/.github/workflows/cli-tests.yaml index 635f66dd219..12a4e5fb348 100644 --- a/.github/workflows/cli-tests.yaml +++ b/.github/workflows/cli-tests.yaml @@ -76,6 +76,16 @@ jobs: - uses: actions/checkout@v4 - uses: crate-ci/typos@v1.16.26 + flake-test: + name: Test Flake Build + if: github.ref != 'refs/heads/main' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: DeterminateSystems/nix-installer-action@main + - run: nix build . + - run: ./result/bin/devbox version + golangci-lint: strategy: matrix: diff --git a/.gitignore b/.gitignore index 098378f6069..1e9c1c0fc45 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,7 @@ __pycache__/ # deployment .vercel .yarn + +# Nix +vendor/ +result diff --git a/devbox.json b/devbox.json index 07ad979dd9c..13cc4d6e1a5 100644 --- a/devbox.json +++ b/devbox.json @@ -1,14 +1,14 @@ { - "name": "devbox", + "name": "devbox", "description": "Instant, easy, and predictable development environments", "packages": { - "go": "latest", + "go": "latest", "runx:golangci/golangci-lint": "latest", - "runx:mvdan/gofumpt": "latest", + "runx:mvdan/gofumpt": "latest" }, "env": { "GOENV": "off", - "PATH": "$PATH:$PWD/dist", + "PATH": "$PATH:$PWD/dist" }, "shell": { "init_hook": [ @@ -16,30 +16,40 @@ // user's environment and could affect the build. "test -z $FISH_VERSION && \\", "unset CGO_ENABLED GO111MODULE GOARCH GOFLAGS GOMOD GOOS GOROOT GOTOOLCHAIN GOWORK || \\", - "set --erase CGO_ENABLED GO111MODULE GOARCH GOFLAGS GOMOD GOOS GOROOT GOTOOLCHAIN GOWORK", + "set --erase CGO_ENABLED GO111MODULE GOARCH GOFLAGS GOMOD GOOS GOROOT GOTOOLCHAIN GOWORK" ], "scripts": { // Build devbox for the current platform - "build": "go build -o dist/devbox ./cmd/devbox", + "build": "go build -o dist/devbox ./cmd/devbox", "build-darwin-amd64": "GOOS=darwin GOARCH=amd64 go build -o dist/devbox-darwin-amd64 ./cmd/devbox", "build-darwin-arm64": "GOOS=darwin GOARCH=arm64 go build -o dist/devbox-darwin-arm64 ./cmd/devbox", - "build-linux-amd64": "GOOS=linux GOARCH=amd64 go build -o dist/devbox-linux-amd64 ./cmd/devbox", - "build-linux-arm64": "GOOS=linux GOARCH=arm64 go build -o dist/devbox-linux-arm64 ./cmd/devbox", + "build-linux-amd64": "GOOS=linux GOARCH=amd64 go build -o dist/devbox-linux-amd64 ./cmd/devbox", + "build-linux-arm64": "GOOS=linux GOARCH=arm64 go build -o dist/devbox-linux-arm64 ./cmd/devbox", "build-all": [ "devbox run build-darwin-amd64", "devbox run build-darwin-arm64", "devbox run build-linux-amd64", - "devbox run build-linux-arm64", + "devbox run build-linux-arm64" ], // Open VSCode - "code": "code .", - "lint": "golangci-lint run --timeout 5m && scripts/gofumpt.sh", - "fmt": "scripts/gofumpt.sh", - "test": "go test -race -cover ./...", + "code": "code .", + "lint": "golangci-lint run --timeout 5m && scripts/gofumpt.sh", + "fmt": "scripts/gofumpt.sh", + "test": "go test -race -cover ./...", "test-projects-only": "DEVBOX_RUN_PROJECT_TESTS=1 go test -v -timeout ${DEVBOX_GOLANG_TEST_TIMEOUT:-30m} ./... -run \"TestExamples|TestScriptsWithProjects\"", - "update-examples": "devbox run build && go run testscripts/testrunner/updater/main.go", - "tidy": "go mod tidy", - + "update-examples": "devbox run build && go run testscripts/testrunner/updater/main.go", + // Updates the Flake's vendorHash: First run `go mod vendor` to vendor + // the dependencies, then hash the vendor directory with Nix. + // The hash is saved to the `vendor-hash` file, which is then + // read into the Nix Flake. + "update-hash": [ + // realpath to work-around nix hash not liking symlinks + "vendor=$(realpath $(mktemp -d))", + "trap \"rm -rf $vendor\" EXIT", + "go mod vendor -o $vendor", + "nix hash path $vendor >vendor-hash", + ], + "tidy": ["go mod tidy", "devbox run update-hash"], // docker-testscripts runs the testscripts with Docker to exercise // Linux-specific tests. It invokes the test binary directly, so any extra // test runner flags must have their "-test." prefix. @@ -58,8 +68,8 @@ "GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go test -c -o testscripts-linux-amd64", "GOOS=linux GOARCH=arm64 CGO_ENABLED=0 go test -c -o testscripts-linux-arm64", "image=$(docker build --quiet --tag devbox-testscripts-ubuntu:noble --platform linux/amd64 .)", - "docker run --rm --mount type=volume,src=devbox-testscripts-amd64,dst=/nix --platform linux/amd64 -e DEVBOX_RUN_FAILING_TESTS -e DEVBOX_RUN_PROJECT_TESTS -e DEVBOX_DEBUG $image \"$@\"", - ], - }, - }, + "docker run --rm --mount type=volume,src=devbox-testscripts-amd64,dst=/nix --platform linux/amd64 -e DEVBOX_RUN_FAILING_TESTS -e DEVBOX_RUN_PROJECT_TESTS -e DEVBOX_DEBUG $image \"$@\"" + ] + } + } } diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000000..b15681f6178 --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1726560853, + "narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1727122398, + "narHash": "sha256-o8VBeCWHBxGd4kVMceIayf5GApqTavJbTa44Xcg5Rrk=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "30439d93eb8b19861ccbe3e581abf97bdc91b093", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000000..2ed7a4d5f2f --- /dev/null +++ b/flake.nix @@ -0,0 +1,69 @@ +{ + description = "Instant, easy, predictable shells and containers"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils }: + flake-utils.lib.eachDefaultSystem (system: + let + pkgs = nixpkgs.legacyPackages.${system}; + + lastTag = "0.13.2"; + + # Add the commit to the version string, in case someone builds from main + getVersion = pkgs.lib.trivial.pipe self [ + (x: "${lastTag}") + (x: if (self ? revCount) + then "${x}-${self.shortRev}" + else "${x}-${self.dirtyShortRev}") + ]; + + # Run `devbox run update-flake` to update the vendorHash + vendorHash = if builtins.pathExists ./vendor-hash + then builtins.readFile ./vendor-hash + else ""; + + buildGoModule = pkgs.buildGo123Module; + + in + { + inherit self; + packages.default = buildGoModule rec { + pname = "devbox"; + version = getVersion; + + src = ./.; + + inherit vendorHash; + + ldflags = [ + "-s" + "-w" + "-X go.jetpack.io/devbox/internal/build.Version=${version}" + ]; + + # Disable tests if they require network access or are integration tests + doCheck = false; + + nativeBuildInputs = [ pkgs.installShellFiles ]; + + postInstall = '' + installShellCompletion --cmd devbox \ + --bash <($out/bin/devbox completion bash) \ + --fish <($out/bin/devbox completion fish) \ + --zsh <($out/bin/devbox completion zsh) + ''; + + meta = with pkgs.lib; { + description = "Instant, easy, and predictable development environments"; + homepage = "https://www.jetify.com/devbox"; + license = licenses.asl20; + maintainers = with maintainers; [ lagoja ]; + }; + }; + } + ); +} diff --git a/go.sum b/go.sum index bc7c5a5dd22..93c0ddb1ce3 100644 --- a/go.sum +++ b/go.sum @@ -159,8 +159,6 @@ github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNI github.com/go-redis/redis v6.15.5+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/uuid/v5 v5.2.0 h1:qw1GMx6/y8vhVsx626ImfKMuS5CvJmhIKKtuyvfajMM= -github.com/gofrs/uuid/v5 v5.2.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= github.com/gofrs/uuid/v5 v5.3.0 h1:m0mUMr+oVYUdxpMLgSYCZiXe7PuVPnI94+OMeVBNedk= github.com/gofrs/uuid/v5 v5.3.0/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -383,8 +381,6 @@ go.jetify.com/typeid v1.2.0 h1:Nd1MZZoWe9q4kkh82xZHQbqCzxJX/ZxgK8RjQWxygwk= go.jetify.com/typeid v1.2.0/go.mod h1:CtVGyt2+TSp4Rq5+ARLvGsJqdNypKBAC6INQ9TLPlmk= go.jetpack.io/envsec v0.0.16-0.20240604163020-540ad12af899 h1:TfmHWWhwKu1jGmSLp8Iy0fsNyvqP5cAf7w/vD80ub00= go.jetpack.io/envsec v0.0.16-0.20240604163020-540ad12af899/go.mod h1:LOdrWtfvoV9dPSVHWN0onLSqeYAOKrS7k1AzwpZg0X0= -go.jetpack.io/pkg v0.0.0-20240604165525-bc24f2adac25 h1:orsMDGMS4vwdGy0LjF+2etV9AG83z0/ITCm1AfjltTI= -go.jetpack.io/pkg v0.0.0-20240604165525-bc24f2adac25/go.mod h1:L2QkDS2uIGGONAElwpoeknyvue5gbuGmMGhZqpB/sE0= go.jetpack.io/pkg v0.0.0-20240815004735-7649b4283d51 h1:udl601M1zuLyjqsW4EAJRQ0ruTYq8DXbkcFg27Ydk4I= go.jetpack.io/pkg v0.0.0-20240815004735-7649b4283d51/go.mod h1:m65l3dl6aFQdVdSvAvih73ZEfs9ndbFGnw03RVC2HFU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= diff --git a/vendor-hash b/vendor-hash new file mode 100644 index 00000000000..9ececc1780d --- /dev/null +++ b/vendor-hash @@ -0,0 +1 @@ +sha256-rwmNzYzmZqNcNVV4GgqCVLT6ofIkblVCMJHLGwlhcGw=