diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fef354ce..9f7a1273 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -23,7 +23,7 @@ before_script: - if command -v nix > /dev/null; then echo "extra-trusted-public-keys = nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" >> /etc/nix/nix.conf; fi # Install direnv and nix-direnv - - if command -v nix > /dev/null; then nix-env -iA nixpkgs.direnv nixpkgs.nix-direnv; fi + - if command -v nix > /dev/null; then nix profile install --impure --inputs-from . nixpkgs#direnv nixpkgs#nix-direnv; fi # Allow .envrc - if command -v nix > /dev/null; then direnv allow; fi @@ -35,8 +35,7 @@ ci: stage: ci image: nixos/nix:2.20.4 script: - # Cache the inputs required for the devShell - - ./bin/nix-build-and-cache .#devShells.x86_64-linux.default.inputDerivation + - ./bin/nix-build-and-cache ci - direnv exec . engage cache: @@ -48,29 +47,4 @@ artifacts: stage: artifacts image: nixos/nix:2.20.4 script: - - ./bin/nix-build-and-cache .#static-x86_64-unknown-linux-musl - - cp result/bin/grapevine x86_64-unknown-linux-musl - - # Since the OCI image package is based on the binary package, this has the - # deploying with Nix can leverage this fact by adding our binary cache to - # fun side effect of uploading the normal binary too. Grapevine users who are - # their systems. - # - # Note that although we have an `oci-image-x86_64-unknown-linux-musl` - # output, we don't build it because it would be largely redundant to this - # one since it's all containerized anyway. - - ./bin/nix-build-and-cache .#oci-image - - cp result oci-image-amd64.tar.gz - - - ./bin/nix-build-and-cache .#static-aarch64-unknown-linux-musl - - cp result/bin/grapevine aarch64-unknown-linux-musl - - - ./bin/nix-build-and-cache .#oci-image-aarch64-unknown-linux-musl - - cp result oci-image-arm64v8.tar.gz - artifacts: - paths: - - x86_64-unknown-linux-musl - - aarch64-unknown-linux-musl - - x86_64-unknown-linux-musl.deb - - oci-image-amd64.tar.gz - - oci-image-arm64v8.tar.gz + - ./bin/nix-build-and-cache packages diff --git a/bin/nix-build-and-cache b/bin/nix-build-and-cache index b206da66..4c2a8d71 100755 --- a/bin/nix-build-and-cache +++ b/bin/nix-build-and-cache @@ -2,30 +2,74 @@ set -euo pipefail -# The first argument must be the desired installable -INSTALLABLE="$1" +toplevel="$(git rev-parse --show-toplevel)" -# Build the installable and forward any other arguments too. Also, use -# nix-output-monitor instead if it's available. -if command -v nom &> /dev/null; then - nom build "$@" -else - nix build "$@" -fi +# Build and cache the specified arguments +just() { + if command -v nom &> /dev/null; then + nom build "$@" + else + nix build "$@" + fi -if [ ! -z ${ATTIC_TOKEN+x} ]; then - nix run --inputs-from . attic -- \ + if [ -z ${ATTIC_TOKEN+x} ]; then + echo "\$ATTIC_TOKEN is unset, skipping uploading to the binary cache" + return + fi + + nix run --inputs-from "$toplevel" attic -- \ login \ "$ATTIC_SERVER" \ "$ATTIC_ENDPOINT" \ "$ATTIC_TOKEN" - # Push the target installable and its build dependencies - nix run --inputs-from . attic -- \ - push \ - "$ATTIC_SERVER:$ATTIC_CACHE" \ - "$(nix path-info "$INSTALLABLE" --derivation)" \ - "$(nix path-info "$INSTALLABLE")" -else - echo "\$ATTIC_TOKEN is unset, skipping uploading to the binary cache" -fi + # Find all output paths of the installables and their build dependencies + readarray -t derivations < <(nix path-info --derivation "$@") + cache=() + for derivation in "${derivations[@]}"; do + cache+=( + "$(nix-store --query --requisites --include-outputs "$derivation")" + ) + done + + # Upload them to Attic + # + # Use `xargs` and a here-string because something would probably explode if + # several thousand arguments got passed to a command at once. Hopefully no + # store paths include a newline in them. + ( + IFS=$'\n' + nix shell --inputs-from "$toplevel" attic -c xargs \ + attic push "$ATTIC_SERVER:$ATTIC_CACHE" <<< "${cache[*]}" + ) +} + +# Build and cache things needed for CI +ci() { + cache=( + --inputs-from "$toplevel" + + # Keep sorted + "$toplevel#devShells.x86_64-linux.default" + attic#default + nixpkgs#direnv + nixpkgs#jq + nixpkgs#nix-direnv + ) + + just "${cache[@]}" +} + +# Build and cache all the package outputs +packages() { + declare -a cache="($( + nix flake show --json 2> /dev/null | + nix run --inputs-from "$toplevel" nixpkgs#jq -- \ + -r \ + '.packages."x86_64-linux" | keys | map("'"$toplevel"'#" + .) | @sh' + ))" + + just "${cache[@]}" +} + +eval "$@"