diff --git a/.coderabbit.yaml b/.coderabbit.yaml
deleted file mode 100644
index 2220649caa28..000000000000
--- a/.coderabbit.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
-# Disable CodeRabbit auto-review to prevent verbose comments on PRs.
-# When enabled: false, CodeRabbit won't attempt reviews and won't post
-# "Review skipped" or other automated comments.
-reviews:
- auto_review:
- enabled: false
- review_status: false
- high_level_summary: false
- poem: false
- sequence_diagrams: false
- changed_files_summary: false
- tools:
- github-checks:
- enabled: false
-chat:
- art: false
- auto_reply: false
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
deleted file mode 100644
index 763c5f27ee6b..000000000000
--- a/.github/CODEOWNERS
+++ /dev/null
@@ -1,17 +0,0 @@
-# Pull requests concerning the listed files will automatically invite the respective maintainers as reviewers.
-# This file is not used for denoting any kind of ownership, but is merely a tool for handling notifications.
-#
-# Merge permissions are required for maintaining an entry in this file.
-# For documentation on this mechanism, see https://help.github.com/articles/about-codeowners/
-
-# Default reviewers if nothing else matches
-* @edolstra
-
-# This file
-.github/CODEOWNERS @edolstra
-
-# Documentation of built-in functions
-src/libexpr/primops.cc @roberth
-
-# Libstore layer
-/src/libstore @ericson2314
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index af94c3e9e5bb..08a5851748d4 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -1,10 +1,9 @@
---
name: Bug report
about: Report unexpected or incorrect behaviour
-title: ''
+title: ""
labels: bug
-assignees: ''
-
+assignees: ""
---
## Describe the bug
@@ -32,7 +31,9 @@ assignees: ''
## Metadata
-
+
+
+
## Additional context
@@ -42,13 +43,9 @@ assignees: ''
-- [ ] checked [latest Nix manual] \([source])
+- [ ] checked [latest Determinate Nix manual] \([source])
- [ ] checked [open bug issues and pull requests] for possible duplicates
-[latest Nix manual]: https://nix.dev/manual/nix/development/
-[source]: https://github.com/NixOS/nix/tree/master/doc/manual/source
-[open bug issues and pull requests]: https://github.com/NixOS/nix/labels/bug
-
----
-
-Add :+1: to [issues you find important](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc).
+[latest Determinate Nix manual]: https://manual.determinate.systems/
+[source]: https://github.com/DeterminateSystems/nix-src/tree/main/doc/manual/source
+[open bug issues and pull requests]: https://github.com/DeterminateSystems/nix-src/labels/bug
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index fe9f9dd209d4..b88e10937988 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -1,10 +1,9 @@
---
name: Feature request
about: Suggest a new feature
-title: ''
+title: ""
labels: feature
-assignees: ''
-
+assignees: ""
---
## Is your feature request related to a problem?
@@ -27,13 +26,9 @@ assignees: ''
-- [ ] checked [latest Nix manual] \([source])
-- [ ] checked [open feature issues and pull requests] for possible duplicates
-
-[latest Nix manual]: https://nix.dev/manual/nix/development/
-[source]: https://github.com/NixOS/nix/tree/master/doc/manual/source
-[open feature issues and pull requests]: https://github.com/NixOS/nix/labels/feature
-
----
+- [ ] checked [latest Determinate Nix manual] \([source])
+- [ ] checked [open bug issues and pull requests] for possible duplicates
-Add :+1: to [issues you find important](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc).
+[latest Determinate Nix manual]: https://manual.determinate.systems/
+[source]: https://github.com/DeterminateSystems/nix-src/tree/main/doc/manual/source
+[open bug issues and pull requests]: https://github.com/DeterminateSystems/nix-src/labels/bug
diff --git a/.github/ISSUE_TEMPLATE/installer.md b/.github/ISSUE_TEMPLATE/installer.md
index 070e0bd9b25b..430bef971aac 100644
--- a/.github/ISSUE_TEMPLATE/installer.md
+++ b/.github/ISSUE_TEMPLATE/installer.md
@@ -1,18 +1,17 @@
---
name: Installer issue
about: Report problems with installation
-title: ''
+title: ""
labels: installer
-assignees: ''
-
+assignees: ""
---
## Platform
-
+
-- [ ] Linux:
- [ ] macOS
+- [ ] Linux:
- [ ] WSL
## Additional information
@@ -35,13 +34,9 @@ assignees: ''
-- [ ] checked [latest Nix manual] \([source])
-- [ ] checked [open installer issues and pull requests] for possible duplicates
-
-[latest Nix manual]: https://nix.dev/manual/nix/development/
-[source]: https://github.com/NixOS/nix/tree/master/doc/manual/source
-[open installer issues and pull requests]: https://github.com/NixOS/nix/labels/installer
-
----
+- [ ] checked [latest Determinate Nix manual] \([source])
+- [ ] checked [open bug issues and pull requests] for possible duplicates
-Add :+1: to [issues you find important](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc).
+[latest Determinate Nix manual]: https://manual.determinate.systems/
+[source]: https://github.com/DeterminateSystems/nix-src/tree/main/doc/manual/source
+[open bug issues and pull requests]: https://github.com/DeterminateSystems/nix-src/labels/bug
diff --git a/.github/ISSUE_TEMPLATE/missing_documentation.md b/.github/ISSUE_TEMPLATE/missing_documentation.md
index 4e05b626d398..fcdd0d20135e 100644
--- a/.github/ISSUE_TEMPLATE/missing_documentation.md
+++ b/.github/ISSUE_TEMPLATE/missing_documentation.md
@@ -1,10 +1,9 @@
---
name: Missing or incorrect documentation
about: Help us improve the reference manual
-title: ''
+title: ""
labels: documentation
-assignees: ''
-
+assignees: ""
---
## Problem
@@ -19,13 +18,9 @@ assignees: ''
-- [ ] checked [latest Nix manual] \([source])
-- [ ] checked [open documentation issues and pull requests] for possible duplicates
-
-[latest Nix manual]: https://nix.dev/manual/nix/development/
-[source]: https://github.com/NixOS/nix/tree/master/doc/manual/source
-[open documentation issues and pull requests]: https://github.com/NixOS/nix/labels/documentation
-
----
+- [ ] checked [latest Determinate Nix manual] \([source])
+- [ ] checked [open bug issues and pull requests] for possible duplicates
-Add :+1: to [issues you find important](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc).
+[latest Determinate Nix manual]: https://manual.determinate.systems/
+[source]: https://github.com/DeterminateSystems/nix-src/tree/main/doc/manual/source
+[open bug issues and pull requests]: https://github.com/DeterminateSystems/nix-src/labels/bug
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index c155bf8bfa4f..d3e1f8177364 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,26 +1,3 @@
-
-
## Motivation
@@ -34,9 +11,3 @@ PR stuck in review? We have two Nix team meetings per week online that are open
-
----
-
-Add :+1: to [pull requests you find important](https://github.com/NixOS/nix/pulls?q=is%3Aopen+sort%3Areactions-%2B1-desc).
-
-The Nix maintainer team uses a [GitHub project board](https://github.com/orgs/NixOS/projects/19) to [schedule and track reviews](https://github.com/NixOS/nix/tree/master/maintainers#project-board-protocol).
diff --git a/.github/STALE-BOT.md b/.github/STALE-BOT.md
index bc0005413f1a..281d0f79a8b7 100644
--- a/.github/STALE-BOT.md
+++ b/.github/STALE-BOT.md
@@ -2,34 +2,21 @@
- Thanks for your contribution!
- To remove the stale label, just leave a new comment.
-- _How to find the right people to ping?_ → [`git blame`](https://git-scm.com/docs/git-blame) to the rescue! (or GitHub's history and blame buttons.)
-- You can always ask for help on [our Discourse Forum](https://discourse.nixos.org/) or on [Matrix - #users:nixos.org](https://matrix.to/#/#users:nixos.org).
+- You can always ask for help on [Discord](https://determinate.systems/discord).
## Suggestions for PRs
-1. GitHub sometimes doesn't notify people who commented / reviewed a PR previously, when you (force) push commits. If you have addressed the reviews you can [officially ask for a review](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/requesting-a-pull-request-review) from those who commented to you or anyone else.
-2. If it is unfinished but you plan to finish it, please mark it as a draft.
-3. If you don't expect to work on it any time soon, closing it with a short comment may encourage someone else to pick up your work.
-4. To get things rolling again, rebase the PR against the target branch and address valid comments.
-5. If you need a review to move forward, ask in [the Discourse thread for PRs that need help](https://discourse.nixos.org/t/prs-in-distress/3604).
-6. If all you need is a merge, check the git history to find and [request reviews](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/requesting-a-pull-request-review) from people who usually merge related contributions.
+1. If it is unfinished but you plan to finish it, please mark it as a draft.
+1. If you don't expect to work on it any time soon, closing it with a short comment may encourage someone else to pick up your work.
+1. To get things rolling again, rebase the PR against the target branch and address valid comments.
+1. If you need a review to move forward, ask in [Discord](https://determinate.systems/discord).
## Suggestions for issues
1. If it is resolved (either for you personally, or in general), please consider closing it.
2. If this might still be an issue, but you are not interested in promoting its resolution, please consider closing it while encouraging others to take over and reopen an issue if they care enough.
-3. If you still have interest in resolving it, try to ping somebody who you believe might have an interest in the topic. Consider discussing the problem in [our Discourse Forum](https://discourse.nixos.org/).
-4. As with all open source projects, your best option is to submit a Pull Request that addresses this issue. We :heart: this attitude!
+3. If you still have interest in resolving it, try to ping somebody who you believe might have an interest in the topic. Consider discussing the problem in [Discord](https://determinate.systems/discord).
**Memorandum on closing issues**
Don't be afraid to close an issue that holds valuable information. Closed issues stay in the system for people to search, read, cross-reference, or even reopen--nothing is lost! Closing obsolete issues is an important way to help maintainers focus their time and effort.
-
-## Useful GitHub search queries
-
-- [Open PRs with any stale-bot interaction](https://github.com/NixOS/nix/pulls?q=is%3Apr+is%3Aopen+commenter%3Aapp%2Fstale+)
-- [Open PRs with any stale-bot interaction and `stale`](https://github.com/NixOS/nix/pulls?q=is%3Apr+is%3Aopen+commenter%3Aapp%2Fstale+label%3A%22stale%22)
-- [Open PRs with any stale-bot interaction and NOT `stale`](https://github.com/NixOS/nix/pulls?q=is%3Apr+is%3Aopen+commenter%3Aapp%2Fstale+-label%3A%22stale%22+)
-- [Open Issues with any stale-bot interaction](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+commenter%3Aapp%2Fstale+)
-- [Open Issues with any stale-bot interaction and `stale`](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+commenter%3Aapp%2Fstale+label%3A%22stale%22+)
-- [Open Issues with any stale-bot interaction and NOT `stale`](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+commenter%3Aapp%2Fstale+-label%3A%22stale%22+)
diff --git a/.github/release-notes.sh b/.github/release-notes.sh
new file mode 100755
index 000000000000..f641e146d2e8
--- /dev/null
+++ b/.github/release-notes.sh
@@ -0,0 +1,69 @@
+#!/usr/bin/env bash
+
+# SC2002 disables "useless cat" warnings.
+# I prefer pipelines that start with an explicit input, and go from there.
+# Overly fussy.
+# shellcheck disable=SC2002
+
+scratch=$(mktemp -d -t tmp.XXXXXXXXXX)
+finish() {
+ rm -rf "$scratch"
+}
+trap finish EXIT
+
+DATE=$(date +%Y-%m-%d)
+DETERMINATE_NIX_VERSION=$(cat .version-determinate)
+TAG_NAME="v${DETERMINATE_NIX_VERSION}"
+NIX_VERSION=$(cat .version)
+NIX_VERSION_MAJOR_MINOR=$(echo "$NIX_VERSION" | cut -d. -f1,2)
+GITHUB_REPOSITORY="${GITHUB_REPOSITORY:-DeterminateSystems/nix-src}"
+
+gh api "/repos/${GITHUB_REPOSITORY}/releases/generate-notes" \
+ -f "tag_name=${TAG_NAME}" > "$scratch/notes.json"
+
+trim_trailing_newlines() {
+ local text
+ text="$(cat)"
+ echo -n "${text}"
+}
+
+linkify_gh() {
+ sed \
+ -e 's!\(https://github.com/DeterminateSystems/nix-src/\(pull\|issue\)/\([[:digit:]]\+\)\)!' \
+ -e 's#\(https://github.com/DeterminateSystems/nix-src/compare/\([^ ]\+\)\)#[\2](\1)#'
+}
+
+(
+ cat doc/manual/source/release-notes-determinate/changes.md \
+ | sed 's/^.*\(\)$/This section lists the differences between upstream Nix '"$NIX_VERSION_MAJOR_MINOR"' and Determinate Nix '"$DETERMINATE_NIX_VERSION"'.\1/' \
+
+ printf "\n\n" "$DETERMINATE_NIX_VERSION"
+ cat "$scratch/notes.json" \
+ | jq -r .body \
+ | grep -v '^#' \
+ | grep -v "Full Changelog" \
+ | trim_trailing_newlines \
+ | sed -e 's/^\* /\n* /' \
+ | linkify_gh
+ echo "" # final newline
+) > "$scratch/changes.md"
+
+(
+ printf "# Release %s (%s)\n\n" \
+ "$DETERMINATE_NIX_VERSION" \
+ "$DATE"
+ printf "* Based on [upstream Nix %s](../release-notes/rl-%s.md).\n\n" \
+ "$NIX_VERSION" \
+ "$NIX_VERSION_MAJOR_MINOR"
+
+ cat "$scratch/notes.json" | jq -r .body | linkify_gh
+) > "$scratch/rl.md"
+
+(
+ cat doc/manual/source/SUMMARY.md.in \
+ | sed 's/\(\)$/\1\n - [Release '"$DETERMINATE_NIX_VERSION"' ('"$DATE"')](release-notes-determinate\/'"$TAG_NAME"'.md)/'
+) > "$scratch/summary.md"
+
+mv "$scratch/changes.md" doc/manual/source/release-notes-determinate/changes.md
+mv "$scratch/rl.md" "doc/manual/source/release-notes-determinate/v${DETERMINATE_NIX_VERSION}.md"
+mv "$scratch/summary.md" doc/manual/source/SUMMARY.md.in
diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml
deleted file mode 100644
index 90dbb9305223..000000000000
--- a/.github/workflows/backport.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-name: Backport
-on:
- pull_request_target:
- types: [closed, labeled]
-permissions:
- contents: read
-jobs:
- backport:
- name: Backport Pull Request
- permissions:
- # for korthout/backport-action
- contents: write
- pull-requests: write
- if: github.repository_owner == 'NixOS' && github.event.pull_request.merged == true && (github.event_name != 'labeled' || startsWith('backport', github.event.label.name))
- runs-on: ubuntu-24.04-arm
- steps:
- - name: Generate GitHub App token
- id: generate-token
- uses: actions/create-github-app-token@v2
- with:
- app-id: ${{ vars.CI_APP_ID }}
- private-key: ${{ secrets.CI_APP_PRIVATE_KEY }}
- - uses: actions/checkout@v6
- with:
- ref: ${{ github.event.pull_request.head.sha }}
- # required to find all branches
- fetch-depth: 0
- - name: Create backport PRs
- uses: korthout/backport-action@c656f5d5851037b2b38fb5db2691a03fa229e3b2 # v4.0.1
- id: backport
- with:
- # Config README: https://github.com/korthout/backport-action#backport-action
- github_token: ${{ steps.generate-token.outputs.token }}
- github_workspace: ${{ github.workspace }}
- auto_merge_enabled: true
- pull_description: |-
- Automatic backport to `${target_branch}`, triggered by a label in #${pull_number}.
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 000000000000..b43a8067d79c
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,274 @@
+on:
+ workflow_call:
+ inputs:
+ system:
+ required: true
+ type: string
+ runner:
+ required: true
+ type: string
+ runner_for_virt:
+ required: true
+ type: string
+ runner_small:
+ required: true
+ type: string
+ if:
+ required: false
+ default: true
+ type: boolean
+ run_tests:
+ required: false
+ default: true
+ type: boolean
+ run_vm_tests:
+ required: false
+ default: false
+ type: boolean
+ run_regression_tests:
+ required: false
+ default: false
+ type: boolean
+ publish_manual:
+ required: false
+ default: false
+ type: boolean
+ secrets:
+ manual_netlify_auth_token:
+ required: false
+ manual_netlify_site_id:
+ required: false
+
+jobs:
+ build:
+ if: ${{ inputs.if }}
+ strategy:
+ fail-fast: false
+ runs-on: ${{ inputs.runner }}
+ timeout-minutes: 60
+ steps:
+ - uses: actions/checkout@v4
+ - uses: DeterminateSystems/determinate-nix-action@main
+ - uses: DeterminateSystems/flakehub-cache-action@main
+ - run: nix build .#packages.${{ inputs.system }}.default .#packages.${{ inputs.system }}.binaryTarball --no-link -L
+ - run: nix build .#packages.${{ inputs.system }}.binaryTarball --out-link tarball
+ - run: nix build .#packages.${{ inputs.system }}.nix-cli-static --no-link -L
+ - uses: actions/upload-artifact@v4
+ with:
+ name: ${{ inputs.system }}
+ path: ./tarball/*.xz
+
+ test:
+ if: ${{ inputs.if && inputs.run_tests}}
+ needs: build
+ strategy:
+ fail-fast: false
+ runs-on: ${{ inputs.runner }}
+ timeout-minutes: 60
+ steps:
+ - uses: actions/checkout@v4
+ - uses: DeterminateSystems/determinate-nix-action@main
+ - uses: DeterminateSystems/flakehub-cache-action@main
+ - run: nix flake check -L --system ${{ inputs.system }}
+
+ vm_tests_smoke:
+ if: inputs.run_vm_tests && github.event_name != 'merge_group'
+ needs: build
+ runs-on: ${{ inputs.runner_for_virt }}
+ steps:
+ - uses: actions/checkout@v4
+ - uses: DeterminateSystems/determinate-nix-action@main
+ - uses: DeterminateSystems/flakehub-cache-action@main
+ - run: |
+ nix build -L \
+ .#hydraJobs.tests.functional_user \
+ .#hydraJobs.tests.githubFlakes \
+ .#hydraJobs.tests.nix-docker \
+ .#hydraJobs.tests.tarballFlakes \
+ ;
+
+ vm_tests_all:
+ if: inputs.run_vm_tests && github.event_name == 'merge_group'
+ needs: build
+ runs-on: ${{ inputs.runner_for_virt }}
+ steps:
+ - uses: actions/checkout@v4
+ - uses: DeterminateSystems/determinate-nix-action@main
+ - uses: DeterminateSystems/flakehub-cache-action@main
+ - run: |
+ cmd() {
+ nix build -L --keep-going --timeout 600 \
+ $(nix flake show --json \
+ | jq -r '
+ .hydraJobs.tests
+ | with_entries(select(.value.type == "derivation"))
+ | keys[]
+ | ".#hydraJobs.tests." + .')
+ }
+
+ if ! cmd; then
+ echo "failed, retrying once ..."
+ printf "\n\n\n\n\n\n\n\n"
+ cmd
+ fi
+
+ flake_regressions:
+ if: |
+ (inputs.run_regression_tests && github.event_name == 'merge_group')
+ || (
+ inputs.run_regression_tests
+ && github.event.pull_request.head.repo.full_name == 'DeterminateSystems/nix-src'
+ && (
+ (github.event.action == 'labeled' && github.event.label.name == 'flake-regression-test')
+ || (github.event.action != 'labeled' && contains(github.event.pull_request.labels.*.name, 'flake-regression-test'))
+ )
+ )
+ needs: build
+ runs-on: ${{ inputs.runner }}
+ strategy:
+ matrix:
+ nix_config:
+ - "lazy-trees = true"
+ - "lazy-trees = false"
+ - "eval-cores = 24"
+ glob:
+ - "[0]*"
+ - "[1]*"
+ - "[2]*"
+ - "[3]*"
+ - "[4]*"
+ - "[5]*"
+ - "[6]*"
+ - "[7]*"
+ - "[8]*"
+ - "[9]*"
+ - "[a]*"
+ - "[b]*"
+ - "[c]*"
+ - "[d]*"
+ - "[e]*"
+ - "[f]*"
+ - "[g]*"
+ - "[h]*"
+ - "[i]*"
+ - "[j]*"
+ - "[k]*"
+ - "[l]*"
+ - "[m]*"
+ - "[n]*"
+ - "[o]*"
+ - "[p]*"
+ - "[q]*"
+ - "[r]*"
+ - "[s]*"
+ - "[t]*"
+ - "[u]*"
+ - "[v]*"
+ - "[w]*"
+ - "[x]*"
+ - "[y]*"
+ - "[z]*"
+
+ steps:
+ - name: Checkout nix
+ uses: actions/checkout@v4
+ - name: Checkout flake-regressions
+ uses: actions/checkout@v4
+ with:
+ repository: NixOS/flake-regressions
+ path: flake-regressions
+ - name: Checkout flake-regressions-data
+ uses: actions/checkout@v4
+ with:
+ repository: NixOS/flake-regressions-data
+ path: flake-regressions/tests
+ - uses: DeterminateSystems/determinate-nix-action@main
+ - uses: DeterminateSystems/flakehub-cache-action@main
+ - name: Run flake regression tests
+ env:
+ #PARALLEL: ${{ !contains(matrix.nix_config, 'eval-cores') && '-P 50%' || '-P 1' }}
+ PARALLEL: '-P 1'
+ FLAKE_REGRESSION_GLOB: ${{ matrix.glob }}
+ NIX_CONFIG: ${{ matrix.nix_config }}
+ PREFETCH: "1"
+ USE_NIX_FLAKE_SHOW: "1"
+ run: |
+ set -x
+ echo "PARALLEL: $PARALLEL"
+ echo "NIX_CONFIG: $NIX_CONFIG"
+ if [ ! -z "${NSC_CACHE_PATH:-}" ]; then
+ mkdir -p "${NSC_CACHE_PATH}/nix/xdg-cache"
+ export XDG_CACHE_HOME="${NSC_CACHE_PATH}/nix/xdg-cache"
+ fi
+ nix build -L --out-link ./new-nix
+ export PATH=$(pwd)/new-nix/bin:$PATH
+ [[ $(type -p nix) = $(pwd)/new-nix/bin/nix ]]
+
+ nix config show lazy-trees
+ nix config show eval-cores
+ lscpu
+ nproc
+
+ if ! flake-regressions/eval-all.sh; then
+ echo "Some failed, trying again"
+ printf "\n\n\n\n\n\n\n\n"
+ NIX_REMOTE=/tmp/nix flake-regressions/eval-all.sh
+ fi
+
+ manual:
+ if: github.event_name != 'merge_group'
+ needs: build
+ runs-on: ${{ inputs.runner_small }}
+ permissions:
+ id-token: "write"
+ contents: "read"
+ pull-requests: "write"
+ statuses: "write"
+ deployments: "write"
+ steps:
+ - name: Checkout nix
+ uses: actions/checkout@v4
+ - uses: DeterminateSystems/determinate-nix-action@main
+ - uses: DeterminateSystems/flakehub-cache-action@main
+ - name: Build manual
+ if: inputs.system == 'x86_64-linux'
+ run: nix build .#hydraJobs.manual
+ - uses: nwtgck/actions-netlify@v3.0
+ if: inputs.publish_manual && inputs.system == 'x86_64-linux'
+ with:
+ publish-dir: "./result/share/doc/nix/manual"
+ production-branch: main
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ deploy-message: "Deploy from GitHub Actions"
+ # NOTE(cole-h): We have a perpetual PR displaying our changes against upstream open, but
+ # its conversation is locked, so this PR comment can never be posted.
+ # https://github.com/DeterminateSystems/nix-src/pull/165
+ enable-pull-request-comment: ${{ github.event.pull_request.number != 165 }}
+ enable-commit-comment: true
+ enable-commit-status: true
+ overwrites-pull-request-comment: true
+ env:
+ NETLIFY_AUTH_TOKEN: ${{ secrets.manual_netlify_auth_token }}
+ NETLIFY_SITE_ID: ${{ secrets.manual_netlify_site_id }}
+
+ success:
+ needs:
+ - build
+ - test
+ - vm_tests_smoke
+ - vm_tests_all
+ - flake_regressions
+ - manual
+ if: ${{ always() }}
+ runs-on: ubuntu-latest
+ steps:
+ - run: "true"
+ - run: |
+ echo "A dependent in the build matrix failed:"
+ echo "$needs"
+ exit 1
+ env:
+ needs: ${{ toJSON(needs) }}
+ if: |
+ contains(needs.*.result, 'failure') ||
+ contains(needs.*.result, 'cancelled')
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 2347bf9107d1..08000ac4c871 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -2,266 +2,158 @@ name: "CI"
on:
pull_request:
- merge_group:
push:
branches:
+ # NOTE: make sure any branches here are also valid directory names,
+ # otherwise creating the directory and uploading to s3 will fail
+ - main
- master
- workflow_dispatch:
- inputs:
- dogfood:
- description: 'Use dogfood Nix build'
- required: false
- default: true
- type: boolean
-
-concurrency:
- group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
- cancel-in-progress: true
+ merge_group:
+ release:
+ types:
+ - published
-permissions: read-all
+permissions:
+ id-token: "write"
+ contents: "read"
+ pull-requests: "write"
+ statuses: "write"
+ deployments: "write"
jobs:
eval:
- runs-on: ubuntu-24.04
+ runs-on: UbuntuLatest32Cores128G
steps:
- - uses: actions/checkout@v6
- with:
- fetch-depth: 0
- - uses: ./.github/actions/install-nix-action
- with:
- dogfood: ${{ github.event_name == 'workflow_dispatch' && inputs.dogfood || github.event_name != 'workflow_dispatch' }}
- extra_nix_config:
- experimental-features = nix-command flakes
- github_token: ${{ secrets.GITHUB_TOKEN }}
- use_cache: false
- - run: nix flake show --all-systems --json
-
- pre-commit-checks:
- name: pre-commit checks
- runs-on: ubuntu-24.04
- steps:
- - uses: actions/checkout@v6
- - uses: ./.github/actions/install-nix-action
+ - uses: actions/checkout@v4
with:
- dogfood: ${{ github.event_name == 'workflow_dispatch' && inputs.dogfood || github.event_name != 'workflow_dispatch' }}
- extra_nix_config: experimental-features = nix-command flakes
- github_token: ${{ secrets.GITHUB_TOKEN }}
- - run: ./ci/gha/tests/pre-commit-checks
+ fetch-depth: 0
+ - uses: DeterminateSystems/determinate-nix-action@main
+ - run: nix flake show --all-systems --json
+
+ build_x86_64-linux:
+ uses: ./.github/workflows/build.yml
+ with:
+ system: x86_64-linux
+ runner: namespace-profile-linuxamd32c64g-cache
+ runner_for_virt: UbuntuLatest32Cores128G
+ runner_small: ubuntu-latest
+ run_tests: true
+ run_vm_tests: true
+ run_regression_tests: true
+ publish_manual: true
+ secrets:
+ manual_netlify_auth_token: ${{ secrets.NETLIFY_AUTH_TOKEN }}
+ manual_netlify_site_id: ${{ secrets.NETLIFY_SITE_ID }}
+
+ build_aarch64-linux:
+ uses: ./.github/workflows/build.yml
+ with:
+ if: ${{
+ github.event_name != 'pull_request'
+ || (
+ github.event.pull_request.head.repo.full_name == 'DeterminateSystems/nix-src'
+ && (
+ (github.event.action == 'labeled' && github.event.label.name == 'upload to s3')
+ || (github.event.action != 'labeled' && contains(github.event.pull_request.labels.*.name, 'upload to s3'))
+ )
+ )
+ }}
+ system: aarch64-linux
+ runner: UbuntuLatest32Cores128GArm
+ runner_for_virt: UbuntuLatest32Cores128GArm
+ runner_small: UbuntuLatest32Cores128GArm
- basic-checks:
- name: aggregate basic checks
+ build_aarch64-darwin:
+ uses: ./.github/workflows/build.yml
+ with:
+ system: aarch64-darwin
+ runner: namespace-profile-mac-m2-12c28g
+ runner_for_virt: namespace-profile-mac-m2-12c28g
+ runner_small: macos-latest-xlarge
+
+ success:
+ runs-on: ubuntu-latest
+ needs:
+ - eval
+ - build_x86_64-linux
+ - build_aarch64-linux
+ - build_aarch64-darwin
if: ${{ always() }}
- runs-on: ubuntu-24.04
- needs: [pre-commit-checks, eval]
steps:
- - name: Exit with any errors
- if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}
- run: |
+ - run: "true"
+ - run: |
+ echo "A dependent in the build matrix failed:"
+ echo "$needs"
exit 1
+ env:
+ needs: ${{ toJSON(needs) }}
+ if: |
+ contains(needs.*.result, 'failure') ||
+ contains(needs.*.result, 'cancelled')
- tests:
- needs: basic-checks
- strategy:
- fail-fast: false
- matrix:
- include:
- - scenario: on ubuntu
- runs-on: ubuntu-24.04
- os: linux
- instrumented: false
- primary: true
- stdenv: stdenv
- - scenario: on macos
- runs-on: macos-14
- os: darwin
- instrumented: false
- primary: true
- stdenv: stdenv
- - scenario: on ubuntu (with sanitizers / coverage)
- runs-on: ubuntu-24.04
- os: linux
- instrumented: true
- primary: false
- stdenv: clangStdenv
- name: tests ${{ matrix.scenario }}
- runs-on: ${{ matrix.runs-on }}
- timeout-minutes: 60
- steps:
- - uses: actions/checkout@v6
- with:
- fetch-depth: 0
- - uses: ./.github/actions/install-nix-action
- with:
- github_token: ${{ secrets.GITHUB_TOKEN }}
- dogfood: ${{ github.event_name == 'workflow_dispatch' && inputs.dogfood || github.event_name != 'workflow_dispatch' }}
- # The sandbox would otherwise be disabled by default on Darwin
- extra_nix_config: "sandbox = true"
- # Since ubuntu 22.30, unprivileged usernamespaces are no longer allowed to map to the root user:
- # https://ubuntu.com/blog/ubuntu-23-10-restricted-unprivileged-user-namespaces
- - run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
- if: matrix.os == 'linux'
- - name: Run component tests
- run: |
- nix build --file ci/gha/tests/wrapper.nix componentTests -L \
- --arg withInstrumentation ${{ matrix.instrumented }} \
- --argstr stdenv "${{ matrix.stdenv }}"
- - name: Run VM tests
- run: |
- nix build --file ci/gha/tests/wrapper.nix vmTests -L \
- --arg withInstrumentation ${{ matrix.instrumented }} \
- --argstr stdenv "${{ matrix.stdenv }}"
- if: ${{ matrix.os == 'linux' }}
- - name: Run flake checks and prepare the installer tarball
- run: |
- ci/gha/tests/build-checks
- ci/gha/tests/prepare-installer-for-github-actions
- if: ${{ matrix.primary }}
- - name: Collect code coverage
- run: |
- nix build --file ci/gha/tests/wrapper.nix codeCoverage.coverageReports -L \
- --arg withInstrumentation ${{ matrix.instrumented }} \
- --argstr stdenv "${{ matrix.stdenv }}" \
- --out-link coverage-reports
- cat coverage-reports/index.txt >> $GITHUB_STEP_SUMMARY
- if: ${{ matrix.instrumented }}
- - name: Upload coverage reports
- uses: actions/upload-artifact@v5
- with:
- name: coverage-reports
- path: coverage-reports/
- if: ${{ matrix.instrumented }}
- - name: Upload installer tarball
- uses: actions/upload-artifact@v5
- with:
- name: installer-${{matrix.os}}
- path: out/*
- if: ${{ matrix.primary }}
-
- installer_test:
- needs: [tests]
- strategy:
- fail-fast: false
- matrix:
- include:
- - scenario: on ubuntu
- runs-on: ubuntu-24.04
- os: linux
- experimental-installer: false
- - scenario: on macos
- runs-on: macos-14
- os: darwin
- experimental-installer: false
- - scenario: on ubuntu (experimental)
- runs-on: ubuntu-24.04
- os: linux
- experimental-installer: true
- - scenario: on macos (experimental)
- runs-on: macos-14
- os: darwin
- experimental-installer: true
- name: installer test ${{ matrix.scenario }}
- runs-on: ${{ matrix.runs-on }}
- steps:
- - uses: actions/checkout@v6
- - name: Download installer tarball
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
- with:
- name: installer-${{matrix.os}}
- path: out
- - name: Looking up the installer tarball URL
- id: installer-tarball-url
- run: |
- echo "installer-url=file://$GITHUB_WORKSPACE/out" >> "$GITHUB_OUTPUT"
- TARBALL_PATH="$(find "$GITHUB_WORKSPACE/out" -name 'nix*.tar.xz' -print | head -n 1)"
- echo "tarball-path=file://$TARBALL_PATH" >> "$GITHUB_OUTPUT"
- - uses: cachix/install-nix-action@0b0e072294b088b73964f1d72dfdac0951439dbd # v31.8.4
- if: ${{ !matrix.experimental-installer }}
- with:
- install_url: ${{ format('{0}/install', steps.installer-tarball-url.outputs.installer-url) }}
- install_options: ${{ format('--tarball-url-prefix {0}', steps.installer-tarball-url.outputs.installer-url) }}
- - uses: ./.github/actions/install-nix-action
- if: ${{ matrix.experimental-installer }}
- with:
- dogfood: false
- experimental-installer: true
- tarball_url: ${{ steps.installer-tarball-url.outputs.tarball-path }}
- github_token: ${{ secrets.GITHUB_TOKEN }}
- - run: sudo apt install fish zsh
- if: matrix.os == 'linux'
- - run: brew install fish
- if: matrix.os == 'darwin'
- - run: exec bash -c "nix-instantiate -E 'builtins.currentTime' --eval"
- - run: exec sh -c "nix-instantiate -E 'builtins.currentTime' --eval"
- - run: exec zsh -c "nix-instantiate -E 'builtins.currentTime' --eval"
- - run: exec fish -c "nix-instantiate -E 'builtins.currentTime' --eval"
- - run: exec bash -c "nix-channel --add https://releases.nixos.org/nixos/unstable/nixos-23.05pre466020.60c1d71f2ba nixpkgs"
- - run: exec bash -c "nix-channel --update && nix-env -iA nixpkgs.hello && hello"
+ - uses: actions/checkout@v4
+ - uses: DeterminateSystems/determinate-nix-action@main
- docker_push_image:
- name: Push docker image to DockerHub and GHCR
- needs: [flake_regressions, installer_test]
- if: github.event_name == 'push' && github.ref_name == 'master'
- uses: ./.github/workflows/docker-push.yml
- with:
- ref: ${{ github.sha }}
- is_master: true
- permissions:
- contents: read
- packages: write
- secrets:
- DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
- DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
+ - name: Create artifacts directory
+ run: mkdir -p ./artifacts
- flake_regressions:
- needs: tests
- runs-on: ubuntu-24.04
- steps:
- - name: Checkout nix
- uses: actions/checkout@v6
- - name: Checkout flake-regressions
- uses: actions/checkout@v6
- with:
- repository: NixOS/flake-regressions
- path: flake-regressions
- - name: Checkout flake-regressions-data
- uses: actions/checkout@v6
+ - name: Fetch artifacts
+ uses: actions/download-artifact@v4
with:
- repository: NixOS/flake-regressions-data
- path: flake-regressions/tests
- - name: Download installer tarball
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
- with:
- name: installer-linux
- path: out
- - name: Looking up the installer tarball URL
- id: installer-tarball-url
+ path: downloaded
+ - name: Move downloaded artifacts to artifacts directory
+ run: |
+ for dir in ./downloaded/*; do
+ arch="$(basename "$dir")"
+ mv "$dir"/*.xz ./artifacts/"${arch}"
+ done
+
+ - name: Build fallback-paths.nix
+ if: ${{
+ github.event_name != 'pull_request'
+ || (
+ github.event.pull_request.head.repo.full_name == 'DeterminateSystems/nix-src'
+ && (
+ (github.event.action == 'labeled' && github.event.label.name == 'upload to s3')
+ || (github.event.action != 'labeled' && contains(github.event.pull_request.labels.*.name, 'upload to s3'))
+ )
+ )
+ }}
run: |
- echo "installer-url=file://$GITHUB_WORKSPACE/out" >> "$GITHUB_OUTPUT"
- - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31.9.0
+ nix build .#fallbackPathsNix --out-link fallback
+ cat fallback > ./artifacts/fallback-paths.nix
+
+ - uses: DeterminateSystems/push-artifact-ids@main
with:
- install_url: ${{ format('{0}/install', steps.installer-tarball-url.outputs.installer-url) }}
- install_options: ${{ format('--tarball-url-prefix {0}', steps.installer-tarball-url.outputs.installer-url) }}
- - name: Run flake regressions tests
- run: MAX_FLAKES=25 flake-regressions/eval-all.sh
+ s3_upload_role: ${{ secrets.AWS_S3_UPLOAD_ROLE_ARN }}
+ bucket: ${{ secrets.AWS_S3_UPLOAD_BUCKET_NAME }}
+ directory: ./artifacts
+ ids_project_name: determinate-nix
+ ids_binary_prefix: determinate-nix
+ skip_acl: true
+ allowed_branches: '["main"]'
- profile_build:
- needs: tests
- runs-on: ubuntu-24.04
- timeout-minutes: 60
- if: >-
- github.event_name == 'push' &&
- github.ref_name == 'master'
+ publish:
+ needs:
+ - success
+ if: (!github.repository.fork && (github.ref == format('refs/heads/{0}', github.event.repository.default_branch) || startsWith(github.ref, 'refs/tags/')))
+ environment: ${{ github.event_name == 'release' && 'production' || '' }}
+ runs-on: ubuntu-latest
+ permissions:
+ contents: write
+ id-token: write
steps:
- - uses: actions/checkout@v6
- with:
- fetch-depth: 0
- - uses: ./.github/actions/install-nix-action
- with:
- github_token: ${{ secrets.GITHUB_TOKEN }}
- dogfood: ${{ github.event_name == 'workflow_dispatch' && inputs.dogfood || github.event_name != 'workflow_dispatch' }}
- extra_nix_config: |
- experimental-features = flakes nix-command ca-derivations impure-derivations
- max-jobs = 1
- - run: |
- nix build -L --file ./ci/gha/profile-build buildTimeReport --out-link build-time-report.md
- cat build-time-report.md >> $GITHUB_STEP_SUMMARY
+ - uses: actions/checkout@v4
+ - uses: DeterminateSystems/determinate-nix-action@main
+ - uses: DeterminateSystems/flakehub-push@main
+ with:
+ rolling: ${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}
+ visibility: "public"
+ tag: "${{ github.ref_name }}"
+ - name: Update the release notes
+ if: startsWith(github.ref, 'refs/tags/')
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ TAG_NAME: ${{ github.ref_name }}
+ run: |
+ gh release edit "$TAG_NAME" --notes-file doc/manual/source/release-notes-determinate/"$TAG_NAME".md || true
diff --git a/.github/workflows/docker-push.yml b/.github/workflows/docker-push.yml
deleted file mode 100644
index c4ccd1fe0d0f..000000000000
--- a/.github/workflows/docker-push.yml
+++ /dev/null
@@ -1,101 +0,0 @@
-name: "Push Docker Image"
-
-on:
- workflow_call:
- inputs:
- ref:
- description: "Git ref to build the docker image from"
- required: true
- type: string
- is_master:
- description: "Whether run from master branch"
- required: true
- type: boolean
- secrets:
- DOCKERHUB_USERNAME:
- required: true
- DOCKERHUB_TOKEN:
- required: true
-
-permissions: {}
-
-jobs:
- # Steps to test CI automation in your own fork.
- # 1. Sign-up for https://hub.docker.com/
- # 2. Store your dockerhub username as DOCKERHUB_USERNAME in "Repository secrets" of your fork repository settings (https://github.com/$githubuser/nix/settings/secrets/actions)
- # 3. Create an access token in https://hub.docker.com/settings/security and store it as DOCKERHUB_TOKEN in "Repository secrets" of your fork
- check_secrets:
- permissions:
- contents: none
- name: Check presence of secrets
- runs-on: ubuntu-24.04
- outputs:
- docker: ${{ steps.secret.outputs.docker }}
- steps:
- - name: Check for DockerHub secrets
- id: secret
- env:
- _DOCKER_SECRETS: ${{ secrets.DOCKERHUB_USERNAME }}${{ secrets.DOCKERHUB_TOKEN }}
- run: |
- echo "docker=${{ env._DOCKER_SECRETS != '' }}" >> $GITHUB_OUTPUT
-
- push:
- name: Push docker image to DockerHub and GHCR
- needs: [check_secrets]
- permissions:
- contents: read
- packages: write
- if: needs.check_secrets.outputs.docker == 'true'
- runs-on: ubuntu-24.04
- steps:
- - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- with:
- fetch-depth: 0
- ref: ${{ inputs.ref }}
- - uses: ./.github/actions/install-nix-action
- with:
- dogfood: false
- extra_nix_config: |
- experimental-features = flakes nix-command
- - run: echo NIX_VERSION="$(nix eval .\#nix.version | tr -d \")" >> $GITHUB_ENV
- - run: nix build .#dockerImage -L
- - run: docker load -i ./result/image.tar.gz
- # We'll deploy the newly built image to both Docker Hub and Github Container Registry.
- #
- # Push to Docker Hub first
- - name: Login to Docker Hub
- uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
- with:
- username: ${{ secrets.DOCKERHUB_USERNAME }}
- password: ${{ secrets.DOCKERHUB_TOKEN }}
- - name: Push to Docker Hub
- env:
- IS_MASTER: ${{ inputs.is_master }}
- DOCKERHUB_REPO: ${{ secrets.DOCKERHUB_USERNAME }}/nix
- run: |
- docker tag nix:$NIX_VERSION $DOCKERHUB_REPO:$NIX_VERSION
- docker push $DOCKERHUB_REPO:$NIX_VERSION
- if [ "$IS_MASTER" = "true" ]; then
- docker tag nix:$NIX_VERSION $DOCKERHUB_REPO:master
- docker push $DOCKERHUB_REPO:master
- fi
- # Push to GitHub Container Registry as well
- - name: Login to GitHub Container Registry
- uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
- with:
- registry: ghcr.io
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
- - name: Push to GHCR
- env:
- IS_MASTER: ${{ inputs.is_master }}
- run: |
- IMAGE_ID=ghcr.io/${{ github.repository_owner }}/nix
- IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')
-
- docker tag nix:$NIX_VERSION $IMAGE_ID:$NIX_VERSION
- docker push $IMAGE_ID:$NIX_VERSION
- if [ "$IS_MASTER" = "true" ]; then
- docker tag nix:$NIX_VERSION $IMAGE_ID:master
- docker push $IMAGE_ID:master
- fi
diff --git a/.github/workflows/propose-release.yml b/.github/workflows/propose-release.yml
new file mode 100644
index 000000000000..ea01e4b7afec
--- /dev/null
+++ b/.github/workflows/propose-release.yml
@@ -0,0 +1,32 @@
+on:
+ workflow_dispatch:
+ inputs:
+ reference-id:
+ type: string
+ required: true
+ version:
+ type: string
+ required: true
+
+concurrency:
+ group: ${{ github.workflow }}
+ cancel-in-progress: true
+
+jobs:
+ propose-release:
+ uses: DeterminateSystems/propose-release/.github/workflows/workflow.yml@main
+ permissions:
+ id-token: write
+ contents: write
+ pull-requests: write
+ with:
+ update-flake: false
+ reference-id: ${{ inputs.reference-id }}
+ version: ${{ inputs.version }}
+ extra-commands-early: |
+ echo ${{ inputs.version }} > .version-determinate
+ git add .version-determinate
+ git commit -m "Set .version-determinate to ${{ inputs.version }}" || true
+ ./.github/release-notes.sh
+ git add doc
+ git commit -m "Generate release notes for ${{ inputs.version }}" || true
diff --git a/.github/workflows/upload-release.yml b/.github/workflows/upload-release.yml
deleted file mode 100644
index 82ce0c40b74d..000000000000
--- a/.github/workflows/upload-release.yml
+++ /dev/null
@@ -1,69 +0,0 @@
-name: Upload Release
-on:
- workflow_dispatch:
- inputs:
- eval_id:
- description: "Hydra evaluation ID"
- required: true
- type: number
- is_latest:
- description: "Mark as latest release"
- required: false
- type: boolean
- default: false
-permissions:
- contents: read
- id-token: write
- packages: write
-jobs:
- release:
- runs-on: ubuntu-24.04
- environment: releases
- steps:
- - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- - uses: ./.github/actions/install-nix-action
- with:
- dogfood: false # Use stable version
- use_cache: false # Don't want any cache injection shenanigans
- extra_nix_config: |
- experimental-features = nix-command flakes
- - name: Set NIX_PATH from flake input
- run: |
- NIXPKGS_PATH=$(nix build --inputs-from .# nixpkgs#path --print-out-paths --no-link)
- # Shebangs with perl have issues. Pin nixpkgs this way. nix shell should maybe
- # get the same uberhack that nix-shell has to support it.
- echo "NIX_PATH=nixpkgs=$NIXPKGS_PATH" >> "$GITHUB_ENV"
- - name: Configure AWS credentials
- uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1
- with:
- role-to-assume: "arn:aws:iam::080433136561:role/nix-release"
- role-session-name: nix-release-oidc-${{ github.run_id }}
- aws-region: eu-west-1
- - name: Login to Docker Hub
- uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
- with:
- username: ${{ secrets.DOCKERHUB_USERNAME }}
- password: ${{ secrets.DOCKERHUB_TOKEN }}
- - name: Login to GitHub Container Registry
- uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v3.6.0
- with:
- registry: ghcr.io
- username: ${{ github.actor }}
- password: ${{ secrets.GITHUB_TOKEN }}
- - name: Upload release
- run: |
- ./maintainers/upload-release.pl \
- ${{ inputs.eval_id }} \
- --skip-git
- env:
- IS_LATEST: ${{ inputs.is_latest && '1' || '' }}
- - name: Push to GHCR
- run: |
- DOCKER_OWNER="ghcr.io/$(echo '${{ github.repository_owner }}' | tr '[A-Z]' '[a-z]')/nix"
- ./maintainers/upload-release.pl \
- ${{ inputs.eval_id }} \
- --skip-git \
- --skip-s3 \
- --docker-owner "$DOCKER_OWNER"
- env:
- IS_LATEST: ${{ inputs.is_latest && '1' || '' }}
diff --git a/.version-determinate b/.version-determinate
new file mode 100644
index 000000000000..3f67e25cea13
--- /dev/null
+++ b/.version-determinate
@@ -0,0 +1 @@
+3.17.0
diff --git a/README.md b/README.md
index 02498944cdb7..c5cbcbed21bb 100644
--- a/README.md
+++ b/README.md
@@ -1,38 +1,111 @@
-# Nix
+
+
+
+
+
+
+
+
+
+
-[](https://opencollective.com/nixos)
-[](https://github.com/NixOS/nix/actions/workflows/ci.yml)
+# The Determinate Nix CLI
-Nix is a powerful package manager for Linux and other Unix systems that makes package
-management reliable and reproducible. Please refer to the [Nix manual](https://nix.dev/reference/nix-manual)
-for more details.
+[](https://github.com/DeterminateSystems/nix-src/actions/workflows/ci.yml)
-## Installation and first steps
+**Nix** is a powerful [language], [package manager][package-management], and [build tool][cli] for [macOS](#macos), [Linux](#linux), and other Unix systems.
+It enables you to create fully reproducible [development environments][envs], to build [packages] in sandboxed environments, to build entire Linux systems using [NixOS], and much more.
-Visit [nix.dev](https://nix.dev) for [installation instructions](https://nix.dev/tutorials/install-nix) and [beginner tutorials](https://nix.dev/tutorials/first-steps).
+[**Determinate Nix**][det-nix] is a downstream distribution of [Nix][upstream] created and maintained by [Determinate Systems][detsys].
+It has two components:
-Full reference documentation can be found in the [Nix manual](https://nix.dev/reference/nix-manual).
+- The Determinate Nix CLI, a distribution of the Nix CLI built from this repository.
+ It's based on the [upstream Nix CLI][upstream] and continuously rebased against it, but adds a wide variety of [features] and [improvements][changelog].
+- [Determinate Nixd][dnixd] is a useful daemon for Linux and macOS that handles vital tasks like configuration and enterprise certificate management.
-## Building and developing
+Determinate Nix is built on SOC-2-Type-II-compliant infrastructure using [Determinate Secure Packages][secure-packages], released via a carefully orchestrated process, and, for Determinate Systems customers, backed by formal security response SLAs that meet stringent compliance standards.
-Follow instructions in the Nix reference manual to [set up a development environment and build Nix from source](https://nix.dev/manual/nix/development/development/building.html).
+> [!NOTE]
+> Determinate Nix, by definition, consists of _both_ the components listed above.
+> While it's possible to use the code in this repository to run just our downstream Nix CLI, we do _not_ officially support this experience and provide none of the guarantees or SLAs that we provide for Determinate Nix proper.
-## Contributing
+Determinate Nix is part of the [Determinate platform][determinate], which also includes [FlakeHub], a secure flake repository with features like [FlakeHub Cache][cache], [private flakes][private-flakes], and [semantic versioning][semver] (SemVer) for [flakes].
+
+## Installing Determinate Nix
+
+You can install Determinate Nix on [macOS](#macos), non-NixOS [Linux](#linux) and WSL, and [NixOS](#nixos).
+
+### macOS
+
+On macOS, we recommend using the graphical installer from Determinate Systems.
+Click [here][gui] to download and run it.
+
+### Linux
+
+On Linux, including Windows Subsystem for Linux (WSL), we recommend installing Determinate Nix using [Determinate Nix Installer][installer]:
+
+```shell
+curl -fsSL https://install.determinate.systems/nix | sh -s -- install
+```
-Check the [contributing guide](./CONTRIBUTING.md) if you want to get involved with developing Nix.
+### NixOS
-## Additional resources
+On [NixOS], we recommend following our [dedicated installation guide][nixos-install].
+We also provide both [Amazon Machine Images][amis] (AMIs) and [ISOs] for using Determinate on NixOS.
-Nix was created by Eelco Dolstra and developed as the subject of his PhD thesis [The Purely Functional Software Deployment Model](https://edolstra.github.io/pubs/phd-thesis.pdf), published 2006.
-Today, a world-wide developer community contributes to Nix and the ecosystem that has grown around it.
+## Other resources
-- [The Nix, Nixpkgs, NixOS Community on nixos.org](https://nixos.org/)
-- [Official documentation on nix.dev](https://nix.dev)
-- [Nixpkgs](https://github.com/NixOS/nixpkgs) is [the largest, most up-to-date free software repository in the world](https://repology.org/repositories/graphs)
-- [NixOS](https://github.com/NixOS/nixpkgs/tree/master/nixos) is a Linux distribution that can be configured fully declaratively
-- [Discourse](https://discourse.nixos.org/)
-- Matrix: [#users:nixos.org](https://matrix.to/#/#users:nixos.org) for user support and [#nix-dev:nixos.org](https://matrix.to/#/#nix-dev:nixos.org) for development
+Nix was created by [Eelco Dolstra][eelco] and developed as the subject of his 2006 PhD thesis, [The Purely Functional Software Deployment Model][thesis].
+Today, a worldwide developer community contributes to Nix and the ecosystem that has grown around it.
+
+- [Zero to Nix][z2n], Determinate Systems' guide to Nix and [flakes] for beginners
+- [Nixpkgs], a collection of well over 100,000 software packages that you can build and manage using Nix
+- [NixOS] is a Linux distribution that can be configured fully declaratively
+- The Nix, Nixpkgs, and NixOS community on [nixos.org][website]
+
+## Reference
+
+The primary documentation for Determinate and Determinate Nix is available at [docs.determinate.systems][determinate].
+For deeply technical reference material, see the [Determinate Nix manual][manual] which is based on the upstream Nix manual.
## License
-Nix is released under the [LGPL v2.1](./COPYING).
+[Upstream Nix][upstream] is released under the [LGPL v2.1][license] license.
+[Determinate Nix][det-nix] is also released under LGPL v2.1 in accordance with the terms of the upstream license.
+
+## Contributing
+
+Check the [contributing guide][contributing] if you want to get involved with developing Nix.
+
+[amis]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html
+[cache]: https://docs.determinate.systems/flakehub/cache
+[changelog]: https://determinate.systems/blog/categories/changelog
+[cli]: https://manual.determinate.systems/command-ref/new-cli/nix.html
+[contributing]: ./CONTRIBUTING.md
+[det-nix]: https://docs.determinate.systems/determinate-nix
+[determinate]: https://docs.determinate.systems
+[detsys]: https://determinate.systems
+[dnixd]: https://docs.determinate.systems/determinate-nix#determinate-nixd
+[eelco]: https://determinate.systems/people/eelco-dolstra
+[envs]: https://zero-to-nix.com/concepts/dev-env
+[features]: https://docs.determinate.systems/determinate-nix/#special-features
+[flakehub]: https://flakehub.com
+[flakes]: https://zero-to-nix.com/concepts/flakes
+[gui]: https://install.determinate.systems/determinate-pkg/stable/Universal
+[installer]: https://github.com/DeterminateSystems/nix-installer
+[isos]: https://github.com/DeterminateSystems/nixos-iso
+[language]: https://zero-to-nix.com/concepts/nix-language
+[license]: ./COPYING
+[manual]: https://manual.determinate.systems
+[nixpkgs]: https://github.com/NixOS/nixpkgs
+[nixos]: https://github.com/NixOS/nixpkgs/tree/master/nixos
+[nixos-install]: https://docs.determinate.systems/guides/advanced-installation#nixos
+[packages]: https://zero-to-nix.com/concepts/packages
+[package-management]: https://zero-to-nix.com/concepts/package-management
+[private-flakes]: https://docs.determinate.systems/flakehub/private-flakes
+[secure-packages]: https://determinate.systems/secure-packages
+[semver]: https://docs.determinate.systems/flakehub/concepts/semver
+[thesis]: https://edolstra.github.io/pubs/phd-thesis.pdf
+[upstream]: https://github.com/NixOS/nix
+[website]: https://nixos.org
+[z2n]: https://zero-to-nix.com
diff --git a/ci/gha/tests/default.nix b/ci/gha/tests/default.nix
index 6100f2f4172e..4a30a96a475d 100644
--- a/ci/gha/tests/default.nix
+++ b/ci/gha/tests/default.nix
@@ -76,13 +76,17 @@ rec {
*/
topLevel = {
installerScriptForGHA = hydraJobs.installerScriptForGHA.${system};
- installTests = hydraJobs.installTests.${system};
nixpkgsLibTests = hydraJobs.tests.nixpkgsLibTests.${system};
rl-next = pkgs.buildPackages.runCommand "test-rl-next-release-notes" { } ''
LANG=C.UTF-8 ${pkgs.changelog-d}/bin/changelog-d ${../../../doc/manual/rl-next} >$out
'';
repl-completion = pkgs.callPackage ../../../tests/repl-completion.nix { inherit (packages') nix; };
+ lazyTrees = nixComponents.nix-functional-tests.override {
+ pname = "nix-lazy-trees-tests";
+ lazyTrees = true;
+ };
+
/**
Checks for our packaging expressions.
This shouldn't build anything significant; just check that things
diff --git a/default.nix b/default.nix
deleted file mode 100644
index 6466507b7140..000000000000
--- a/default.nix
+++ /dev/null
@@ -1,9 +0,0 @@
-(import (
- let
- lock = builtins.fromJSON (builtins.readFile ./flake.lock);
- in
- fetchTarball {
- url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
- sha256 = lock.nodes.flake-compat.locked.narHash;
- }
-) { src = ./.; }).defaultNix
diff --git a/doc/manual/book.toml.in b/doc/manual/book.toml.in
index c798afc4a8c0..11efca75f110 100644
--- a/doc/manual/book.toml.in
+++ b/doc/manual/book.toml.in
@@ -1,12 +1,12 @@
[book]
-title = "Nix @version@ Reference Manual"
+title = "Determinate Nix @version@ Reference Manual"
src = "source"
[output.html]
additional-css = ["custom.css"]
additional-js = ["redirects.js"]
-edit-url-template = "https://github.com/NixOS/nix/tree/master/doc/manual/{path}"
-git-repository-url = "https://github.com/NixOS/nix"
+edit-url-template = "https://github.com/DeterminateSystems/nix-src/tree/master/doc/manual/{path}"
+git-repository-url = "https://github.com/DeterminateSystems/nix-src"
mathjax-support = true
# Handles replacing @docroot@ with a path to ./source relative to that markdown file,
diff --git a/doc/manual/custom.css b/doc/manual/custom.css
index 7af150be391b..119c6d125430 100644
--- a/doc/manual/custom.css
+++ b/doc/manual/custom.css
@@ -1,5 +1,5 @@
:root {
- --sidebar-width: 23em;
+ --sidebar-width: 23em;
}
h1.menu-title::before {
@@ -7,11 +7,10 @@ h1.menu-title::before {
background-image: url("./favicon.svg");
padding: 1.25em;
background-position: center center;
- background-size: 2em;
+ background-size: 1.5em;
background-repeat: no-repeat;
}
-
.menu-bar {
padding: 0.5em 0em;
}
@@ -21,13 +20,13 @@ h1.menu-title::before {
}
h1:not(:first-of-type) {
- margin-top: 1.3em;
+ margin-top: 1.3em;
}
h2 {
- margin-top: 1em;
+ margin-top: 1em;
}
.hljs-meta {
- user-select: none;
+ user-select: none;
}
diff --git a/doc/manual/generate-manpage.nix b/doc/manual/generate-manpage.nix
index 31e74e17d264..292cb283d3d6 100644
--- a/doc/manual/generate-manpage.nix
+++ b/doc/manual/generate-manpage.nix
@@ -42,11 +42,6 @@ let
let
result = ''
- > **Warning** \
- > This program is
- > [**experimental**](@docroot@/development/experimental-features.md#xp-feature-nix-command)
- > and its interface is subject to change.
-
# Name
`${command}` - ${details.description}
diff --git a/doc/manual/meson.build b/doc/manual/meson.build
index 3c3e79541139..1b9a325df2ac 100644
--- a/doc/manual/meson.build
+++ b/doc/manual/meson.build
@@ -5,19 +5,9 @@ project(
license : 'LGPL-2.1-or-later',
)
-# Compute documentation URL based on version and release type
-version = meson.project_version()
-official_release = get_option('official-release')
+fs = import('fs')
-if official_release
- # For official releases, use versioned URL (dropping patch version)
- version_parts = version.split('.')
- major_minor = '@0@.@1@'.format(version_parts[0], version_parts[1])
- doc_url = 'https://nix.dev/manual/nix/@0@'.format(major_minor)
-else
- # For development builds, use /latest
- doc_url = 'https://nix.dev/manual/nix/latest'
-endif
+doc_url = 'https://manual.determinate.systems/'
nix = find_program('nix', native : true)
@@ -40,7 +30,7 @@ nix_env_for_docs = {
'NIX_CONFIG' : 'cores = 0',
}
-nix_for_docs = [ nix, '--experimental-features', 'nix-command' ]
+nix_for_docs = [ nix ]
nix_eval_for_docs_common = nix_for_docs + [
'eval',
'-I',
@@ -137,7 +127,7 @@ if get_option('html-manual')
python.full_path(),
mdbook.full_path(),
meson.current_build_dir(),
- meson.project_version(),
+ fs.read('../../.version-determinate').strip(),
rsync.full_path(),
),
],
diff --git a/doc/manual/package.nix b/doc/manual/package.nix
index 3a90a0faf8a0..0b3d8ca940a2 100644
--- a/doc/manual/package.nix
+++ b/doc/manual/package.nix
@@ -34,7 +34,7 @@ let
in
mkMesonDerivation (finalAttrs: {
- pname = "nix-manual";
+ pname = "determinate-nix-manual";
inherit version;
workDir = ./.;
@@ -42,6 +42,7 @@ mkMesonDerivation (finalAttrs: {
fileset.difference
(fileset.unions [
../../.version
+ ../../.version-determinate
# For example JSON
../../src/libutil-tests/data/memory-source-accessor
../../src/libutil-tests/data/hash
diff --git a/doc/manual/redirects.json b/doc/manual/redirects.json
index 0a6c71508006..07a6f36627ff 100644
--- a/doc/manual/redirects.json
+++ b/doc/manual/redirects.json
@@ -243,29 +243,11 @@
"gloss-validity": "glossary.html#gloss-validity",
"part-glossary": "glossary.html",
"sec-building-source": "installation/building-source.html",
- "ch-env-variables": "installation/env-variables.html",
- "sec-installer-proxy-settings": "installation/env-variables.html#proxy-environment-variables",
- "sec-nix-ssl-cert-file": "installation/env-variables.html#nix_ssl_cert_file",
- "sec-nix-ssl-cert-file-with-nix-daemon-and-macos": "installation/env-variables.html#nix_ssl_cert_file",
"chap-installation": "installation/index.html",
- "ch-installing-binary": "installation/installing-binary.html",
- "sect-macos-installation": "installation/installing-binary.html#macos-installation",
- "sect-macos-installation-change-store-prefix": "installation/installing-binary.html#macos-installation",
- "sect-macos-installation-encrypted-volume": "installation/installing-binary.html#macos-installation",
- "sect-macos-installation-recommended-notes": "installation/installing-binary.html#macos-installation",
- "sect-macos-installation-symlink": "installation/installing-binary.html#macos-installation",
- "sect-multi-user-installation": "installation/installing-binary.html#multi-user-installation",
- "sect-nix-install-binary-tarball": "installation/installing-binary.html#installing-from-a-binary-tarball",
- "sect-nix-install-pinned-version-url":
- "installation/installing-binary.html#installing-a-pinned-nix-version-from-a-url",
- "sect-single-user-installation": "installation/installing-binary.html#single-user-installation",
"ch-installing-source": "installation/installing-source.html",
- "ssec-multi-user": "installation/multi-user.html",
"ch-nix-security": "installation/nix-security.html",
"sec-obtaining-source": "installation/obtaining-source.html",
"sec-prerequisites-source": "installation/prerequisites-source.html",
- "sec-single-user": "installation/single-user.html",
- "ch-supported-platforms": "installation/supported-platforms.html",
"ch-upgrading-nix": "installation/upgrading.html",
"ch-about-nix": "introduction.html",
"chap-introduction": "introduction.html",
@@ -287,43 +269,7 @@
"sec-sharing-packages": "package-management/sharing-packages.html",
"ssec-ssh-substituter": "package-management/ssh-substituter.html",
"chap-quick-start": "quick-start.html",
- "sec-relnotes": "release-notes/index.html",
- "ch-relnotes-0.10.1": "release-notes/rl-0.10.1.html",
- "ch-relnotes-0.10": "release-notes/rl-0.10.html",
- "ssec-relnotes-0.11": "release-notes/rl-0.11.html",
- "ssec-relnotes-0.12": "release-notes/rl-0.12.html",
- "ssec-relnotes-0.13": "release-notes/rl-0.13.html",
- "ssec-relnotes-0.14": "release-notes/rl-0.14.html",
- "ssec-relnotes-0.15": "release-notes/rl-0.15.html",
- "ssec-relnotes-0.16": "release-notes/rl-0.16.html",
- "ch-relnotes-0.5": "release-notes/rl-0.5.html",
- "ch-relnotes-0.6": "release-notes/rl-0.6.html",
- "ch-relnotes-0.7": "release-notes/rl-0.7.html",
- "ch-relnotes-0.8.1": "release-notes/rl-0.8.1.html",
- "ch-relnotes-0.8": "release-notes/rl-0.8.html",
- "ch-relnotes-0.9.1": "release-notes/rl-0.9.1.html",
- "ch-relnotes-0.9.2": "release-notes/rl-0.9.2.html",
- "ch-relnotes-0.9": "release-notes/rl-0.9.html",
- "ssec-relnotes-1.0": "release-notes/rl-1.0.html",
- "ssec-relnotes-1.1": "release-notes/rl-1.1.html",
- "ssec-relnotes-1.10": "release-notes/rl-1.10.html",
- "ssec-relnotes-1.11.10": "release-notes/rl-1.11.10.html",
- "ssec-relnotes-1.11": "release-notes/rl-1.11.html",
- "ssec-relnotes-1.2": "release-notes/rl-1.2.html",
- "ssec-relnotes-1.3": "release-notes/rl-1.3.html",
- "ssec-relnotes-1.4": "release-notes/rl-1.4.html",
- "ssec-relnotes-1.5.1": "release-notes/rl-1.5.html",
- "ssec-relnotes-1.5.2": "release-notes/rl-1.5.2.html",
- "ssec-relnotes-1.5": "release-notes/rl-1.5.html",
- "ssec-relnotes-1.6.1": "release-notes/rl-1.6.1.html",
- "ssec-relnotes-1.6.0": "release-notes/rl-1.6.html",
- "ssec-relnotes-1.7": "release-notes/rl-1.7.html",
- "ssec-relnotes-1.8": "release-notes/rl-1.8.html",
- "ssec-relnotes-1.9": "release-notes/rl-1.9.html",
- "ssec-relnotes-2.0": "release-notes/rl-2.0.html",
- "ssec-relnotes-2.1": "release-notes/rl-2.1.html",
- "ssec-relnotes-2.2": "release-notes/rl-2.2.html",
- "ssec-relnotes-2.3": "release-notes/rl-2.3.html"
+ "sec-relnotes": "release-notes/index.html"
},
"language/types.html": {
"simple-values": "#primitives",
@@ -340,12 +286,10 @@
"builder-execution": "../store/building.html#builder-execution"
},
"installation/installing-binary.html": {
- "linux": "uninstall.html#linux",
- "macos": "uninstall.html#macos",
"uninstalling": "uninstall.html"
},
"development/building.html": {
- "nix-with-flakes": "#building-nix-with-flakes",
+ "nix-with-flakes": "#building-nix",
"classic-nix": "#building-nix",
"running-tests": "testing.html#running-tests",
"unit-tests": "testing.html#unit-tests",
diff --git a/doc/manual/rl-next/c-api-new-store-methods.md b/doc/manual/rl-next/c-api-new-store-methods.md
new file mode 100644
index 000000000000..28792e7cc42d
--- /dev/null
+++ b/doc/manual/rl-next/c-api-new-store-methods.md
@@ -0,0 +1,9 @@
+---
+synopsis: "C API: New store API methods"
+prs: [14766]
+---
+
+The C API now includes additional methods:
+
+- `nix_store_query_path_from_hash_part()` - Get the full store path given its hash part
+- `nix_store_copy_path()` - Copy a single store path between two stores, allows repairs and configuring signature checking
diff --git a/doc/manual/rl-next/shorter-build-dir-names.md b/doc/manual/rl-next/shorter-build-dir-names.md
new file mode 100644
index 000000000000..e87fa5d04fb8
--- /dev/null
+++ b/doc/manual/rl-next/shorter-build-dir-names.md
@@ -0,0 +1,6 @@
+---
+synopsis: "Temporary build directories no longer include derivation names"
+prs: [13839]
+---
+
+Temporary build directories created during derivation builds no longer include the derivation name in their path to avoid build failures when the derivation name is too long. This change ensures predictable prefix lengths for build directories under `/nix/var/nix/builds`.
\ No newline at end of file
diff --git a/doc/manual/source/SUMMARY.md.in b/doc/manual/source/SUMMARY.md.in
index 8b6b29f6a7ff..df8f10dcda7f 100644
--- a/doc/manual/source/SUMMARY.md.in
+++ b/doc/manual/source/SUMMARY.md.in
@@ -3,17 +3,12 @@
- [Introduction](introduction.md)
- [Quick Start](quick-start.md)
- [Installation](installation/index.md)
- - [Supported Platforms](installation/supported-platforms.md)
- - [Installing a Binary Distribution](installation/installing-binary.md)
- [Installing Nix from Source](installation/installing-source.md)
- [Prerequisites](installation/prerequisites-source.md)
- [Obtaining a Source Distribution](installation/obtaining-source.md)
- [Building Nix from Source](installation/building-source.md)
- [Using Nix within Docker](installation/installing-docker.md)
- [Security](installation/nix-security.md)
- - [Single-User Mode](installation/single-user.md)
- - [Multi-User Mode](installation/multi-user.md)
- - [Environment Variables](installation/env-variables.md)
- [Upgrading Nix](installation/upgrading.md)
- [Uninstalling Nix](installation/uninstall.md)
- [Nix Store](store/index.md)
@@ -65,8 +60,11 @@
- [Command Reference](command-ref/index.md)
- [Common Options](command-ref/opt-common.md)
- [Common Environment Variables](command-ref/env-common.md)
- - [Main Commands](command-ref/main-commands.md)
+ - [Subcommands](command-ref/subcommands.md)
+{{#include ./command-ref/new-cli/SUMMARY.md}}
+ - [Deprecated Commands](command-ref/main-commands.md)
- [nix-build](command-ref/nix-build.md)
+ - [nix-channel](command-ref/nix-channel.md)
- [nix-shell](command-ref/nix-shell.md)
- [nix-store](command-ref/nix-store.md)
- [nix-store --add-fixed](command-ref/nix-store/add-fixed.md)
@@ -102,22 +100,17 @@
- [nix-env --uninstall](command-ref/nix-env/uninstall.md)
- [nix-env --upgrade](command-ref/nix-env/upgrade.md)
- [Utilities](command-ref/utilities.md)
- - [nix-channel](command-ref/nix-channel.md)
- [nix-collect-garbage](command-ref/nix-collect-garbage.md)
- [nix-copy-closure](command-ref/nix-copy-closure.md)
- [nix-daemon](command-ref/nix-daemon.md)
- [nix-hash](command-ref/nix-hash.md)
- [nix-instantiate](command-ref/nix-instantiate.md)
- [nix-prefetch-url](command-ref/nix-prefetch-url.md)
- - [Experimental Commands](command-ref/experimental-commands.md)
-{{#include ./command-ref/new-cli/SUMMARY.md}}
- [Files](command-ref/files.md)
- [nix.conf](command-ref/conf-file.md)
- [Profiles](command-ref/files/profiles.md)
- [manifest.nix](command-ref/files/manifest.nix.md)
- [manifest.json](command-ref/files/manifest.json.md)
- - [Channels](command-ref/files/channels.md)
- - [Default Nix expression](command-ref/files/default-nix-expression.md)
- [Architecture and Design](architecture/architecture.md)
- [Formats and Protocols](protocols/index.md)
- [JSON Formats](protocols/json/index.md)
@@ -136,6 +129,8 @@
- [Store Path Specification](protocols/store-path.md)
- [Nix Archive (NAR) Format](protocols/nix-archive/index.md)
- [Derivation "ATerm" file format](protocols/derivation-aterm.md)
+ - [`builtins.wasm` Host Interface](protocols/wasm.md)
+ - [Flake Schemas](protocols/flake-schemas.md)
- [C API](c-api.md)
- [Glossary](glossary.md)
- [Development](development/index.md)
@@ -149,7 +144,55 @@
- [C++ style guide](development/cxx.md)
- [Experimental Features](development/experimental-features.md)
- [Contributing](development/contributing.md)
-- [Releases](release-notes/index.md)
+- [Determinate Nix Release Notes](release-notes-determinate/index.md)
+ - [Changes between Nix and Determinate Nix](release-notes-determinate/changes.md)
+ - [Release 3.17.0 (2026-03-04)](release-notes-determinate/v3.17.0.md)
+ - [Release 3.16.3 (2026-02-24)](release-notes-determinate/v3.16.3.md)
+ - [Release 3.16.2 (2026-02-23)](release-notes-determinate/v3.16.2.md)
+ - [Release 3.16.1 (2026-02-22)](release-notes-determinate/v3.16.1.md)
+ - [Release 3.16.0 (2026-02-12)](release-notes-determinate/v3.16.0.md)
+ - [Release 3.15.2 (2026-01-20)](release-notes-determinate/v3.15.2.md)
+ - [Release 3.15.1 (2025-12-24)](release-notes-determinate/v3.15.1.md)
+ - [Release 3.15.0 (2025-12-19)](release-notes-determinate/v3.15.0.md)
+ - [Release 3.14.0 (2025-12-08)](release-notes-determinate/v3.14.0.md)
+ - [Release 3.13.2 (2025-11-19)](release-notes-determinate/v3.13.2.md)
+ - [Release 3.13.1 (2025-11-12)](release-notes-determinate/v3.13.1.md)
+ - [Release 3.13.0 (2025-11-09)](release-notes-determinate/v3.13.0.md)
+ - [Release 3.12.2 (2025-11-05)](release-notes-determinate/v3.12.2.md)
+ - [Release 3.12.1 (2025-11-04)](release-notes-determinate/v3.12.1.md)
+ - [Release 3.12.0 (2025-10-23)](release-notes-determinate/v3.12.0.md)
+ - [Release 3.11.3 (2025-10-09)](release-notes-determinate/v3.11.3.md)
+ - [Release 3.11.2 (2025-09-12)](release-notes-determinate/v3.11.2.md)
+ - [Release 3.11.1 (2025-09-04)](release-notes-determinate/v3.11.1.md)
+ - [Release 3.11.0 (2025-09-03)](release-notes-determinate/v3.11.0.md)
+ - [Release 3.10.1 (2025-09-02)](release-notes-determinate/v3.10.1.md)
+ - [Release 3.10.0 (2025-09-02)](release-notes-determinate/v3.10.0.md)
+ - [Release 3.9.1 (2025-08-28)](release-notes-determinate/v3.9.1.md)
+ - [Release 3.9.0 (2025-08-26)](release-notes-determinate/v3.9.0.md)
+ - [Release 3.8.6 (2025-08-19)](release-notes-determinate/v3.8.6.md)
+ - [Release 3.8.5 (2025-08-04)](release-notes-determinate/rl-3.8.5.md)
+ - [Release 3.8.4 (2025-07-21)](release-notes-determinate/rl-3.8.4.md)
+ - [Release 3.8.3 (2025-07-18)](release-notes-determinate/rl-3.8.3.md)
+ - [Release 3.8.2 (2025-07-12)](release-notes-determinate/rl-3.8.2.md)
+ - [Release 3.8.1 (2025-07-11)](release-notes-determinate/rl-3.8.1.md)
+ - [Release 3.8.0 (2025-07-10)](release-notes-determinate/rl-3.8.0.md)
+ - [Release 3.7.0 (2025-07-03)](release-notes-determinate/rl-3.7.0.md)
+ - [Release 3.6.8 (2025-06-25)](release-notes-determinate/rl-3.6.8.md)
+ - [Release 3.6.7 (2025-06-24)](release-notes-determinate/rl-3.6.7.md)
+ - [Release 3.6.6 (2025-06-17)](release-notes-determinate/rl-3.6.6.md)
+ - [Release 3.6.5 (2025-06-16)](release-notes-determinate/rl-3.6.5.md)
+ - [Release 3.6.2 (2025-06-02)](release-notes-determinate/rl-3.6.2.md)
+ - [Release 3.6.1 (2025-05-24)](release-notes-determinate/rl-3.6.1.md)
+ - [Release 3.6.0 (2025-05-22)](release-notes-determinate/rl-3.6.0.md)
+ - [Release 3.5.2 (2025-05-12)](release-notes-determinate/rl-3.5.2.md)
+ - [Release 3.5.1 (2025-05-09)](release-notes-determinate/rl-3.5.1.md)
+ - [~~Release 3.5.0 (2025-05-09)~~](release-notes-determinate/rl-3.5.0.md)
+ - [Release 3.4.2 (2025-05-05)](release-notes-determinate/rl-3.4.2.md)
+ - [Release 3.4.0 (2025-04-25)](release-notes-determinate/rl-3.4.0.md)
+ - [Release 3.3.0 (2025-04-11)](release-notes-determinate/rl-3.3.0.md)
+ - [Release 3.1.0 (2025-03-27)](release-notes-determinate/rl-3.1.0.md)
+ - [Release 3.0.0 (2025-03-04)](release-notes-determinate/rl-3.0.0.md)
+- [Nix Release Notes](release-notes/index.md)
{{#include ./SUMMARY-rl-next.md}}
- [Release 2.33 (2025-12-09)](release-notes/rl-2.33.md)
- [Release 2.32 (2025-10-06)](release-notes/rl-2.32.md)
@@ -159,60 +202,3 @@
- [Release 2.28 (2025-04-02)](release-notes/rl-2.28.md)
- [Release 2.27 (2025-03-03)](release-notes/rl-2.27.md)
- [Release 2.26 (2025-01-22)](release-notes/rl-2.26.md)
- - [Release 2.25 (2024-11-07)](release-notes/rl-2.25.md)
- - [Release 2.24 (2024-07-31)](release-notes/rl-2.24.md)
- - [Release 2.23 (2024-06-03)](release-notes/rl-2.23.md)
- - [Release 2.22 (2024-04-23)](release-notes/rl-2.22.md)
- - [Release 2.21 (2024-03-11)](release-notes/rl-2.21.md)
- - [Release 2.20 (2024-01-29)](release-notes/rl-2.20.md)
- - [Release 2.19 (2023-11-17)](release-notes/rl-2.19.md)
- - [Release 2.18 (2023-09-20)](release-notes/rl-2.18.md)
- - [Release 2.17 (2023-07-24)](release-notes/rl-2.17.md)
- - [Release 2.16 (2023-05-31)](release-notes/rl-2.16.md)
- - [Release 2.15 (2023-04-11)](release-notes/rl-2.15.md)
- - [Release 2.14 (2023-02-28)](release-notes/rl-2.14.md)
- - [Release 2.13 (2023-01-17)](release-notes/rl-2.13.md)
- - [Release 2.12 (2022-12-06)](release-notes/rl-2.12.md)
- - [Release 2.11 (2022-08-25)](release-notes/rl-2.11.md)
- - [Release 2.10 (2022-07-11)](release-notes/rl-2.10.md)
- - [Release 2.9 (2022-05-30)](release-notes/rl-2.9.md)
- - [Release 2.8 (2022-04-19)](release-notes/rl-2.8.md)
- - [Release 2.7 (2022-03-07)](release-notes/rl-2.7.md)
- - [Release 2.6 (2022-01-24)](release-notes/rl-2.6.md)
- - [Release 2.5 (2021-12-13)](release-notes/rl-2.5.md)
- - [Release 2.4 (2021-11-01)](release-notes/rl-2.4.md)
- - [Release 2.3 (2019-09-04)](release-notes/rl-2.3.md)
- - [Release 2.2 (2019-01-11)](release-notes/rl-2.2.md)
- - [Release 2.1 (2018-09-02)](release-notes/rl-2.1.md)
- - [Release 2.0 (2018-02-22)](release-notes/rl-2.0.md)
- - [Release 1.11.10 (2017-06-12)](release-notes/rl-1.11.10.md)
- - [Release 1.11 (2016-01-19)](release-notes/rl-1.11.md)
- - [Release 1.10 (2015-09-03)](release-notes/rl-1.10.md)
- - [Release 1.9 (2015-06-12)](release-notes/rl-1.9.md)
- - [Release 1.8 (2014-12-14)](release-notes/rl-1.8.md)
- - [Release 1.7 (2014-04-11)](release-notes/rl-1.7.md)
- - [Release 1.6.1 (2013-10-28)](release-notes/rl-1.6.1.md)
- - [Release 1.6 (2013-09-10)](release-notes/rl-1.6.md)
- - [Release 1.5.2 (2013-05-13)](release-notes/rl-1.5.2.md)
- - [Release 1.5 (2013-02-27)](release-notes/rl-1.5.md)
- - [Release 1.4 (2013-02-26)](release-notes/rl-1.4.md)
- - [Release 1.3 (2013-01-04)](release-notes/rl-1.3.md)
- - [Release 1.2 (2012-12-06)](release-notes/rl-1.2.md)
- - [Release 1.1 (2012-07-18)](release-notes/rl-1.1.md)
- - [Release 1.0 (2012-05-11)](release-notes/rl-1.0.md)
- - [Release 0.16 (2010-08-17)](release-notes/rl-0.16.md)
- - [Release 0.15 (2010-03-17)](release-notes/rl-0.15.md)
- - [Release 0.14 (2010-02-04)](release-notes/rl-0.14.md)
- - [Release 0.13 (2009-11-05)](release-notes/rl-0.13.md)
- - [Release 0.12 (2008-11-20)](release-notes/rl-0.12.md)
- - [Release 0.11 (2007-12-31)](release-notes/rl-0.11.md)
- - [Release 0.10.1 (2006-10-11)](release-notes/rl-0.10.1.md)
- - [Release 0.10 (2006-10-06)](release-notes/rl-0.10.md)
- - [Release 0.9.2 (2005-09-21)](release-notes/rl-0.9.2.md)
- - [Release 0.9.1 (2005-09-20)](release-notes/rl-0.9.1.md)
- - [Release 0.9 (2005-09-16)](release-notes/rl-0.9.md)
- - [Release 0.8.1 (2005-04-13)](release-notes/rl-0.8.1.md)
- - [Release 0.8 (2005-04-11)](release-notes/rl-0.8.md)
- - [Release 0.7 (2005-01-12)](release-notes/rl-0.7.md)
- - [Release 0.6 (2004-11-14)](release-notes/rl-0.6.md)
- - [Release 0.5 and earlier](release-notes/rl-0.5.md)
diff --git a/doc/manual/source/advanced-topics/distributed-builds.md b/doc/manual/source/advanced-topics/distributed-builds.md
index 08a980643e88..c39cf4500795 100644
--- a/doc/manual/source/advanced-topics/distributed-builds.md
+++ b/doc/manual/source/advanced-topics/distributed-builds.md
@@ -5,8 +5,8 @@ this allows multiple builds to be performed in parallel.
Remote builds also allow Nix to perform multi-platform builds in a
semi-transparent way. For example, if you perform a build for a
-`x86_64-darwin` on an `i686-linux` machine, Nix can automatically
-forward the build to a `x86_64-darwin` machine, if one is available.
+`aarch64-darwin` on an `x86_64-linux` machine, Nix can automatically
+forward the build to a `aarch64-darwin` machine, if one is available.
## Requirements
@@ -59,7 +59,7 @@ then you need to ensure that the `PATH` of non-interactive login shells
contains Nix.
The [list of remote build machines](@docroot@/command-ref/conf-file.md#conf-builders) can be specified on the command line or in the Nix configuration file.
-For example, the following command allows you to build a derivation for `x86_64-darwin` on a Linux machine:
+For example, the following command allows you to build a derivation for `aarch64-darwin` on a Linux machine:
```console
uname
@@ -71,8 +71,8 @@ Linux
```console
nix build --impure \
- --expr '(with import { system = "x86_64-darwin"; }; runCommand "foo" {} "uname > $out")' \
- --builders 'ssh://mac x86_64-darwin'
+ --expr '(with import { system = "aarch64-darwin"; }; runCommand "foo" {} "uname > $out")' \
+ --builders 'ssh://mac aarch64-darwin'
```
```console
@@ -90,12 +90,12 @@ Darwin
It is possible to specify multiple build machines separated by a semicolon or a newline, e.g.
```console
- --builders 'ssh://mac x86_64-darwin ; ssh://beastie x86_64-freebsd'
+ --builders 'ssh://mac aarch64-darwin ; ssh://beastie x86_64-freebsd'
```
Remote build machines can also be configured in [`nix.conf`](@docroot@/command-ref/conf-file.md), e.g.
- builders = ssh://mac x86_64-darwin ; ssh://beastie x86_64-freebsd
+ builders = ssh://mac aarch64-darwin ; ssh://beastie x86_64-freebsd
After making changes to `nix.conf`, restart the Nix daemon for changes to take effect.
@@ -107,4 +107,4 @@ file included in `builders` via the syntax `@/path/to/file`. For example,
causes the list of machines in `/etc/nix/machines` to be included.
(This is the default.)
-[Nix instance]: @docroot@/glossary.md#gloss-nix-instance
\ No newline at end of file
+[Nix instance]: @docroot@/glossary.md#gloss-nix-instance
diff --git a/doc/manual/source/advanced-topics/eval-profiler.md b/doc/manual/source/advanced-topics/eval-profiler.md
index ed3848bb2db4..2bc7ebb05e00 100644
--- a/doc/manual/source/advanced-topics/eval-profiler.md
+++ b/doc/manual/source/advanced-topics/eval-profiler.md
@@ -27,7 +27,7 @@ site](https://en.wikipedia.org/wiki/Call_site) position and the name of the
function being called (when available). For example:
```
-/nix/store/x9wnkly3k1gkq580m90jjn32q9f05q2v-source/pkgs/top-level/default.nix:167:5:primop import
+/nix/store/2q71fdvr4h33g9832hiriwnf20fn630l-source/pkgs/top-level/default.nix:167:5:primop import
```
-Here `import` primop is called at `/nix/store/x9wnkly3k1gkq580m90jjn32q9f05q2v-source/pkgs/top-level/default.nix:167:5`.
+Here `import` primop is called at `/nix/store/2q71fdvr4h33g9832hiriwnf20fn630l-source/pkgs/top-level/default.nix:167:5`.
diff --git a/doc/manual/source/command-ref/env-common.md b/doc/manual/source/command-ref/env-common.md
index e0fd2b00eec3..fe6e822ff16a 100644
--- a/doc/manual/source/command-ref/env-common.md
+++ b/doc/manual/source/command-ref/env-common.md
@@ -102,7 +102,7 @@ Most Nix commands interpret the following environment variables:
This variable should be set to `daemon` if you want to use the Nix
daemon to execute Nix operations. This is necessary in [multi-user
- Nix installations](@docroot@/installation/multi-user.md). If the Nix
+ Nix installations](@docroot@/installation/nix-security.md#multi-user-model). If the Nix
daemon's Unix socket is at some non-standard path, this variable
should be set to `unix://path/to/socket`. Otherwise, it should be
left unset.
diff --git a/doc/manual/source/command-ref/experimental-commands.md b/doc/manual/source/command-ref/experimental-commands.md
deleted file mode 100644
index 1190729a2305..000000000000
--- a/doc/manual/source/command-ref/experimental-commands.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# Experimental Commands
-
-This section lists [experimental commands](@docroot@/development/experimental-features.md#xp-feature-nix-command).
-
-> **Warning**
->
-> These commands may be removed in the future, or their syntax may
-> change in incompatible ways.
diff --git a/doc/manual/source/command-ref/files/default-nix-expression.md b/doc/manual/source/command-ref/files/default-nix-expression.md
index 2bd45ff5debd..e886e3ff4991 100644
--- a/doc/manual/source/command-ref/files/default-nix-expression.md
+++ b/doc/manual/source/command-ref/files/default-nix-expression.md
@@ -31,12 +31,12 @@ Then, the resulting expression is interpreted like this:
The file [`manifest.nix`](@docroot@/command-ref/files/manifest.nix.md) is always ignored.
-The command [`nix-channel`] places a symlink to the current user's [channels] in this directory, the [user channel link](#user-channel-link).
+The command [`nix-channel`] places a symlink to the current user's channels in this directory, the [user channel link](#user-channel-link).
This makes all subscribed channels available as attributes in the default expression.
## User channel link
-A symlink that ensures that [`nix-env`] can find the current user's [channels]:
+A symlink that ensures that [`nix-env`] can find the current user's channels:
- `~/.nix-defexpr/channels`
- `$XDG_STATE_HOME/defexpr/channels` if [`use-xdg-base-directories`] is set to `true`.
@@ -51,4 +51,3 @@ In a multi-user installation, you may also have `~/.nix-defexpr/channels_root`,
[`nix-channel`]: @docroot@/command-ref/nix-channel.md
[`nix-env`]: @docroot@/command-ref/nix-env.md
[`use-xdg-base-directories`]: @docroot@/command-ref/conf-file.md#conf-use-xdg-base-directories
-[channels]: @docroot@/command-ref/files/channels.md
diff --git a/doc/manual/source/command-ref/files/manifest.nix.md b/doc/manual/source/command-ref/files/manifest.nix.md
index d7d1b605b54b..78bfdc346eaf 100644
--- a/doc/manual/source/command-ref/files/manifest.nix.md
+++ b/doc/manual/source/command-ref/files/manifest.nix.md
@@ -114,9 +114,9 @@ Here is an example of how this file might look like after installing `hello` fro
};
name = "hello-2.12.1";
out = {
- outPath = "/nix/store/260q5867crm1xjs4khgqpl6vr9kywql1-hello-2.12.1";
+ outPath = "/nix/store/src1vzij2z0slnakrsbpqpk20389z0k6-hello-2.12.1";
};
- outPath = "/nix/store/260q5867crm1xjs4khgqpl6vr9kywql1-hello-2.12.1";
+ outPath = "/nix/store/src1vzij2z0slnakrsbpqpk20389z0k6-hello-2.12.1";
outputs = [ "out" ];
system = "x86_64-linux";
type = "derivation";
diff --git a/doc/manual/source/command-ref/files/profiles.md b/doc/manual/source/command-ref/files/profiles.md
index b5c7378800fd..f137336747f1 100644
--- a/doc/manual/source/command-ref/files/profiles.md
+++ b/doc/manual/source/command-ref/files/profiles.md
@@ -37,13 +37,13 @@ dr-xr-xr-x 4 root root 4096 Jan 1 1970 share
/home/eelco/.local/state/nix/profiles/profile-7-link/bin:
total 20
-lrwxrwxrwx 5 root root 79 Jan 1 1970 chromium -> /nix/store/ijm5k0zqisvkdwjkc77mb9qzb35xfi4m-chromium-86.0.4240.111/bin/chromium
+lrwxrwxrwx 5 root root 79 Jan 1 1970 chromium -> /nix/store/cyxny9d1zjb9l9103fr6j6kavp3bqjxf-chromium-86.0.4240.111/bin/chromium
lrwxrwxrwx 7 root root 87 Jan 1 1970 spotify -> /nix/store/w9182874m1bl56smps3m5zjj36jhp3rn-spotify-1.1.26.501.gbe11e53b-15/bin/spotify
lrwxrwxrwx 3 root root 79 Jan 1 1970 zoom-us -> /nix/store/wbhg2ga8f3h87s9h5k0slxk0m81m4cxl-zoom-us-5.3.469451.0927/bin/zoom-us
/home/eelco/.local/state/nix/profiles/profile-7-link/share/applications:
total 12
-lrwxrwxrwx 4 root root 120 Jan 1 1970 chromium-browser.desktop -> /nix/store/4cf803y4vzfm3gyk3vzhzb2327v0kl8a-chromium-unwrapped-86.0.4240.111/share/applications/chromium-browser.desktop
+lrwxrwxrwx 4 root root 120 Jan 1 1970 chromium-browser.desktop -> /nix/store/sqzyx2l85i6j2a77pnyvglh3bvzwmjjp-chromium-unwrapped-86.0.4240.111/share/applications/chromium-browser.desktop
lrwxrwxrwx 7 root root 110 Jan 1 1970 spotify.desktop -> /nix/store/w9182874m1bl56smps3m5zjj36jhp3rn-spotify-1.1.26.501.gbe11e53b-15/share/applications/spotify.desktop
lrwxrwxrwx 3 root root 107 Jan 1 1970 us.zoom.Zoom.desktop -> /nix/store/wbhg2ga8f3h87s9h5k0slxk0m81m4cxl-zoom-us-5.3.469451.0927/share/applications/us.zoom.Zoom.desktop
@@ -67,7 +67,7 @@ By default, this symlink points to:
- `$NIX_STATE_DIR/profiles/per-user/root/profile` for `root`
The `PATH` environment variable should include `/bin` subdirectory of the profile link (e.g. `~/.nix-profile/bin`) for the user environment to be visible to the user.
-The [installer](@docroot@/installation/installing-binary.md) sets this up by default, unless you enable [`use-xdg-base-directories`].
+The installer sets this up by default, unless you enable [`use-xdg-base-directories`].
[`nix-env`]: @docroot@/command-ref/nix-env.md
[`nix profile`]: @docroot@/command-ref/new-cli/nix3-profile.md
diff --git a/doc/manual/source/command-ref/nix-channel.md b/doc/manual/source/command-ref/nix-channel.md
index 865f43ccce5b..59817be974b5 100644
--- a/doc/manual/source/command-ref/nix-channel.md
+++ b/doc/manual/source/command-ref/nix-channel.md
@@ -8,6 +8,12 @@
# Description
+> **Warning**
+>
+> nix-channel is deprecated in favor of flakes in Determinate Nix.
+> For a guide on Nix flakes, see: .
+> For details and to offer feedback on the deprecation process, see: .
+
Channels are a mechanism for referencing remote Nix expressions and conveniently retrieving their latest version.
The moving parts of channels are:
diff --git a/doc/manual/source/command-ref/nix-copy-closure.md b/doc/manual/source/command-ref/nix-copy-closure.md
index b7e31d93bfc3..b34d57a50150 100644
--- a/doc/manual/source/command-ref/nix-copy-closure.md
+++ b/doc/manual/source/command-ref/nix-copy-closure.md
@@ -72,11 +72,11 @@ When using public key authentication, you can avoid typing the passphrase with `
> $ storePath="$(nix-build '' -I nixpkgs=channel:nixpkgs-unstable -A hello --no-out-link)"
> $ nix-copy-closure --to alice@itchy.example.org "$storePath"
> copying 5 paths...
-> copying path '/nix/store/nrwkk6ak3rgkrxbqhsscb01jpzmslf2r-xgcc-13.2.0-libgcc' to 'ssh://alice@itchy.example.org'...
-> copying path '/nix/store/gm61h1y42pqyl6178g90x8zm22n6pyy5-libunistring-1.1' to 'ssh://alice@itchy.example.org'...
-> copying path '/nix/store/ddfzjdykw67s20c35i7a6624by3iz5jv-libidn2-2.3.7' to 'ssh://alice@itchy.example.org'...
-> copying path '/nix/store/apab5i73dqa09wx0q27b6fbhd1r18ihl-glibc-2.39-31' to 'ssh://alice@itchy.example.org'...
-> copying path '/nix/store/g1n2vryg06amvcc1avb2mcq36faly0mh-hello-2.12.1' to 'ssh://alice@itchy.example.org'...
+> copying path '/nix/store/h6q8sqsqfbd3252f9gixqn3z282wds7m-xgcc-13.2.0-libgcc' to 'ssh://alice@itchy.example.org'...
+> copying path '/nix/store/imnwvn96lw355giswsk36hx105j4wnpj-libunistring-1.1' to 'ssh://alice@itchy.example.org'...
+> copying path '/nix/store/85301indj7scg34spnfczkz72jgv8wa9-libidn2-2.3.7' to 'ssh://alice@itchy.example.org'...
+> copying path '/nix/store/ypwfsaljwhzw9iffiysxmxnhjj8v7np0-glibc-2.39-31' to 'ssh://alice@itchy.example.org'...
+> copying path '/nix/store/0dklv59zppdsqdvgf0qdvjgzcs5wbwxa-hello-2.12.1' to 'ssh://alice@itchy.example.org'...
> ```
> **Example**
diff --git a/doc/manual/source/command-ref/nix-env.md b/doc/manual/source/command-ref/nix-env.md
index bda02149ed06..d01caaf7f787 100644
--- a/doc/manual/source/command-ref/nix-env.md
+++ b/doc/manual/source/command-ref/nix-env.md
@@ -52,7 +52,7 @@ These pages can be viewed offline:
`nix-env` can obtain packages from multiple sources:
- An attribute set of derivations from:
- - The [default Nix expression](@docroot@/command-ref/files/default-nix-expression.md) (by default)
+ - The default Nix expression (by default)
- A Nix file, specified via `--file`
- A [profile](@docroot@/command-ref/files/profiles.md), specified via `--from-profile`
- A Nix expression that is a function which takes default expression as argument, specified via `--from-expression`
diff --git a/doc/manual/source/command-ref/nix-env/install.md b/doc/manual/source/command-ref/nix-env/install.md
index 527fd8f90d87..320fa530fdaa 100644
--- a/doc/manual/source/command-ref/nix-env/install.md
+++ b/doc/manual/source/command-ref/nix-env/install.md
@@ -22,12 +22,11 @@ It is based on the current generation of the active [profile](@docroot@/command-
The arguments *args* map to store paths in a number of possible ways:
-- By default, *args* is a set of names denoting derivations in the [default Nix expression].
+- By default, *args* is a set of names denoting derivations in the default Nix expression.
These are [realised], and the resulting output paths are installed.
Currently installed derivations with a name equal to the name of a derivation being added are removed unless the option `--preserve-installed` is specified.
[derivation expression]: @docroot@/glossary.md#gloss-derivation-expression
- [default Nix expression]: @docroot@/command-ref/files/default-nix-expression.md
[realised]: @docroot@/glossary.md#gloss-realise
If there are multiple derivations matching a name in *args* that
@@ -45,7 +44,7 @@ The arguments *args* map to store paths in a number of possible ways:
gcc-3.3.6 gcc-4.1.1` will install both version of GCC (and will
probably cause a user environment conflict\!).
-- If [`--attr`](#opt-attr) / `-A` is specified, the arguments are *attribute paths* that select attributes from the [default Nix expression].
+- If [`--attr`](#opt-attr) / `-A` is specified, the arguments are *attribute paths* that select attributes from the default Nix expression.
This is faster than using derivation names and unambiguous.
Show the attribute paths of available packages with [`nix-env --query`](./query.md):
@@ -58,7 +57,7 @@ The arguments *args* map to store paths in a number of possible ways:
easy way to copy user environment elements from one profile to
another.
-- If `--from-expression` is given, *args* are [Nix language functions](@docroot@/language/syntax.md#functions) that are called with the [default Nix expression] as their single argument.
+- If `--from-expression` is given, *args* are [Nix language functions](@docroot@/language/syntax.md#functions) that are called with the default Nix expression as their single argument.
The derivations returned by those function calls are installed.
This allows derivations to be specified in an unambiguous way, which is necessary if there are multiple derivations with the same name.
@@ -204,7 +203,7 @@ To install a specific [store derivation] (typically created by
`nix-instantiate`):
```console
-$ nix-env --install /nix/store/fibjb1bfbpm5mrsxc4mh2d8n37sxh91i-gcc-3.4.3.drv
+$ nix-env --install /nix/store/8la6y31fmm6i4wfmby6avly1wf718xnj-gcc-3.4.3.drv
```
To install a specific output path:
@@ -232,7 +231,7 @@ $ nix-env --file '' --install --attr hello --dry-run
(dry run; not doing anything)
installing ‘hello-2.10’
this path will be fetched (0.04 MiB download, 0.19 MiB unpacked):
- /nix/store/wkhdf9jinag5750mqlax6z2zbwhqb76n-hello-2.10
+ /nix/store/ikwkxz4wwlp2g1428n7dy729cg1d9hin-hello-2.10
...
```
diff --git a/doc/manual/source/command-ref/nix-prefetch-url.md b/doc/manual/source/command-ref/nix-prefetch-url.md
index 19322ec8e04c..8451778ad46d 100644
--- a/doc/manual/source/command-ref/nix-prefetch-url.md
+++ b/doc/manual/source/command-ref/nix-prefetch-url.md
@@ -76,7 +76,7 @@ $ nix-prefetch-url ftp://ftp.gnu.org/pub/gnu/hello/hello-2.10.tar.gz
```console
$ nix-prefetch-url --print-path mirror://gnu/hello/hello-2.10.tar.gz
0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i
-/nix/store/3x7dwzq014bblazs7kq20p9hyzz0qh8g-hello-2.10.tar.gz
+/nix/store/8alrpdaasjd1x6g1fczchmzbpqm936a3-hello-2.10.tar.gz
```
```console
diff --git a/doc/manual/source/command-ref/nix-store/add-fixed.md b/doc/manual/source/command-ref/nix-store/add-fixed.md
index 2ea90a135925..511fe2050ebe 100644
--- a/doc/manual/source/command-ref/nix-store/add-fixed.md
+++ b/doc/manual/source/command-ref/nix-store/add-fixed.md
@@ -34,6 +34,6 @@ This operation has the following options:
```console
$ nix-store --add-fixed sha256 ./hello-2.10.tar.gz
-/nix/store/3x7dwzq014bblazs7kq20p9hyzz0qh8g-hello-2.10.tar.gz
+/nix/store/8alrpdaasjd1x6g1fczchmzbpqm936a3-hello-2.10.tar.gz
```
diff --git a/doc/manual/source/command-ref/nix-store/delete.md b/doc/manual/source/command-ref/nix-store/delete.md
index 550c5ea2914c..fcb2212d86d8 100644
--- a/doc/manual/source/command-ref/nix-store/delete.md
+++ b/doc/manual/source/command-ref/nix-store/delete.md
@@ -27,7 +27,7 @@ paths in the store that refer to it (i.e., depend on it).
# Example
```console
-$ nix-store --delete /nix/store/zq0h41l75vlb4z45kzgjjmsjxvcv1qk7-mesa-6.4
+$ nix-store --delete /nix/store/gjak3al7lj61x4gj6rln4f5pc5v0f67n-mesa-6.4
0 bytes freed (0.00 MiB)
-error: cannot delete path `/nix/store/zq0h41l75vlb4z45kzgjjmsjxvcv1qk7-mesa-6.4' since it is still alive
+error: cannot delete path `/nix/store/gjak3al7lj61x4gj6rln4f5pc5v0f67n-mesa-6.4' since it is still alive
```
diff --git a/doc/manual/source/command-ref/nix-store/query.md b/doc/manual/source/command-ref/nix-store/query.md
index b5ba63adae26..cc45eeb74cf1 100644
--- a/doc/manual/source/command-ref/nix-store/query.md
+++ b/doc/manual/source/command-ref/nix-store/query.md
@@ -103,6 +103,13 @@ symlink.
example when *paths* were substituted from a binary cache.
Use `--valid-derivers` instead to obtain valid paths only.
+ > **Note**
+ >
+ > `nix-store --query --deriver` is replaced with the following `nix` command:
+ >
+ > nix path-info --json ... | jq -r '.[].deriver'
+
+
[deriver]: @docroot@/glossary.md#gloss-deriver
- `--valid-derivers`
@@ -184,9 +191,9 @@ Print the build-time dependencies of `svn`:
```console
$ nix-store --query --requisites $(nix-store --query --deriver $(which svn))
-/nix/store/02iizgn86m42q905rddvg4ja975bk2i4-grep-2.5.1.tar.bz2.drv
-/nix/store/07a2bzxmzwz5hp58nf03pahrv2ygwgs3-gcc-wrapper.sh
-/nix/store/0ma7c9wsbaxahwwl04gbw3fcd806ski4-glibc-2.3.4.drv
+/nix/store/y6qa66l9h0pw161crnlk6y16rdrcljx4-grep-2.5.1.tar.bz2.drv
+/nix/store/z716h753s97jhnzvfank2srqbljswpgm-gcc-wrapper.sh
+/nix/store/f39x0q73rjdyvzm93y9wrkfr6x39lb7f-glibc-2.3.4.drv
... lots of other paths ...
```
@@ -199,10 +206,10 @@ Show the build-time dependencies as a tree:
```console
$ nix-store --query --tree $(nix-store --query --deriver $(which svn))
/nix/store/7i5082kfb6yjbqdbiwdhhza0am2xvh6c-subversion-1.1.4.drv
-+---/nix/store/d8afh10z72n8l1cr5w42366abiblgn54-builder.sh
-+---/nix/store/fmzxmpjx2lh849ph0l36snfj9zdibw67-bash-3.0.drv
-| +---/nix/store/570hmhmx3v57605cqg9yfvvyh0nnb8k8-bash
-| +---/nix/store/p3srsbd8dx44v2pg6nbnszab5mcwx03v-builder.sh
++---/nix/store/vxnmkc8l8d2ijjha4xwhkfgx9vvc3q4c-builder.sh
++---/nix/store/rn9776dy82n5qrgz7xbcl1iw4vfkcrkk-bash-3.0.drv
+| +---/nix/store/x9j20hz6bln1crzn55qifk0bbsm8v5ac-bash
+| +---/nix/store/ajnn1mcm45wjvn0rlc22gvx2cwhjnazx-builder.sh
...
```
diff --git a/doc/manual/source/command-ref/nix-store/realise.md b/doc/manual/source/command-ref/nix-store/realise.md
index 240685ce5c78..f5d203894e6b 100644
--- a/doc/manual/source/command-ref/nix-store/realise.md
+++ b/doc/manual/source/command-ref/nix-store/realise.md
@@ -76,7 +76,7 @@ This operation is typically used to build [store derivation]s produced by
```console
$ nix-store --realise $(nix-instantiate ./test.nix)
-/nix/store/31axcgrlbfsxzmfff1gyj1bf62hvkby2-aterm-2.3.1
+/nix/store/6gwmy5jcnwdlz6aqqhksz863f1l8xc2w-aterm-2.3.1
```
This is essentially what [`nix-build`](@docroot@/command-ref/nix-build.md) does.
diff --git a/doc/manual/source/command-ref/subcommands.md b/doc/manual/source/command-ref/subcommands.md
new file mode 100644
index 000000000000..6a26732338d1
--- /dev/null
+++ b/doc/manual/source/command-ref/subcommands.md
@@ -0,0 +1,3 @@
+# Subcommands
+
+This section lists all the subcommands of the `nix` CLI.
diff --git a/doc/manual/source/development/building.md b/doc/manual/source/development/building.md
index eb65a7247572..9694183ba82e 100644
--- a/doc/manual/source/development/building.md
+++ b/doc/manual/source/development/building.md
@@ -1,73 +1,5 @@
# Building Nix
-This section provides some notes on how to start hacking on Nix.
-To get the latest version of Nix from GitHub:
-
-```console
-$ git clone https://github.com/NixOS/nix.git
-$ cd nix
-```
-
-> **Note**
->
-> The following instructions assume you already have some version of Nix installed locally, so that you can use it to set up the development environment.
-> If you don't have it installed, follow the [installation instructions](../installation/index.md).
-
-
-To build all dependencies and start a shell in which all environment variables are set up so that those dependencies can be found:
-
-```console
-$ nix-shell
-```
-
-To get a shell with one of the other [supported compilation environments](#compilation-environments):
-
-```console
-$ nix-shell --attr devShells.x86_64-linux.native-clangStdenv
-```
-
-> **Note**
->
-> You can use `native-ccacheStdenv` to drastically improve rebuild time.
-> By default, [ccache](https://ccache.dev) keeps artifacts in `~/.cache/ccache/`.
-
-To build Nix itself in this shell:
-
-```console
-[nix-shell]$ out="$(pwd)/outputs/out" dev=$out debug=$out mesonFlags+=" --prefix=${out}"
-[nix-shell]$ dontAddPrefix=1 configurePhase
-[nix-shell]$ buildPhase
-```
-
-To test it:
-
-```console
-[nix-shell]$ checkPhase
-```
-
-To install it in `$(pwd)/outputs`:
-
-```console
-[nix-shell]$ installPhase
-[nix-shell]$ ./outputs/out/bin/nix --version
-nix (Nix) 2.12
-```
-
-To build a release version of Nix for the current operating system and CPU architecture:
-
-```console
-$ nix-build
-```
-
-You can also build Nix for one of the [supported platforms](#platforms).
-
-## Building Nix with flakes
-
-This section assumes you are using Nix with the [`flakes`] and [`nix-command`] experimental features enabled.
-
-[`flakes`]: @docroot@/development/experimental-features.md#xp-feature-flakes
-[`nix-command`]: @docroot@/development/experimental-features.md#xp-feature-nix-command
-
To build all dependencies and start a shell in which all environment variables are set up so that those dependencies can be found:
```console
@@ -126,8 +58,6 @@ Nix can be built for various platforms, as specified in [`flake.nix`]:
[`flake.nix`]: https://github.com/nixos/nix/blob/master/flake.nix
- `x86_64-linux`
-- `x86_64-darwin`
-- `i686-linux`
- `aarch64-linux`
- `aarch64-darwin`
- `armv6l-linux`
@@ -145,12 +75,6 @@ platform. Common solutions include [remote build machines] and [binary format em
Given such a setup, executing the build only requires selecting the respective attribute.
For example, to compile for `aarch64-linux`:
-```console
-$ nix-build --attr packages.aarch64-linux.default
-```
-
-or for Nix with the [`flakes`] and [`nix-command`] experimental features enabled:
-
```console
$ nix build .#packages.aarch64-linux.default
```
@@ -219,6 +143,7 @@ For historic reasons and backward-compatibility, some CPU and OS identifiers are
|-----------------------------|-------------------------|---------------------|
| `x86` | | `i686` |
| `arm` | | `host_machine.cpu()`|
+| `arm64` | | `host_machine.cpu()`|
| `ppc` | `little` | `powerpcle` |
| `ppc64` | `little` | `powerpc64le` |
| `ppc` | `big` | `powerpc` |
@@ -243,20 +168,12 @@ To build with one of those environments, you can use
$ nix build .#nix-cli-ccacheStdenv
```
-for flake-enabled Nix, or
-
-```console
-$ nix-build --attr nix-cli-ccacheStdenv
-```
-
-for classic Nix.
-
You can use any of the other supported environments in place of `nix-cli-ccacheStdenv`.
## Editor integration
The `clangd` LSP server is installed by default on the `clang`-based `devShell`s.
-See [supported compilation environments](#compilation-environments) and instructions how to set up a shell [with flakes](#building-nix-with-flakes) or in [classic Nix](#building-nix).
+See [supported compilation environments](#compilation-environments) and instructions how to [set up a shell](#building-nix).
To use the LSP with your editor, you will want a `compile_commands.json` file telling `clangd` how we are compiling the code.
Meson's configure always produces this inside the build directory.
diff --git a/doc/manual/source/development/debugging.md b/doc/manual/source/development/debugging.md
index d2450495e504..6578632d991a 100644
--- a/doc/manual/source/development/debugging.md
+++ b/doc/manual/source/development/debugging.md
@@ -6,14 +6,7 @@ Additionally, see [Testing Nix](./testing.md) for further instructions on how to
## Building Nix with Debug Symbols
-In the development shell, set the `mesonBuildType` environment variable to `debug` before configuring the build:
-
-```console
-[nix-shell]$ export mesonBuildType=debugoptimized
-```
-
-Then, proceed to build Nix as described in [Building Nix](./building.md).
-This will build Nix with debug symbols, which are essential for effective debugging.
+In the development shell, `mesonBuildType` is set automatically to `debugoptimized`. This builds Nix with debug symbols, which are essential for effective debugging.
It is also possible to build without optimization for faster build:
diff --git a/doc/manual/source/development/experimental-features.md b/doc/manual/source/development/experimental-features.md
index ad5cffa91ee5..56a45b23890a 100644
--- a/doc/manual/source/development/experimental-features.md
+++ b/doc/manual/source/development/experimental-features.md
@@ -6,7 +6,7 @@ Experimental features are considered unstable, which means that they can be chan
Users must explicitly enable them by toggling the associated [experimental feature flags](@docroot@/command-ref/conf-file.md#conf-experimental-features).
This allows accessing unstable functionality without unwittingly relying on it.
-Experimental feature flags were first introduced in [Nix 2.4](@docroot@/release-notes/rl-2.4.md).
+Experimental feature flags were first introduced in [Nix 2.4](https://nix.dev/manual/nix/latest/release-notes/rl-2.4).
Before that, Nix did have experimental features, but they were not guarded by flags and were merely documented as unstable.
This was a source of confusion and controversy.
diff --git a/doc/manual/source/development/testing.md b/doc/manual/source/development/testing.md
index dd965862a34c..35654d163935 100644
--- a/doc/manual/source/development/testing.md
+++ b/doc/manual/source/development/testing.md
@@ -325,7 +325,6 @@ Creating a Cachix cache for your installer tests and adding its authorisation to
- `x86_64-linux`
- `armv6l-linux`
- `armv7l-linux`
- - `x86_64-darwin`
- The `installer_test` job (which runs on `ubuntu-24.04` and `macos-14`) will try to install Nix with the cached installer and run a trivial Nix command.
diff --git a/doc/manual/source/favicon.png b/doc/manual/source/favicon.png
deleted file mode 100644
index 1ed2b5fe0fdf..000000000000
Binary files a/doc/manual/source/favicon.png and /dev/null differ
diff --git a/doc/manual/source/favicon.svg b/doc/manual/source/favicon.svg
index 1d2a6e835d5f..55fb9479b06e 100644
--- a/doc/manual/source/favicon.svg
+++ b/doc/manual/source/favicon.svg
@@ -1 +1,29 @@
-
\ No newline at end of file
+
diff --git a/doc/manual/source/glossary.md b/doc/manual/source/glossary.md
index 502e6d4de6b0..64ca1cf5e167 100644
--- a/doc/manual/source/glossary.md
+++ b/doc/manual/source/glossary.md
@@ -136,7 +136,7 @@
> **Example**
>
- > `/nix/store/a040m110amc4h71lds2jmr8qrkj2jhxd-git-2.38.1`
+ > `/nix/store/jf6gn2dzna4nmsfbdxsd7kwhsk6gnnlr-git-2.38.1`
See [Store Path](@docroot@/store/store-path.md) for details.
@@ -353,14 +353,6 @@
See [Nix Archive](store/file-system-object/content-address.html#serial-nix-archive) for details.
-- [`∅`]{#gloss-empty-set}
-
- The empty set symbol. In the context of profile history, this denotes a package is not present in a particular version of the profile.
-
-- [`ε`]{#gloss-epsilon}
-
- The epsilon symbol. In the context of a package, this means the version is empty. More precisely, the derivation does not have a version attribute.
-
- [package]{#package}
A software package; files that belong together for a particular purpose, and metadata.
diff --git a/doc/manual/source/installation/env-variables.md b/doc/manual/source/installation/env-variables.md
deleted file mode 100644
index 0350904211ac..000000000000
--- a/doc/manual/source/installation/env-variables.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# Environment Variables
-
-To use Nix, some environment variables should be set. In particular,
-`PATH` should contain the directories `prefix/bin` and
-`~/.nix-profile/bin`. The first directory contains the Nix tools
-themselves, while `~/.nix-profile` is a symbolic link to the current
-*user environment* (an automatically generated package consisting of
-symlinks to installed packages). The simplest way to set the required
-environment variables is to include the file
-`prefix/etc/profile.d/nix.sh` in your `~/.profile` (or similar), like
-this:
-
-```bash
-source prefix/etc/profile.d/nix.sh
-```
-
-# `NIX_SSL_CERT_FILE`
-
-If you need to specify a custom certificate bundle to account for an
-HTTPS-intercepting man in the middle proxy, you must specify the path to
-the certificate bundle in the environment variable `NIX_SSL_CERT_FILE`.
-
-If you don't specify a `NIX_SSL_CERT_FILE` manually, Nix will install
-and use its own certificate bundle.
-
-Set the environment variable and install Nix
-
-```console
-$ export NIX_SSL_CERT_FILE=/etc/ssl/my-certificate-bundle.crt
-$ curl -L https://nixos.org/nix/install | sh
-```
-
-In the shell profile and rc files (for example, `/etc/bashrc`,
-`/etc/zshrc`), add the following line:
-
-```bash
-export NIX_SSL_CERT_FILE=/etc/ssl/my-certificate-bundle.crt
-```
-
-> **Note**
->
-> You must not add the export and then do the install, as the Nix
-> installer will detect the presence of Nix configuration, and abort.
-
-If you use the Nix daemon, you should also add the following to
-`/etc/nix/nix.conf`:
-
-```
-ssl-cert-file = /etc/ssl/my-certificate-bundle.crt
-```
-
-## Proxy Environment Variables
-
-The Nix installer has special handling for these proxy-related
-environment variables: `http_proxy`, `https_proxy`, `ftp_proxy`,
-`all_proxy`, `no_proxy`, `HTTP_PROXY`, `HTTPS_PROXY`, `FTP_PROXY`,
-`ALL_PROXY`, `NO_PROXY`.
-
-If any of these variables are set when running the Nix installer, then
-the installer will create an override file at
-`/etc/systemd/system/nix-daemon.service.d/override.conf` so `nix-daemon`
-will use them.
diff --git a/doc/manual/source/installation/index.md b/doc/manual/source/installation/index.md
index 3c09f103184a..aded684b0b59 100644
--- a/doc/manual/source/installation/index.md
+++ b/doc/manual/source/installation/index.md
@@ -1,44 +1,11 @@
# Installation
-This section describes how to install and configure Nix for first-time use.
-
-The current recommended option on Linux and MacOS is [multi-user](#multi-user).
-
-## Multi-user
-
-This installation offers better sharing, improved isolation, and more security
-over a single user installation.
-
-This option requires either:
-
-* Linux running systemd, with SELinux disabled
-* MacOS
-
-> **Updating to macOS 15 Sequoia**
->
-> If you recently updated to macOS 15 Sequoia and are getting
-> ```console
-> error: the user '_nixbld1' in the group 'nixbld' does not exist
-> ```
-> when running Nix commands, refer to GitHub issue [NixOS/nix#10892](https://github.com/NixOS/nix/issues/10892) for instructions to fix your installation without reinstalling.
+We recommend that macOS users install Determinate Nix using our graphical installer, [Determinate.pkg][pkg].
+For Linux and Windows Subsystem for Linux (WSL) users:
```console
-$ curl -L https://nixos.org/nix/install | sh -s -- --daemon
-```
-
-## Single-user
-
-> Single-user is not supported on Mac.
-
-> `warning: installing Nix as root is not supported by this script!`
-
-This installation has less requirements than the multi-user install, however it
-cannot offer equivalent sharing, isolation, or security.
-
-This option is suitable for systems without systemd.
-
-```console
-$ curl -L https://nixos.org/nix/install | sh -s -- --no-daemon
+curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | \
+ sh -s -- install
```
## Distributions
@@ -46,3 +13,5 @@ $ curl -L https://nixos.org/nix/install | sh -s -- --no-daemon
The Nix community maintains installers for several distributions.
They can be found in the [`nix-community/nix-installers`](https://github.com/nix-community/nix-installers) repository.
+
+[pkg]: https://install.determinate.systems/determinate-pkg/stable/Universal
diff --git a/doc/manual/source/installation/installing-binary.md b/doc/manual/source/installation/installing-binary.md
deleted file mode 100644
index 21c15637437d..000000000000
--- a/doc/manual/source/installation/installing-binary.md
+++ /dev/null
@@ -1,158 +0,0 @@
-# Installing a Binary Distribution
-
-> **Updating to macOS 15 Sequoia**
->
-> If you recently updated to macOS 15 Sequoia and are getting
-> ```console
-> error: the user '_nixbld1' in the group 'nixbld' does not exist
-> ```
-> when running Nix commands, refer to GitHub issue [NixOS/nix#10892](https://github.com/NixOS/nix/issues/10892) for instructions to fix your installation without reinstalling.
-
-To install the latest version Nix, run the following command:
-
-```console
-$ curl -L https://nixos.org/nix/install | sh
-```
-
-This performs the default type of installation for your platform:
-
-- [Multi-user](#multi-user-installation):
- - Linux with systemd and without SELinux
- - macOS
-- [Single-user](#single-user-installation):
- - Linux without systemd
- - Linux with SELinux
-
-We recommend the multi-user installation if it supports your platform and you can authenticate with `sudo`.
-
-The installer can be configured with various command line arguments and environment variables.
-To show available command line flags:
-
-```console
-$ curl -L https://nixos.org/nix/install | sh -s -- --help
-```
-
-To check what it does and how it can be customised further, [download and edit the second-stage installation script](#installing-from-a-binary-tarball).
-
-# Installing a pinned Nix version from a URL
-
-Version-specific installation URLs for all Nix versions since 1.11.16 can be found at [releases.nixos.org](https://releases.nixos.org/?prefix=nix/).
-The directory for each version contains the corresponding SHA-256 hash.
-
-All installation scripts are invoked the same way:
-
-```console
-$ export VERSION=2.19.2
-$ curl -L https://releases.nixos.org/nix/nix-$VERSION/install | sh
-```
-
-# Multi User Installation
-
-The multi-user Nix installation creates system users and a system service for the Nix daemon.
-
-Supported systems:
-
-- Linux running systemd, with SELinux disabled
-- macOS
-
-To explicitly instruct the installer to perform a multi-user installation on your system:
-
-```console
-$ bash <(curl -L https://nixos.org/nix/install) --daemon
-```
-
-You can run this under your usual user account or `root`.
-The script will invoke `sudo` as needed.
-
-# Single User Installation
-
-To explicitly select a single-user installation on your system:
-
-```console
-$ bash <(curl -L https://nixos.org/nix/install) --no-daemon
-```
-
-In a single-user installation, `/nix` is owned by the invoking user.
-The script will invoke `sudo` to create `/nix` if it doesn’t already exist.
-If you don’t have `sudo`, manually create `/nix` as `root`:
-
-```console
-$ su root
-# mkdir /nix
-# chown alice /nix
-```
-
-# Installing from a binary tarball
-
-You can also download a binary tarball that contains Nix and all its dependencies:
-- Choose a [version](https://releases.nixos.org/?prefix=nix/) and [system type](../development/building.md#platforms)
-- Download and unpack the tarball
-- Run the installer
-
-> **Example**
->
-> ```console
-> $ pushd $(mktemp -d)
-> $ export VERSION=2.19.2
-> $ export SYSTEM=x86_64-linux
-> $ curl -LO https://releases.nixos.org/nix/nix-$VERSION/nix-$VERSION-$SYSTEM.tar.xz
-> $ tar xfj nix-$VERSION-$SYSTEM.tar.xz
-> $ cd nix-$VERSION-$SYSTEM
-> $ ./install
-> $ popd
-> ```
-
-The installer can be customised with the environment variables declared in the file named `install-multi-user`.
-
-## Native packages for Linux distributions
-
-The Nix community maintains installers for some Linux distributions in their native packaging format(https://nix-community.github.io/nix-installers/).
-
-# macOS Installation
-
-
-[]{#sect-macos-installation-change-store-prefix}[]{#sect-macos-installation-encrypted-volume}[]{#sect-macos-installation-symlink}[]{#sect-macos-installation-recommended-notes}
-
-We believe we have ironed out how to cleanly support the read-only root file system
-on modern macOS. New installs will do this automatically.
-
-This section previously detailed the situation, options, and trade-offs,
-but it now only outlines what the installer does. You don't need to know
-this to run the installer, but it may help if you run into trouble:
-
-- create a new APFS volume for your Nix store
-- update `/etc/synthetic.conf` to direct macOS to create a "synthetic"
- empty root directory to mount your volume
-- specify mount options for the volume in `/etc/fstab`
- - `rw`: read-write
- - `noauto`: prevent the system from auto-mounting the volume (so the
- LaunchDaemon mentioned below can control mounting it, and to avoid
- masking problems with that mounting service).
- - `nobrowse`: prevent the Nix Store volume from showing up on your
- desktop; also keeps Spotlight from spending resources to index
- this volume
-
-- if you have FileVault enabled
- - generate an encryption password
- - put it in your system Keychain
- - use it to encrypt the volume
-- create a system LaunchDaemon to mount this volume early enough in the
- boot process to avoid problems loading or restoring any programs that
- need access to your Nix store
-
diff --git a/doc/manual/source/installation/nix-security.md b/doc/manual/source/installation/nix-security.md
index 1e9036b68b21..61cad24c2b3b 100644
--- a/doc/manual/source/installation/nix-security.md
+++ b/doc/manual/source/installation/nix-security.md
@@ -1,15 +1,85 @@
# Security
-Nix has two basic security models. First, it can be used in “single-user
-mode”, which is similar to what most other package management tools do:
-there is a single user (typically root) who performs all package
-management operations. All other users can then use the installed
-packages, but they cannot perform package management operations
-themselves.
-
-Alternatively, you can configure Nix in “multi-user mode”. In this
-model, all users can perform package management operations — for
-instance, every user can install software without requiring root
-privileges. Nix ensures that this is secure. For instance, it’s not
-possible for one user to overwrite a package used by another user with a
-Trojan horse.
+Nix follows a [**multi-user**](#multi-user-model) security model in which all
+users can perform package management operations. Every user can, for example,
+install software without requiring root privileges, and Nix ensures that this
+is secure. It's *not* possible for one user to, for example, overwrite a
+package used by another user with a Trojan horse.
+
+## Multi-User model
+
+To allow a Nix store to be shared safely among multiple users, it is
+important that users are not able to run builders that modify the Nix
+store or database in arbitrary ways, or that interfere with builds
+started by other users. If they could do so, they could install a Trojan
+horse in some package and compromise the accounts of other users.
+
+To prevent this, the Nix store and database are owned by some privileged
+user (usually `root`) and builders are executed under special user
+accounts (usually named `nixbld1`, `nixbld2`, etc.). When a unprivileged
+user runs a Nix command, actions that operate on the Nix store (such as
+builds) are forwarded to a *Nix daemon* running under the owner of the
+Nix store/database that performs the operation.
+
+> **Note**
+>
+> Multi-user mode has one important limitation: only root and a set of
+> trusted users specified in `nix.conf` can specify arbitrary binary
+> caches. So while unprivileged users may install packages from
+> arbitrary Nix expressions, they may not get pre-built binaries.
+
+### Setting up the build users
+
+The *build users* are the special UIDs under which builds are performed.
+They should all be members of the *build users group* `nixbld`. This
+group should have no other members. The build users should not be
+members of any other group. On Linux, you can create the group and users
+as follows:
+
+```console
+$ groupadd -r nixbld
+$ for n in $(seq 1 10); do useradd -c "Nix build user $n" \
+ -d /var/empty -g nixbld -G nixbld -M -N -r -s "$(which nologin)" \
+ nixbld$n; done
+```
+
+This creates 10 build users. There can never be more concurrent builds
+than the number of build users, so you may want to increase this if you
+expect to do many builds at the same time.
+
+### Running the daemon
+
+The [Nix daemon](../command-ref/nix-daemon.md) should be started as
+follows (as `root`):
+
+```console
+$ nix-daemon
+```
+
+You’ll want to put that line somewhere in your system’s boot scripts.
+
+To let unprivileged users use the daemon, they should set the
+[`NIX_REMOTE` environment variable](../command-ref/env-common.md) to
+`daemon`. So you should put a line like
+
+```console
+export NIX_REMOTE=daemon
+```
+
+into the users’ login scripts.
+
+### Restricting access
+
+To limit which users can perform Nix operations, you can use the
+permissions on the directory `/nix/var/nix/daemon-socket`. For instance,
+if you want to restrict the use of Nix to the members of a group called
+`nix-users`, do
+
+```console
+$ chgrp nix-users /nix/var/nix/daemon-socket
+$ chmod ug=rwx,o= /nix/var/nix/daemon-socket
+```
+
+This way, users who are not in the `nix-users` group cannot connect to
+the Unix domain socket `/nix/var/nix/daemon-socket/socket`, so they
+cannot perform Nix operations.
diff --git a/doc/manual/source/installation/single-user.md b/doc/manual/source/installation/single-user.md
deleted file mode 100644
index f9a3b26edf41..000000000000
--- a/doc/manual/source/installation/single-user.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# Single-User Mode
-
-In single-user mode, all Nix operations that access the database in
-`prefix/var/nix/db` or modify the Nix store in `prefix/store` must be
-performed under the user ID that owns those directories. This is
-typically root. (If you install from RPM packages, that’s in fact the
-default ownership.) However, on single-user machines, it is often
-convenient to `chown` those directories to your normal user account so
-that you don’t have to `su` to root all the time.
diff --git a/doc/manual/source/installation/supported-platforms.md b/doc/manual/source/installation/supported-platforms.md
deleted file mode 100644
index 8ca3ce8d445e..000000000000
--- a/doc/manual/source/installation/supported-platforms.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Supported Platforms
-
-Nix is currently supported on the following platforms:
-
- - Linux (i686, x86\_64, aarch64).
-
- - macOS (x86\_64, aarch64).
diff --git a/doc/manual/source/installation/uninstall.md b/doc/manual/source/installation/uninstall.md
index 69d59847b6fd..e95634c213a1 100644
--- a/doc/manual/source/installation/uninstall.md
+++ b/doc/manual/source/installation/uninstall.md
@@ -1,197 +1,15 @@
# Uninstalling Nix
-## Multi User
-
-Removing a [multi-user installation](./installing-binary.md#multi-user-installation) depends on the operating system.
-
-### Linux
-
-If you are on Linux with systemd:
-
-1. Remove the Nix daemon service:
-
- ```console
- sudo systemctl stop nix-daemon.service
- sudo systemctl disable nix-daemon.socket nix-daemon.service
- sudo systemctl daemon-reload
- ```
-
-Remove files created by Nix:
+To uninstall Determinate Nix, use the uninstallation utility built into the [Determinate Nix Installer][installer]:
```console
-sudo rm -rf /etc/nix /etc/profile.d/nix.sh /etc/tmpfiles.d/nix-daemon.conf /nix ~root/.nix-channels ~root/.nix-defexpr ~root/.nix-profile ~root/.cache/nix
+$ /nix/nix-installer uninstall
```
-Remove build users and their group:
+If you're certain that you want to uninstall, you can skip the confirmation step:
```console
-for i in $(seq 1 32); do
- sudo userdel nixbld$i
-done
-sudo groupdel nixbld
+$ /nix/nix-installer uninstall --no-confirm
```
-There may also be references to Nix in
-
-- `/etc/bash.bashrc`
-- `/etc/bashrc`
-- `/etc/profile`
-- `/etc/zsh/zshrc`
-- `/etc/zshrc`
-
-which you may remove.
-
-### FreeBSD
-
-1. Stop and remove the Nix daemon service:
-
- ```console
- sudo service nix-daemon stop
- sudo rm -f /usr/local/etc/rc.d/nix-daemon
- sudo sysrc -x nix_daemon_enable
- ```
-
-2. Remove files created by Nix:
-
- ```console
- sudo rm -rf /etc/nix /usr/local/etc/profile.d/nix.sh /nix ~root/.nix-channels ~root/.nix-defexpr ~root/.nix-profile ~root/.cache/nix
- ```
-
-3. Remove build users and their group:
-
- ```console
- for i in $(seq 1 32); do
- sudo pw userdel nixbld$i
- done
- sudo pw groupdel nixbld
- ```
-
-4. There may also be references to Nix in:
- - `/usr/local/etc/bashrc`
- - `/usr/local/etc/zshrc`
- - Shell configuration files in users' home directories
-
- which you may remove.
-
-### macOS
-
-> **Updating to macOS 15 Sequoia**
->
-> If you recently updated to macOS 15 Sequoia and are getting
-> ```console
-> error: the user '_nixbld1' in the group 'nixbld' does not exist
-> ```
-> when running Nix commands, refer to GitHub issue [NixOS/nix#10892](https://github.com/NixOS/nix/issues/10892) for instructions to fix your installation without reinstalling.
-
-1. If system-wide shell initialisation files haven't been altered since installing Nix, use the backups made by the installer:
-
- ```console
- sudo mv /etc/zshrc.backup-before-nix /etc/zshrc
- sudo mv /etc/bashrc.backup-before-nix /etc/bashrc
- sudo mv /etc/bash.bashrc.backup-before-nix /etc/bash.bashrc
- ```
-
- Otherwise, edit `/etc/zshrc`, `/etc/bashrc`, and `/etc/bash.bashrc` to remove the lines sourcing `nix-daemon.sh`, which should look like this:
-
- ```bash
- # Nix
- if [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then
- . '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'
- fi
- # End Nix
- ```
-
-2. Stop and remove the Nix daemon services:
-
- ```console
- sudo launchctl unload /Library/LaunchDaemons/org.nixos.nix-daemon.plist
- sudo rm /Library/LaunchDaemons/org.nixos.nix-daemon.plist
- sudo launchctl unload /Library/LaunchDaemons/org.nixos.darwin-store.plist
- sudo rm /Library/LaunchDaemons/org.nixos.darwin-store.plist
- ```
-
- This stops the Nix daemon and prevents it from being started next time you boot the system.
-
-3. Remove the `nixbld` group and the `_nixbuildN` users:
-
- ```console
- sudo dscl . -delete /Groups/nixbld
- for u in $(sudo dscl . -list /Users | grep _nixbld); do sudo dscl . -delete /Users/$u; done
- ```
-
- This will remove all the build users that no longer serve a purpose.
-
-4. Edit fstab using `sudo vifs` to remove the line mounting the Nix Store volume on `/nix`, which looks like
-
- ```
- UUID= /nix apfs rw,noauto,nobrowse,suid,owners
- ```
- or
-
- ```
- LABEL=Nix\040Store /nix apfs rw,nobrowse
- ```
-
- by setting the cursor on the respective line using the arrow keys, and pressing `dd`, and then `:wq` to save the file.
-
- This will prevent automatic mounting of the Nix Store volume.
-
-5. Edit `/etc/synthetic.conf` to remove the `nix` line.
- If this is the only line in the file you can remove it entirely:
-
- ```bash
- if [ -f /etc/synthetic.conf ]; then
- if [ "$(cat /etc/synthetic.conf)" = "nix" ]; then
- sudo rm /etc/synthetic.conf
- else
- sudo vi /etc/synthetic.conf
- fi
- fi
- ```
-
- This will prevent the creation of the empty `/nix` directory.
-
-6. Remove the files Nix added to your system, except for the store:
-
- ```console
- sudo rm -rf /etc/nix /var/root/.nix-profile /var/root/.nix-defexpr /var/root/.nix-channels ~/.nix-profile ~/.nix-defexpr ~/.nix-channels
- ```
-
-
-7. Remove the Nix Store volume:
-
- ```console
- sudo diskutil apfs deleteVolume /nix
- ```
-
- This will remove the Nix Store volume and everything that was added to the store.
-
- If the output indicates that the command couldn't remove the volume, you should make sure you don't have an _unmounted_ Nix Store volume.
- Look for a "Nix Store" volume in the output of the following command:
-
- ```console
- diskutil list
- ```
-
- If you _do_ find a "Nix Store" volume, delete it by running `diskutil apfs deleteVolume` with the store volume's `diskXsY` identifier.
-
- If you get an error that the volume is in use by the kernel, reboot and immediately delete the volume before starting any other process.
-
-> **Note**
->
-> After you complete the steps here, you will still have an empty `/nix` directory.
-> This is an expected sign of a successful uninstall.
-> The empty `/nix` directory will disappear the next time you reboot.
->
-> You do not have to reboot to finish uninstalling Nix.
-> The uninstall is complete.
-> macOS (Catalina+) directly controls root directories, and its read-only root will prevent you from manually deleting the empty `/nix` mountpoint.
-
-## Single User
-
-To remove a [single-user installation](./installing-binary.md#single-user-installation) of Nix, run:
-
-```console
-rm -rf /nix ~/.nix-channels ~/.nix-defexpr ~/.nix-profile
-```
-You might also want to manually remove references to Nix from your `~/.profile`.
+[installer]: https://github.com/DeterminateSystems/nix-installer
diff --git a/doc/manual/source/installation/upgrading.md b/doc/manual/source/installation/upgrading.md
index a433f1d30e6c..8fe342b09b7c 100644
--- a/doc/manual/source/installation/upgrading.md
+++ b/doc/manual/source/installation/upgrading.md
@@ -1,40 +1,10 @@
# Upgrading Nix
-> **Note**
->
-> These upgrade instructions apply where Nix was installed following the [installation instructions in this manual](./index.md).
-
-Check which Nix version will be installed, for example from one of the [release channels](http://channels.nixos.org/) such as `nixpkgs-unstable`:
-
-```console
-$ nix-shell -p nix -I nixpkgs=channel:nixpkgs-unstable --run "nix --version"
-nix (Nix) 2.18.1
-```
-
-> **Warning**
->
-> Writing to the [local store](@docroot@/store/types/local-store.md) with a newer version of Nix, for example by building derivations with [`nix-build`](@docroot@/command-ref/nix-build.md) or [`nix-store --realise`](@docroot@/command-ref/nix-store/realise.md), may change the database schema!
-> Reverting to an older version of Nix may therefore require purging the store database before it can be used.
-
-## Linux multi-user
+You can upgrade Determinate Nix using Determinate Nixd:
```console
-$ sudo su
-# nix-env --install --file '' --attr nix cacert -I nixpkgs=channel:nixpkgs-unstable
-# systemctl daemon-reload
-# systemctl restart nix-daemon
+sudo determinate-nixd upgrade
```
-## macOS multi-user
+Note that the `sudo` is necessary here and upgrading fails without it.
-```console
-$ sudo nix-env --install --file '' --attr nix cacert -I nixpkgs=channel:nixpkgs-unstable
-$ sudo launchctl remove org.nixos.nix-daemon
-$ sudo launchctl load /Library/LaunchDaemons/org.nixos.nix-daemon.plist
-```
-
-## Single-user all platforms
-
-```console
-$ nix-env --install --file '' --attr nix cacert -I nixpkgs=channel:nixpkgs-unstable
-```
diff --git a/doc/manual/source/introduction.md b/doc/manual/source/introduction.md
index e70411c11f56..039ad6f30b1c 100644
--- a/doc/manual/source/introduction.md
+++ b/doc/manual/source/introduction.md
@@ -1,4 +1,19 @@
-# Introduction
+# Determinate Nix
+
+**Determinate Nix** is a downstream distribution of [Nix], a purely functional language, CLI tool, and package management system.
+It's available on Linux, macOS, and Windows Subsystem for Linux (WSL).
+
+## Installing
+
+We recommend that macOS users install Determinate Nix using our graphical installer, [Determinate.pkg][pkg].
+For Linux and Windows Subsystem for Linux (WSL) users:
+
+```console
+curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | \
+ sh -s -- install
+```
+
+## How Nix works
Nix is a _purely functional package manager_. This means that it
treats packages like values in a purely functional programming language
@@ -8,7 +23,7 @@ stores packages in the _Nix store_, usually the directory
`/nix/store`, where each package has its own unique subdirectory such
as
- /nix/store/b6gvzjyb2pg0kjfwrjmg1vfhh54ad73z-firefox-33.1/
+ /nix/store/q06x3jll2yfzckz2bzqak089p43ixkkq-firefox-33.1/
where `b6gvzjyb2pg0…` is a unique identifier for the package that
captures all its dependencies (it’s a cryptographic hash of the
@@ -184,10 +199,14 @@ to build configuration files in `/etc`). This means, among other
things, that it is easy to roll back the entire configuration of the
system to an earlier state. Also, users can install software without
root privileges. For more information and downloads, see the [NixOS
-homepage](https://nixos.org/).
+homepage][nix].
## License
Nix is released under the terms of the [GNU LGPLv2.1 or (at your
option) any later
-version](http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html).
+version][license].
+
+[license]: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
+[pkg]: https://install.determinate.systems/determinate-pkg/stable/Universal
+[site]: https://nixos.org
diff --git a/doc/manual/source/language/string-context.md b/doc/manual/source/language/string-context.md
index 65c59d865f09..0968cc88b849 100644
--- a/doc/manual/source/language/string-context.md
+++ b/doc/manual/source/language/string-context.md
@@ -34,12 +34,12 @@ String context elements come in different forms:
> [`builtins.storePath`] creates a string with a single constant string context element:
>
> ```nix
- > builtins.getContext (builtins.storePath "/nix/store/wkhdf9jinag5750mqlax6z2zbwhqb76n-hello-2.10")
+ > builtins.getContext (builtins.storePath "/nix/store/ikwkxz4wwlp2g1428n7dy729cg1d9hin-hello-2.10")
> ```
> evaluates to
> ```nix
> {
- > "/nix/store/wkhdf9jinag5750mqlax6z2zbwhqb76n-hello-2.10" = {
+ > "/nix/store/ikwkxz4wwlp2g1428n7dy729cg1d9hin-hello-2.10" = {
> path = true;
> };
> }
diff --git a/doc/manual/source/language/string-interpolation.md b/doc/manual/source/language/string-interpolation.md
index 8e25d2b63114..3f6bf9b9f855 100644
--- a/doc/manual/source/language/string-interpolation.md
+++ b/doc/manual/source/language/string-interpolation.md
@@ -181,7 +181,7 @@ A derivation interpolates to the [store path] of its first [output](./derivation
> "${pkgs.hello}"
> ```
>
-> "/nix/store/4xpfqf29z4m8vbhrqcz064wfmb46w5r7-hello-2.12.1"
+> "/nix/store/qnlr7906z0mrl2syrkdbpicffq02nw07-hello-2.12.1"
An attribute set interpolates to the return value of the function in the `__toString` applied to the attribute set itself.
diff --git a/doc/manual/source/protocols/flake-schemas.md b/doc/manual/source/protocols/flake-schemas.md
new file mode 100644
index 000000000000..18bffeef1dc1
--- /dev/null
+++ b/doc/manual/source/protocols/flake-schemas.md
@@ -0,0 +1,64 @@
+# Flake Schemas
+
+Flake schemas are a mechanism to allow tools like `nix flake show` and `nix flake check` to enumerate and check the contents of a flake
+in a generic way, without requiring built-in knowledge of specific flake output types like `packages` or `nixosConfigurations`.
+
+A flake can define schemas for its outputs by defining a `schemas` output. `schemas` should be an attribute set with an attribute for
+every output type that you want to be supported. If a flake does not have a `schemas` attribute, Nix uses a built-in set of schemas (namely https://github.com/DeterminateSystems/flake-schemas).
+
+A schema is an attribute set with the following attributes:
+
+| Attribute | Description | Default |
+| :---------- | :---------------------------------------------------------------------------------------------- | :------ |
+| `version` | Should be set to 1 | |
+| `doc` | A string containing documentation about the flake output type in Markdown format. | |
+| `allowIFD` | Whether the evaluation of the output attributes of this flake can read from derivation outputs. | `true` |
+| `inventory` | A function that returns the contents of the flake output (described [below](#inventory)). | |
+
+# Inventory
+
+The `inventory` function returns a _node_ describing the contents of the flake output. A node is either a _leaf node_ or a _non-leaf node_. This allows nested flake output attributes to be described (e.g. `x86_64-linux.hello` inside a `packages` output).
+
+Non-leaf nodes must have the following attribute:
+
+| Attribute | Description |
+| :--------- | :------------------------------------------------------------------------------------- |
+| `children` | An attribute set of nodes. If this attribute is missing, the attribute is a leaf node. |
+
+Leaf nodes can have the following attributes:
+
+| Attribute | Description |
+| :------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `derivationAttrPath` | If not null, a list of strings denoting the attribute path of the "main" derivation of this node. |
+| `evalChecks` | An attribute set of Boolean values, used by `nix flake check`. Each attribute must evaluate to `true`. |
+| `isFlakeCheck` | Whether `nix flake check` should build the attribute denoted by `derivationAttrPath`. |
+| `shortDescription` | A one-sentence description of the node (such as the `meta.description` attribute in Nixpkgs). |
+| `what` | A brief human-readable string describing the type of the node, e.g. `"package"` or `"development environment"`. This is used by tools like `nix flake show` to describe the contents of a flake. |
+
+Both leaf and non-leaf nodes can have the following attributes:
+
+| Attribute | Description |
+| :----------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `forSystems` | A list of Nix system types (e.g. `["x86_64-linux"]`) supported by this node. This is used by tools to skip nodes that cannot be built on the user's system. Setting this on a non-leaf node allows all the children to be skipped, regardless of the `forSystems` attributes of the children. If this attribute is not set, the node is never skipped. |
+
+# Example
+
+Here is a schema that checks that every element of the `nixosConfigurations` flake output evaluates and builds correctly (meaning that it has a `config.system.build.toplevel` attribute that yields a buildable derivation).
+
+```nix
+outputs = {
+ schemas.nixosConfigurations = {
+ version = 1;
+ doc = ''
+ The `nixosConfigurations` flake output defines NixOS system configurations.
+ '';
+ inventory = output: {
+ children = builtins.mapAttrs (configName: machine:
+ {
+ what = "NixOS configuration";
+ derivationAttrPath = [ "config" "system" "build" "toplevel" ];
+ }) output;
+ };
+ };
+};
+```
diff --git a/doc/manual/source/protocols/json/schema/derivation-options-v1.yaml b/doc/manual/source/protocols/json/schema/derivation-options-v1.yaml
index 58ff070882ff..d247802cd6c2 100644
--- a/doc/manual/source/protocols/json/schema/derivation-options-v1.yaml
+++ b/doc/manual/source/protocols/json/schema/derivation-options-v1.yaml
@@ -9,7 +9,7 @@ description: |
> **Warning**
>
> This JSON format is currently
- > [**experimental**](@docroot@/development/experimental-features.md#xp-feature-nix-command)
+ > [**experimental**](@docroot@/development/experimental-features.md)
> and subject to change.
type: object
diff --git a/doc/manual/source/protocols/json/schema/derivation-v4.yaml b/doc/manual/source/protocols/json/schema/derivation-v4.yaml
index 2528f7502e63..c1884769671e 100644
--- a/doc/manual/source/protocols/json/schema/derivation-v4.yaml
+++ b/doc/manual/source/protocols/json/schema/derivation-v4.yaml
@@ -9,7 +9,7 @@ description: |
> **Warning**
>
> This JSON format is currently
- > [**experimental**](@docroot@/development/experimental-features.md#xp-feature-nix-command)
+ > [**experimental**](@docroot@/development/experimental-features.md)
> and subject to change.
type: object
@@ -94,8 +94,8 @@ properties:
>
> ```json
> "srcs": [
- > "47y241wqdhac3jm5l7nv0x4975mb1975-separate-debug-info.sh",
- > "56d0w71pjj9bdr363ym3wj1zkwyqq97j-fix-pop-var-context-error.patch"
+ > "b8nwz167km1yciqpwzjj24f8jcy8pq1h-separate-debug-info.sh",
+ > "ihzmilr413r8fb3ah30yjnhlb18c1laz-fix-pop-var-context-error.patch"
> ]
> ```
items:
@@ -140,7 +140,7 @@ properties:
description: |
Absolute path of the program used to perform the build.
Typically this is the `bash` shell
- (e.g. `/nix/store/r3j288vpmczbl500w6zz89gyfa4nr0b1-bash-4.4-p23/bin/bash`).
+ (e.g. `/nix/store/p4xlj4imjbnm4v0x5jf4qysvyjjlgq1d-bash-4.4-p23/bin/bash`).
args:
type: array
diff --git a/doc/manual/source/protocols/json/schema/store-object-info-v2.yaml b/doc/manual/source/protocols/json/schema/store-object-info-v2.yaml
index 3ed7e99e28d8..582b5e9eb476 100644
--- a/doc/manual/source/protocols/json/schema/store-object-info-v2.yaml
+++ b/doc/manual/source/protocols/json/schema/store-object-info-v2.yaml
@@ -6,12 +6,6 @@ description: |
This schema describes the JSON representation of store object metadata as returned by commands like [`nix path-info --json`](@docroot@/command-ref/new-cli/nix3-path-info.md).
- > **Warning**
- >
- > This JSON format is currently
- > [**experimental**](@docroot@/development/experimental-features.md#xp-feature-nix-command)
- > and subject to change.
-
### Field Categories
Store object information can come in a few different variations.
@@ -185,6 +179,15 @@ $defs:
The total size of this store object and every other object in its [closure](@docroot@/glossary.md#gloss-closure).
> This field is not stored at all, but computed by traversing the other fields across all the store objects in a closure.
+
+ provenance:
+ oneOf:
+ - type: "null"
+ - type: object # FIXME
+ title: Provenance
+ description: |
+ An arbitrary JSON object containing provenance information about the store object, or `null` if not available.
+
additionalProperties: false
narInfo:
@@ -268,4 +271,13 @@ $defs:
> This is an impure "`.narinfo`" field that may not be included in certain contexts.
> This field is not stored at all, but computed by traversing the other fields across all the store objects in a closure.
+
+ provenance:
+ oneOf:
+ - type: "null"
+ - type: object # FIXME
+ title: Provenance
+ description: |
+ An arbitrary JSON object containing provenance information about the store object, or `null` if not available.
+
additionalProperties: false
diff --git a/doc/manual/source/protocols/json/schema/store-path-v1.yaml b/doc/manual/source/protocols/json/schema/store-path-v1.yaml
index 2012aab99150..61653d60e214 100644
--- a/doc/manual/source/protocols/json/schema/store-path-v1.yaml
+++ b/doc/manual/source/protocols/json/schema/store-path-v1.yaml
@@ -6,12 +6,6 @@ description: |
This schema describes the JSON representation of store paths as used in various Nix JSON APIs.
- > **Warning**
- >
- > This JSON format is currently
- > [**experimental**](@docroot@/development/experimental-features.md#xp-feature-nix-command)
- > and subject to change.
-
## Format
Store paths in JSON are represented as strings containing just the hash and name portion, without the store directory prefix.
diff --git a/doc/manual/source/protocols/json/schema/store-v1.yaml b/doc/manual/source/protocols/json/schema/store-v1.yaml
index e0c6f8fed6ce..31aa10c41476 100644
--- a/doc/manual/source/protocols/json/schema/store-v1.yaml
+++ b/doc/manual/source/protocols/json/schema/store-v1.yaml
@@ -10,7 +10,7 @@ description: |
> **Warning**
>
> This JSON format is currently
- > [**experimental**](@docroot@/development/experimental-features.md#xp-feature-nix-command)
+ > [**experimental**](@docroot@/development/experimental-features.md)
> and subject to change.
type: object
diff --git a/doc/manual/source/protocols/wasm.md b/doc/manual/source/protocols/wasm.md
new file mode 100644
index 000000000000..ca67491cadd5
--- /dev/null
+++ b/doc/manual/source/protocols/wasm.md
@@ -0,0 +1,379 @@
+# Wasm Host Interface
+
+Nix provides a builtin for calling WebAssembly modules: `builtins.wasm`. This allows extending Nix with custom functionality written in languages that compile to WebAssembly (such as Rust).
+
+## Overview
+
+WebAssembly modules can interact with Nix values through a host interface that provides functions for creating and inspecting Nix values. The WASM module receives Nix values as opaque `ValueId` handles and uses host functions to work with them.
+
+The `builtins.wasm` builtin takes two arguments:
+1. A configuration attribute set with the following attributes:
+ - `path` - Path to the WebAssembly module (required)
+ - `function` - Name of the Wasm function to call (required for non-WASI modules, not allowed for WASI modules)
+2. The argument value to pass to the function
+
+WASI mode is automatically detected by checking if the module imports from `wasi_snapshot_preview1`. There are two calling conventions:
+
+- **Non-WASI mode** (no WASI imports) calls the Wasm export specified by `function` directly. The function receives its input as a `ValueId` parameter and returns a `ValueId`.
+- **WASI mode** (when the module imports from `wasi_snapshot_preview1`) runs the WASI module's `_start` entry point. The input `ValueId` is passed as a command-line argument (`argv[1]`), and the result is returned by calling the `return_to_nix` host function.
+
+## Value IDs
+
+Nix values are represented in Wasm code as a `u32` referred to below as a `ValueId`. These are opaque handles that reference values managed by the Nix evaluator. Value ID 0 is reserved to represent a missing attribute lookup result.
+
+## Entry Points
+
+### Non-WASI Mode
+
+Non-WASI mode is used when the module does **not** import from `wasi_snapshot_preview1`.
+
+Usage:
+```nix
+builtins.wasm {
+ path = ;
+ function = ;
+}
+```
+
+Every Wasm module used in non-WASI mode must export:
+- A `memory` object that the host can use to read/write data.
+- `nix_wasm_init_v1()`, a function that is called once when the module is instantiated.
+- The entry point function, whose name is specified by the `function` attribute. It takes a single `ValueId` and returns a single `ValueId` (i.e. it has type `fn(arg: u32) -> u32`).
+
+### WASI Mode
+
+WASI mode is automatically used when the module imports a `wasi_snapshot_preview1` function.
+
+Usage:
+```nix
+builtins.wasm {
+ path = ;
+}
+```
+
+Every WASI module must export:
+- A `memory` object that the host can use to read/write data.
+- `_start()`, the standard WASI entry point. This function takes no parameters.
+
+The input value is passed as a command-line argument: `argv[1]` is set to the decimal representation of the `ValueId` of the input value.
+
+To return a result to Nix, the module must call the `return_to_nix` host function (see below) with the `ValueId` of the result. If `_start` finishes without calling `return_to_nix`, an error is raised.
+
+Standard output and standard error from the WASI module are captured and emitted as Nix warnings (one warning per line).
+
+## Host Functions
+
+All host functions are imported from the `env` module.
+
+### Error Handling
+
+#### `panic(ptr: u32, len: u32)`
+
+Aborts execution with an error message.
+
+**Parameters:**
+- `ptr` - Pointer to UTF-8 encoded error message in Wasm memory
+- `len` - Length of the error message in bytes
+
+#### `warn(ptr: u32, len: u32)`
+
+Emits a warning message.
+
+**Parameters:**
+- `ptr` - Pointer to UTF-8 encoded warning message in Wasm memory
+- `len` - Length of the warning message in bytes
+
+### Type Inspection
+
+#### `get_type(value: ValueId) -> u32`
+
+Returns the type of a Nix value.
+
+**Parameters:**
+- `value` - ID of a Nix value
+
+**Return values:**
+- `1` - Integer
+- `2` - Float
+- `3` - Boolean
+- `4` - String
+- `5` - Path
+- `6` - Null
+- `7` - Attribute set
+- `8` - List
+- `9` - Function
+
+**Note:** Forces evaluation of the value.
+
+### Integer Operations
+
+#### `make_int(n: i64) -> ValueId`
+
+Creates a Nix integer value.
+
+**Parameters:**
+- `n` - The integer value
+
+**Returns:** Value ID of the created integer
+
+#### `get_int(value: ValueId) -> i64`
+
+Extracts an integer from a Nix value. Throws an error if the value is not an integer.
+
+**Parameters:**
+- `value` - ID of a Nix integer value
+
+**Returns:** The integer value
+
+### Float Operations
+
+#### `make_float(x: f64) -> ValueId`
+
+Creates a Nix float value.
+
+**Parameters:**
+- `x` - The float value
+
+**Returns:** Value ID of the created float
+
+#### `get_float(value: ValueId) -> f64`
+
+Extracts a float from a Nix value. Throws an error if the value is not a float.
+
+**Parameters:**
+- `value` - ID of a Nix float value
+
+**Returns:** The float value
+
+### Boolean Operations
+
+#### `make_bool(b: i32) -> ValueId`
+
+Creates a Nix Boolean value.
+
+**Parameters:**
+- `b` - Boolean value (0 = false, non-zero = true)
+
+**Returns:** Value ID of the created Boolean
+
+#### `get_bool(value: ValueId) -> i32`
+
+Extracts a Boolean from a Nix value. Throws an error if the value is not a Boolean.
+
+**Parameters:**
+- `value` - ID of a Nix Boolean value
+
+**Returns:** 0 for false, 1 for true
+
+### Null Operations
+
+#### `make_null() -> ValueId`
+
+Creates a Nix null value.
+
+**Returns:** Value ID of the null value
+
+### String Operations
+
+#### `make_string(ptr: u32, len: u32) -> ValueId`
+
+Creates a Nix string value from Wasm memory.
+
+**Parameters:**
+- `ptr` - Pointer to a string in Wasm memory
+- `len` - Length of the string in bytes
+
+**Note:** Strings do not require a null terminator.
+
+**Returns:** Value ID of the created string
+
+#### `copy_string(value: ValueId, ptr: u32, max_len: u32) -> u32`
+
+Copies a Nix string value into Wasm memory.
+
+**Parameters:**
+- `value` - ID of a string value
+- `ptr` - Pointer to buffer in Wasm memory
+- `max_len` - Maximum number of bytes to copy
+
+**Returns:** The actual length of the string in bytes
+
+**Note:** If the returned length is greater than `max_len`, no data is copied. Call again with a larger buffer to get the full string.
+
+### Path Operations
+
+#### `make_path(base: ValueId, ptr: u32, len: u32) -> ValueId`
+
+Creates a Nix path value relative to a base path.
+
+**Parameters:**
+- `base` - ID of a path value
+- `ptr` - Pointer to a string in Wasm memory
+- `len` - Length of the path string in bytes
+
+**Returns:** ID of a new path value
+
+**Note:** The path string is interpreted relative to the base path. The resulting path is in the same source tree ("source accessor") as the original path.
+
+#### `copy_path(value: ValueId, ptr: u32, max_len: u32) -> u32`
+
+Copies a Nix path value into Wasm memory as an absolute path string.
+
+**Parameters:**
+- `value` - ID of a path value
+- `ptr` - Pointer to buffer in Wasm memory
+- `max_len` - Maximum number of bytes to copy
+
+**Returns:** The actual length of the path string in bytes
+
+**Note:** If the returned length is greater than `max_len`, no data is copied.
+
+### List Operations
+
+#### `make_list(ptr: u32, len: u32) -> ValueId`
+
+Creates a Nix list from an array of value IDs in Wasm memory.
+
+**Parameters:**
+- `ptr` - Pointer to array of `ValueId` (u32) in Wasm memory
+- `len` - Number of elements in the array
+
+**Returns:** Value ID of the created list
+
+**Note:** The array must contain `len * 4` bytes (each ValueId is 4 bytes).
+
+#### `copy_list(value: ValueId, ptr: u32, max_len: u32) -> u32`
+
+Copies a Nix list into Wasm memory as an array of value IDs.
+
+**Parameters:**
+- `value` - ID of a list value
+- `ptr` - Pointer to buffer in Wasm memory
+- `max_len` - Maximum number of elements to copy
+
+**Returns:** The actual number of elements in the list
+
+**Note:** If the returned length is greater than `max_len`, no data is copied. Each element is written as a `ValueId` (4 bytes). The buffer must be `max_len * 4` bytes large.
+
+### Attribute Set Operations
+
+#### `make_attrset(ptr: u32, len: u32) -> ValueId`
+
+Creates a Nix attribute set from an array of attributes in Wasm memory.
+
+**Parameters:**
+- `ptr` - Pointer to array of attribute structures in Wasm memory
+- `len` - Number of attributes
+
+**Returns:** Value ID of the created attribute set
+
+**Attribute structure format:**
+```c
+struct Attr {
+ name_ptr: u32, // Pointer to attribute name
+ name_len: u32, // Length of attribute name in bytes
+ value_id: u32, // ID of the attribute value
+}
+```
+
+Each `Attr` element is 12 bytes (3 × 4 bytes).
+
+#### `copy_attrset(value: ValueId, ptr: u32, max_len: u32) -> u32`
+
+Copies a Nix attribute set into Wasm memory as an array of attribute structures.
+
+**Parameters:**
+- `value` - ID of a Nix attribute set value
+- `ptr` - Pointer to buffer in Wasm memory
+- `max_len` - Maximum number of attributes to copy
+
+**Returns:** The actual number of attributes in the set
+
+**Note:** If the returned length is greater than `max_len`, no data is copied.
+
+**Output structure format:**
+```c
+struct Attr {
+ value_id: u32, // ID of the attribute value
+ name_len: u32, // Length of attribute name in bytes
+}
+```
+
+Each attribute is 8 bytes (2 × 4 bytes). Use `copy_attrname` to retrieve attribute names.
+
+#### `copy_attrname(value: ValueId, attr_idx: u32, ptr: u32, len: u32)`
+
+Copies an attribute name into Wasm memory.
+
+**Parameters:**
+- `value` - ID of a Nix attribute set value
+- `attr_idx` - Index of the attribute (from `copy_attrset`)
+- `ptr` - Pointer to buffer in Wasm memory
+- `len` - Length of the buffer (must exactly match the attribute name length)
+
+**Note:** Throws an error if `len` doesn't match the attribute name length or if `attr_idx` is out of bounds.
+
+#### `get_attr(value: ValueId, ptr: u32, len: u32) -> ValueId`
+
+Gets an attribute value from an attribute set by name.
+
+**Parameters:**
+- `value` - ID of a Nix attribute set value
+- `ptr` - Pointer to the attribute name in Wasm memory
+- `len` - Length of the attribute name in bytes
+
+**Returns:** Value ID of the attribute value, or 0 if the attribute doesn't exist
+
+### Function Operations
+
+#### `call_function(fun: ValueId, ptr: u32, len: u32) -> ValueId`
+
+Calls a Nix function with arguments.
+
+**Parameters:**
+- `fun` - ID of a Nix function value
+- `ptr` - Pointer to array of `ValueId` arguments in Wasm memory
+- `len` - Number of arguments
+
+**Returns:** Value ID of the function result
+
+#### `make_app(fun: ValueId, ptr: u32, len: u32) -> ValueId`
+
+Creates a lazy or partially applied function application.
+
+**Parameters:**
+- `fun` - ID of a Nix function value
+- `ptr` - Pointer to array of `ValueId` arguments in Wasm memory
+- `len` - Number of arguments
+
+**Returns:** Value ID of the unevaluated application
+
+### Returning Results (WASI mode only)
+
+#### `return_to_nix(value: ValueId)`
+
+Returns a result value to the Nix evaluator from a WASI module. This function is only available in WASI mode.
+
+**Parameters:**
+- `value` - ID of the Nix value to return as the result of the `builtins.wasm` call
+
+**Note:** Calling this function immediately terminates the WASI module's execution. The module must call `return_to_nix` before finishing; otherwise, an error is raised.
+
+### File I/O
+
+#### `read_file(path: ValueId, ptr: u32, len: u32) -> u32`
+
+Reads a file into Wasm memory.
+
+**Parameters:**
+- `path` - Value ID of a Nix path value
+- `ptr` - Pointer to buffer in Wasm memory
+- `len` - Maximum number of bytes to read
+
+**Returns:** The actual file size in bytes
+
+**Note:** Similar to `builtins.readFile`, but can handle files that cannot be represented as Nix strings (in particular, files containing NUL bytes). If the returned size is greater than `len`, no data is copied.
+
+## Example Usage
+
+For Rust bindings to this interface and several examples, see https://github.com/DeterminateSystems/nix-wasm-rust/.
diff --git a/doc/manual/source/quick-start.md b/doc/manual/source/quick-start.md
index 9eb7a3265903..42e4e9c0c247 100644
--- a/doc/manual/source/quick-start.md
+++ b/doc/manual/source/quick-start.md
@@ -3,10 +3,13 @@
This chapter is for impatient people who don't like reading documentation.
For more in-depth information you are kindly referred to subsequent chapters.
-1. Install Nix:
+1. Install Nix.
+ We recommend that macOS users install Determinate Nix using our graphical installer, [Determinate.pkg][pkg].
+ For Linux and Windows Subsystem for Linux (WSL) users:
```console
- $ curl -L https://nixos.org/nix/install | sh
+ $ curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | \
+ sh -s -- install
```
The install script will use `sudo`, so make sure you have sufficient rights.
@@ -41,3 +44,5 @@ For more in-depth information you are kindly referred to subsequent chapters.
```console
$ nix-collect-garbage
```
+
+[pkg]: https://install.determinate.systems/determinate-pkg/stable/Universal
diff --git a/doc/manual/source/release-notes-determinate/changes.md b/doc/manual/source/release-notes-determinate/changes.md
new file mode 100644
index 000000000000..80446d6d6ea5
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/changes.md
@@ -0,0 +1,200 @@
+# Changes between Nix and Determinate Nix
+
+This section lists the differences between upstream Nix 2.33 and Determinate Nix 3.17.0.
+
+* In Determinate Nix, flakes are stable. You no longer need to enable the `flakes` experimental feature.
+
+* In Determinate Nix, the new Nix CLI (i.e. the `nix` command) is stable. You no longer need to enable the `nix-command` experimental feature.
+
+* Determinate Nix has a setting [`json-log-path`](@docroot@/command-ref/conf-file.md#conf-json-log-path) to send a copy of all Nix log messages (in JSON format) to a file or Unix domain socket.
+
+* Determinate Nix has made `nix profile install` an alias to `nix profile add`, a more symmetrical antonym of `nix profile remove`.
+
+* `nix-channel` and `channel:` url syntax (like `channel:nixos-24.11`) is deprecated, see: https://github.com/DeterminateSystems/nix-src/issues/34
+
+* Using indirect flake references and implicit inputs is deprecated, see: https://github.com/DeterminateSystems/nix-src/issues/37
+
+* Warnings around "dirty trees" are updated to reduce "dirty" jargon, and now refers to "uncommitted changes".
+
+
+
+
+
+
+
+* `nix upgrade-nix` is now inert, and suggests using `determinate-nixd upgrade`. [DeterminateSystems/nix-src#55](https://github.com/DeterminateSystems/nix-src/pull/55)
+
+* Determinate Nix has Lazy Trees, avoiding expensive copying of flake inputs to the Nix store. ([DeterminateSystems/nix-src#27](https://github.com/DeterminateSystems/nix-src/pull/27), [DeterminateSystems/nix-src#56](https://github.com/DeterminateSystems/nix-src/pull/56))
+
+
+
+
+
+
+
+
+
+* Documentation on how to replicate `nix-store --query --deriver` with the new `nix` cli. [DeterminateSystems/nix-src#82](https://github.com/DeterminateSystems/nix-src/pull/82)
+
+* In `nix profile`, the symbols `ε` and `∅` have been replaced with descriptive English words. [DeterminateSystems/nix-src#81](https://github.com/DeterminateSystems/nix-src/pull/81)
+
+
+
+
+
+
+
+* When remote building with `--keep-failed`, Determinate Nix shows "you can rerun" message if the derivation's platform is supported on this machine. [DeterminateSystems/nix-src#87](https://github.com/DeterminateSystems/nix-src/pull/87)
+
+* Improved error message when `sandbox-paths` specifies a missing file. [DeterminateSystems/nix-src#88](https://github.com/DeterminateSystems/nix-src/pull/88)
+
+
+
+
+
+
+
+
+
+* `nix store delete` now explains why deletion fails. [DeterminateSystems/nix-src#130](https://github.com/DeterminateSystems/nix-src/pull/130)
+
+
+
+
+
+
+
+
+
+
+
+
+
+* Tab completing arguments to Nix avoids network access. [DeterminateSystems/nix-src#161](https://github.com/DeterminateSystems/nix-src/pull/161)
+
+* Importing Nixpkgs and other tarballs to the cache is 2-4x faster. [DeterminateSystems/nix-src#149](https://github.com/DeterminateSystems/nix-src/pull/149)
+
+* Adding paths to the store is significantly faster. [DeterminateSystems/nix-src#162](https://github.com/DeterminateSystems/nix-src/pull/162)
+
+
+
+
+
+* Determinate Nix allows flake inputs to be fetched at build time. [DeterminateSystems/nix-src#49](https://github.com/DeterminateSystems/nix-src/pull/49)
+
+
+
+* The default `nix flake init` template is much more useful. [DeterminateSystems/nix-src#180](https://github.com/DeterminateSystems/nix-src/pull/180)
+
+
+
+
+
+
+
+
+* Multithreaded evaluation support. [DeterminateSystems/nix-src#125](https://github.com/DeterminateSystems/nix-src/pull/125)
+
+
+
+
+
+
+* Determinate Nix only tries to substitute inputs if fetching from its original location fails.[DeterminateSystems/nix-src#202](https://github.com/DeterminateSystems/nix-src/pull/202)
+
+
+
+
+
+
+* A new command `nix nario` that replaces `nix-store --export|--export`. It also has a new file format (`--format 2`) that supports store path attributes such as signatures, and that can be imported more efficiently. [DeterminateSystems/nix-src#215](https://github.com/DeterminateSystems/nix-src/pull/215)
+
+* Determinate Nix prints the Nix version when using `-vv` or higher verbosity. [DeterminateSystems/nix-src#237](https://github.com/DeterminateSystems/nix-src/pull/237)
+
+
+
+
+* During evaluation, you can read or import from the result of `builtins.fetchClosure`. [DeterminateSystems/nix-src#241](https://github.com/DeterminateSystems/nix-src/pull/241)
+
+
+
+* Flakerefs in error messages and lockfile diffs are abbreviated for readability. [DeterminateSystems/nix-src#243](https://github.com/DeterminateSystems/nix-src/pull/243), [DeterminateSystems/nix-src#264](https://github.com/DeterminateSystems/nix-src/pull/264)
+
+
+
+
+
+
+
+
+* The Git fetcher doesn't compute `revCount` or `lastModified` if they're already specified [DeterminateSystems./nix-src#269](https://github.com/DeterminateSystems/nix-src/pull/269)
+
+* The Git fetcher avoids doing a shallow Git fetch if it previously did a non-shallow fetch of the same repository. [DeterminateSystems/nix-src#270](https://github.com/DeterminateSystems/nix-src/pull/270)
+
+* Determinate Nix has a builtin copy of the flake registry, making it more resilient to network outages. [DeterminateSystems/nix-src#271](https://github.com/DeterminateSystems/nix-src/pull/271)
+
+
+
+* `nix build` and `nix profile` report failing or succeeding installables. [DeterminateSystems/nix-src#281](https://github.com/DeterminateSystems/nix-src/pull/281)
+
+* `nix flake check` shows which outputs failed or succeeded. [DeterminateSystems/nix-src#285](https://github.com/DeterminateSystems/nix-src/pull/285)
+
+* Determinate Nix has a `nix ps` command to show active builds. [DeterminateSystems/nix-src#282](https://github.com/DeterminateSystems/nix-src/pull/282)
+
+* Determinate Nix has improved backward compatibility with lock files created by Nix < 2.20. [DeterminateSystems/nix-src#278](https://github.com/DeterminateSystems/nix-src/pull/278)
+
+
+
+* Determinate Nix has a builtin function `builtins.filterAttrs`. [DeterminateSystems/nix-src#291](https://github.com/DeterminateSystems/nix-src/pull/291)
+
+* `builtins.fetchTree` implicitly sets `__final = true` when a `narHash` is supplied. This allows the tree to be substituted. [DeterminateSystems/nix-src#297](https://github.com/DeterminateSystems/nix-src/pull/297)
+
+
+
+
+
+* Path inputs are now lazy [DeterminateSystems/nix-src#312](https://github.com/DeterminateSystems/nix-src/pull/312)
+
+* Improved performance when fetching a lot of dependencies with curl [DeterminateSystems/nix-src#315](https://github.com/DeterminateSystems/nix-src/pull/315)
+
+
+
+* Wasm support [DeterminateSystems/nix-src#309](https://github.com/DeterminateSystems/nix-src/pull/309)
+
+* Fix hung downloads when `http-connections = 0` [DeterminateSystems/nix-src#327](https://github.com/DeterminateSystems/nix-src/pull/327)
+
+* Support .gitattributes in subdirectories [DeterminateSystems/nix-src#335](https://github.com/DeterminateSystems/nix-src/pull/335)
+
+* builtins.getFlake fixes [DeterminateSystems/nix-src#337](https://github.com/DeterminateSystems/nix-src/pull/337)
+
+* builtins.getFlake: Support path values [DeterminateSystems/nix-src#338](https://github.com/DeterminateSystems/nix-src/pull/338)
+
+* Provenance [DeterminateSystems/nix-src#321](https://github.com/DeterminateSystems/nix-src/pull/321)
+
+* Add subcommand 'nix provenance show' [DeterminateSystems/nix-src#340](https://github.com/DeterminateSystems/nix-src/pull/340)
+
+* Increase the open file soft limit to the hard limit [DeterminateSystems/nix-src#347](https://github.com/DeterminateSystems/nix-src/pull/347)
+
+
+
+
+* Record provenance for unlocked inputs and impure evaluations in [DeterminateSystems/nix-src#354](https://github.com/DeterminateSystems/nix-src/pull/354)
+
+* Add setting narinfo-cache-meta-ttl in [DeterminateSystems/nix-src#355](https://github.com/DeterminateSystems/nix-src/pull/355)
+
+* Add derivationWithMeta builtin in [DeterminateSystems/nix-src#357](https://github.com/DeterminateSystems/nix-src/pull/357)
+
+* Add builtins.wasi in [DeterminateSystems/nix-src#359](https://github.com/DeterminateSystems/nix-src/pull/359)
+
+* Add `nix provenance verify` command in [DeterminateSystems/nix-src#356](https://github.com/DeterminateSystems/nix-src/pull/356)
+
+* builtins.hashString: Devirtualize lazy paths, and re-enable lazy trees tests in [DeterminateSystems/nix-src#360](https://github.com/DeterminateSystems/nix-src/pull/360)
+
+
+
+
+
+
+
+
+
diff --git a/doc/manual/source/release-notes-determinate/index.md b/doc/manual/source/release-notes-determinate/index.md
new file mode 100644
index 000000000000..bba33084424c
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/index.md
@@ -0,0 +1,3 @@
+# Determinate Nix Release Notes
+
+This chapter lists the differences between Nix and Determinate Nix, as well as the release history of Determinate Nix.
diff --git a/doc/manual/source/release-notes-determinate/rl-3.0.0.md b/doc/manual/source/release-notes-determinate/rl-3.0.0.md
new file mode 100644
index 000000000000..d60786e9a72f
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.0.0.md
@@ -0,0 +1,5 @@
+# Release 3.0.0 (2025-03-04)
+
+* Initial release of Determinate Nix.
+
+* Based on [upstream Nix 2.26.2](../release-notes/rl-2.26.md).
diff --git a/doc/manual/source/release-notes-determinate/rl-3.1.0.md b/doc/manual/source/release-notes-determinate/rl-3.1.0.md
new file mode 100644
index 000000000000..96b7819d08db
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.1.0.md
@@ -0,0 +1,5 @@
+# Release 3.1.0 (2025-03-27)
+
+* Based on [upstream Nix 2.27.1](../release-notes/rl-2.27.md).
+
+* New setting `json-log-path` that sends a copy of all Nix log messages (in JSON format) to a file or Unix domain socket.
diff --git a/doc/manual/source/release-notes-determinate/rl-3.3.0.md b/doc/manual/source/release-notes-determinate/rl-3.3.0.md
new file mode 100644
index 000000000000..badf96415df0
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.3.0.md
@@ -0,0 +1,5 @@
+# Release 3.3.0 (2025-04-11)
+
+* Based on [upstream Nix 2.28.1](../release-notes/rl-2.28.md).
+
+* The `nix profile install` command is now an alias to `nix profile add`, a more symmetrical antonym of `nix profile remove`.
diff --git a/doc/manual/source/release-notes-determinate/rl-3.4.0.md b/doc/manual/source/release-notes-determinate/rl-3.4.0.md
new file mode 100644
index 000000000000..24ae03ca554f
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.4.0.md
@@ -0,0 +1,50 @@
+# Release 3.4.0 (2025-04-25)
+
+* Based on [upstream Nix 2.28.2](../release-notes/rl-2.28.md).
+
+* **Warn users that `nix-channel` is deprecated.**
+
+This is the first change accomplishing our roadmap item of deprecating Nix channels: https://github.com/DeterminateSystems/nix-src/issues/34
+
+This is due to user confusion and surprising behavior of channels, especially in the context of user vs. root channels.
+
+The goal of this change is to make the user experience of Nix more predictable.
+In particular, these changes are to support users with lower levels of experience who are following guides that focus on channels as the mechanism of distribution.
+
+Users will now see this message:
+
+> nix-channel is deprecated in favor of flakes in Determinate Nix. For a guide on Nix flakes, see: https://zero-to-nix.com/. or details and to offer feedback on the deprecation process, see: https://github.com/DeterminateSystems/nix-src/issues/34.
+
+
+* **Warn users that `channel:` URLs are deprecated.**
+
+This is the second change regarding our deprecation of Nix channels.
+Using a `channel:` URL (like `channel:nixos-24.11`) will yield a warning like this:
+
+> Channels are deprecated in favor of flakes in Determinate Nix. Instead of 'channel:nixos-24.11', use 'https://nixos.org/channels/nixos-24.11/nixexprs.tar.xz'. For a guide on Nix flakes, see: https://zero-to-nix.com/. For details and to offer feedback on the deprecation process, see: https://github.com/DeterminateSystems/nix-src/issues/34.
+
+* **Warn users against indirect flake references in `flake.nix` inputs**
+
+This is the first change accomplishing our roadmap item of deprecating implicit and indirect flake inputs: https://github.com/DeterminateSystems/nix-src/issues/37
+
+The flake registry provides an important UX affordance for using Nix flakes and remote sources in command line uses.
+For that reason, the registry is not being deprecated entirely and will still be used for command-line incantations, like nix run.
+
+This move will eliminate user confusion and surprising behavior around global and local registries during flake input resolution.
+
+The goal of this change is to make the user experience of Nix more predictable.
+We have seen a pattern of confusion when using automatic flake inputs and local registries.
+Specifically, users' flake inputs resolving and locking inconsistently depending on the configuration of the host system.
+
+Users will now see the following warning if their flake.nix uses an implicit or indirect Flake reference input:
+
+> Flake input 'nixpkgs' uses the flake registry. Using the registry in flake inputs is deprecated in Determinate Nix. To make your flake future-proof, add the following to 'xxx/flake.nix':
+>
+> inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
+>
+> For more information, see: https://github.com/DeterminateSystems/nix-src/issues/37
+
+
+### Other updates:
+* Improve the "dirty tree" message. Determinate Nix will now say `Git tree '...' has uncommitted changes` instead of `Git tree '...' is dirty`
+* Stop warning about uncommitted changes in a Git repository when using `nix develop`
diff --git a/doc/manual/source/release-notes-determinate/rl-3.4.2.md b/doc/manual/source/release-notes-determinate/rl-3.4.2.md
new file mode 100644
index 000000000000..8acabd4425fd
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.4.2.md
@@ -0,0 +1,4 @@
+# Release 3.4.2 (2025-05-05)
+
+* Based on [upstream Nix 2.28.3](../release-notes/rl-2.28.md).
+
diff --git a/doc/manual/source/release-notes-determinate/rl-3.5.0.md b/doc/manual/source/release-notes-determinate/rl-3.5.0.md
new file mode 100644
index 000000000000..d5b26b9419e7
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.5.0.md
@@ -0,0 +1,4 @@
+# Release 3.5.0 (2025-05-09)
+
+* Based on [upstream Nix 2.28.3](../release-notes/rl-2.28.md).
+
diff --git a/doc/manual/source/release-notes-determinate/rl-3.5.1.md b/doc/manual/source/release-notes-determinate/rl-3.5.1.md
new file mode 100644
index 000000000000..b0813ca59c90
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.5.1.md
@@ -0,0 +1,57 @@
+# Release 3.5.1 (2025-05-09)
+
+* Based on [upstream Nix 2.28.3](../release-notes/rl-2.28.md).
+
+## What's Changed
+
+Most notably, Lazy Trees has merged in to Determinate Nix and is in Feature Preview status, but remains disabled by default.
+Lazy trees massively improves performance in virtually all scenarios because it enables Nix to avoid making unnecessary copies of files into the Nix store.
+In testing, we saw iteration times on Nixpkgs **drop from over 12 seconds to 3.5 seconds**.
+
+After upgrading to Determinate Nix 3.5.1 with `sudo determinate-nixd upgrade`, enable lazy trees by adding this to `/etc/nix/nix.custom.conf`:
+
+```
+lazy-trees = true
+```
+
+Please note that our full flake regression test suite passes with no changes with lazy trees, and please report compatibility issues.
+
+Read [this GitHub comment](https://github.com/DeterminateSystems/nix-src/pull/27#pullrequestreview-2822153088) for further details and next steps.
+We'll be publishing an update on the [Determinate Systems blog](https://determinate.systems/posts/) in the next few days with more information as well.
+
+Relevant PRs:
+* Lazy trees v2 by @edolstra in [DeterminateSystems/nix-src#27](https://github.com/DeterminateSystems/nix-src/pull/27)
+* Improve lazy trees backward compatibility by @edolstra in [DeterminateSystems/nix-src#56](https://github.com/DeterminateSystems/nix-src/pull/56)
+
+
+### Additional changes in this release:
+* Bug fix: Flake input URLs are canonicalized before checking flake.lock file staleness, avoiding needlessly regenerating flake.lock files with `dir` in URL-style flakerefs by @edolstra in [DeterminateSystems/nix-src#57](https://github.com/DeterminateSystems/nix-src/pull/57)
+* `nix upgrade-nix` is deprecated in favor of `determinate-nixd upgrade`, by @gustavderdrache in [DeterminateSystems/nix-src#55](https://github.com/DeterminateSystems/nix-src/pull/55)
+* UX: Improved build failure and dependency failure error messages to include needed output paths by @edolstra in [DeterminateSystems/nix-src#58](https://github.com/DeterminateSystems/nix-src/pull/58).
+
+Previously:
+
+```
+error: builder for '/nix/store/[...]-nested-failure-bottom.drv' failed with exit code 1
+error: 1 dependencies of derivation '/nix/store/[...]-nested-failure-middle.drv' failed to build
+error: 1 dependencies of derivation '/nix/store/[...]-nested-failure-top.drv' failed to build
+```
+
+Now:
+
+```
+error: Cannot build '/nix/store/w37gflm9wz9dcnsgy3sfrmnlvm8qigaj-nested-failure-bottom.drv'.
+ Reason: builder failed with exit code 1.
+ Output paths:
+ /nix/store/yzybs8kp35dfipbzdlqcc6lxz62hax04-nested-failure-bottom
+error: Cannot build '/nix/store/00gr5hlxfc03x2675w6nn3pwfrz2fr62-nested-failure-middle.drv'.
+ Reason: 1 dependency failed.
+ Output paths:
+ /nix/store/h781j5h4bdchmb4c2lvy8qzh8733azhz-nested-failure-middle
+error: Cannot build '/nix/store/8am0ng1gyx8sbzyr0yx6jd5ix3yy5szc-nested-failure-top.drv'.
+ Reason: 1 dependency failed.
+ Output paths:
+ /nix/store/fh12637kgvp906s9yhi9w2dc7ghfwxs1-nested-failure-top
+```
+
+**Full Changelog**: [v3.4.2...v3.5.1](https://github.com/DeterminateSystems/nix-src/compare/v3.4.2...v3.5.1)
diff --git a/doc/manual/source/release-notes-determinate/rl-3.5.2.md b/doc/manual/source/release-notes-determinate/rl-3.5.2.md
new file mode 100644
index 000000000000..bc5396c255b6
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.5.2.md
@@ -0,0 +1,11 @@
+# Release 3.5.2 (2025-05-12)
+
+* Based on [upstream Nix 2.28.3](../release-notes/rl-2.28.md).
+
+## What's Changed
+* Fix a regression where narHash was not added to lock files when lazy trees were disabled by @edolstra in [DeterminateSystems/nix-src#63](https://github.com/DeterminateSystems/nix-src/pull/63)
+
+* Tell users a source is corrupted ("cannot read file from tarball: Truncated tar archive detected while reading data"), improving over the previous 'cannot read file from tarball' error by @edolstra in [DeterminateSystems/nix-src#64](https://github.com/DeterminateSystems/nix-src/pull/64)
+
+
+**Full Changelog**: [v3.5.1...v3.5.2](https://github.com/DeterminateSystems/nix-src/compare/v3.5.1...v3.5.2)
diff --git a/doc/manual/source/release-notes-determinate/rl-3.6.0.md b/doc/manual/source/release-notes-determinate/rl-3.6.0.md
new file mode 100644
index 000000000000..453ab6c301dc
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.6.0.md
@@ -0,0 +1,11 @@
+# Release 3.6.0 (2025-05-22)
+
+* Based on [upstream Nix 2.29.0](../release-notes/rl-2.29.md).
+
+## What's Changed
+* Install 'nix profile add' manpage by @edolstra in [DeterminateSystems/nix-src#69](https://github.com/DeterminateSystems/nix-src/pull/69)
+* Sync with upstream 2.29.0 by @edolstra in [DeterminateSystems/nix-src#67](https://github.com/DeterminateSystems/nix-src/pull/67)
+* Emit warnings when using import-from-derivation by setting the `trace-import-from-derivation` option to `true` by @gustavderdrache in [DeterminateSystems/nix-src#70](https://github.com/DeterminateSystems/nix-src/pull/70)
+
+
+**Full Changelog**: [v3.5.2...v3.6.0](https://github.com/DeterminateSystems/nix-src/compare/v3.5.2...v3.6.0)
diff --git a/doc/manual/source/release-notes-determinate/rl-3.6.1.md b/doc/manual/source/release-notes-determinate/rl-3.6.1.md
new file mode 100644
index 000000000000..12505afee278
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.6.1.md
@@ -0,0 +1,9 @@
+# Release 3.6.1 (2025-05-24)
+
+* Based on [upstream Nix 2.29.0](../release-notes/rl-2.29.md).
+
+## What's Changed
+* Fix nlohmann error in fromStructuredAttrs() by @edolstra in [DeterminateSystems/nix-src#73](https://github.com/DeterminateSystems/nix-src/pull/73)
+
+
+**Full Changelog**: [v3.6.0...v3.6.1](https://github.com/DeterminateSystems/nix-src/compare/v3.6.0...v3.6.1)
diff --git a/doc/manual/source/release-notes-determinate/rl-3.6.2.md b/doc/manual/source/release-notes-determinate/rl-3.6.2.md
new file mode 100644
index 000000000000..882c142f00c3
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.6.2.md
@@ -0,0 +1,15 @@
+# Release 3.6.2 (2025-06-02)
+
+* Based on [upstream Nix 2.29.0](../release-notes/rl-2.29.md).
+
+## What's Changed
+* Dramatically improve the performance of nix store copy-sigs: Use http-connections setting to control parallelism by @edolstra in [DeterminateSystems/nix-src#80](https://github.com/DeterminateSystems/nix-src/pull/80)
+* Document how to replicate nix-store --query --deriver with the nix cli by @grahamc in [DeterminateSystems/nix-src#82](https://github.com/DeterminateSystems/nix-src/pull/82)
+* The garbage collector no longer gives up if it encounters an undeletable file, by @edolstra in [DeterminateSystems/nix-src#83](https://github.com/DeterminateSystems/nix-src/pull/83)
+* nix profile: Replace ε and ∅ with descriptive English words by @grahamc in [DeterminateSystems/nix-src#81](https://github.com/DeterminateSystems/nix-src/pull/81)
+* Rework README to clarify that this distribution is our distribution, by @lucperkins in [DeterminateSystems/nix-src#84](https://github.com/DeterminateSystems/nix-src/pull/84)
+* Include the source location when warning about inefficient double copies by @edolstra in [DeterminateSystems/nix-src#79](https://github.com/DeterminateSystems/nix-src/pull/79)
+* Call out that `--keep-failed` with remote builders will keep the failed build directory on that builder by @cole-h in [DeterminateSystems/nix-src#85](https://github.com/DeterminateSystems/nix-src/pull/85)
+
+
+**Full Changelog**: [v3.6.1...v3.6.2](https://github.com/DeterminateSystems/nix-src/compare/v3.6.1...v3.6.2)
diff --git a/doc/manual/source/release-notes-determinate/rl-3.6.5.md b/doc/manual/source/release-notes-determinate/rl-3.6.5.md
new file mode 100644
index 000000000000..8ef5be0fd0d3
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.6.5.md
@@ -0,0 +1,19 @@
+# Release 3.6.5 (2025-06-12)
+
+* Based on [upstream Nix 2.29.0](../release-notes/rl-2.29.md).
+
+## What's Changed
+* When remote building with --keep-failed, only show "you can rerun" message if the derivation's platform is supported on this machine by @cole-h in [DeterminateSystems/nix-src#87](https://github.com/DeterminateSystems/nix-src/pull/87)
+* Indicate that sandbox-paths specifies a missing file in the corresponding error message. by @cole-h in [DeterminateSystems/nix-src#88](https://github.com/DeterminateSystems/nix-src/pull/88)
+* Render lazy tree paths in messages withouth the/nix/store/hash... prefix in substituted source trees by @edolstra in [DeterminateSystems/nix-src#91](https://github.com/DeterminateSystems/nix-src/pull/91)
+* Use FlakeHub inputs by @lucperkins in [DeterminateSystems/nix-src#89](https://github.com/DeterminateSystems/nix-src/pull/89)
+* Proactively cache more flake inputs and fetches by @edolstra in [DeterminateSystems/nix-src#93](https://github.com/DeterminateSystems/nix-src/pull/93)
+* Fix: register extra builtins just once by @edolstra in [DeterminateSystems/nix-src#97](https://github.com/DeterminateSystems/nix-src/pull/97)
+* Fix the link to `builders-use-substitutes` documentation for `builders` by @lucperkins in [DeterminateSystems/nix-src#102](https://github.com/DeterminateSystems/nix-src/pull/102)
+* Improve error messages that use the hypothetical future tense of "will" by @lucperkins in [DeterminateSystems/nix-src#92](https://github.com/DeterminateSystems/nix-src/pull/92)
+* Make the `nix repl` test more stable by @edolstra in [DeterminateSystems/nix-src#103](https://github.com/DeterminateSystems/nix-src/pull/103)
+* Run nixpkgsLibTests against lazy trees by @edolstra in [DeterminateSystems/nix-src#100](https://github.com/DeterminateSystems/nix-src/pull/100)
+* Run the Nix test suite against lazy trees by @edolstra in [DeterminateSystems/nix-src#105](https://github.com/DeterminateSystems/nix-src/pull/105)
+* Improve caching of inputs by @edolstra in [DeterminateSystems/nix-src#98](https://github.com/DeterminateSystems/nix-src/pull/98), [DeterminateSystems/nix-src#110](https://github.com/DeterminateSystems/nix-src/pull/110), and [DeterminateSystems/nix-src#115](https://github.com/DeterminateSystems/nix-src/pull/115)
+
+**Full Changelog**: [v3.6.2...v3.6.5](https://github.com/DeterminateSystems/nix-src/compare/v3.6.2...v3.6.4)
diff --git a/doc/manual/source/release-notes-determinate/rl-3.6.6.md b/doc/manual/source/release-notes-determinate/rl-3.6.6.md
new file mode 100644
index 000000000000..bf4e3690afa1
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.6.6.md
@@ -0,0 +1,7 @@
+# Release 3.6.6 (2025-06-17)
+
+* Based on [upstream Nix 2.29.0](../release-notes/rl-2.29.md).
+
+## What's Changed
+
+* No-op release on the nix-src side, due to a regression on nix-darwin in determinate-nixd.
diff --git a/doc/manual/source/release-notes-determinate/rl-3.6.7.md b/doc/manual/source/release-notes-determinate/rl-3.6.7.md
new file mode 100644
index 000000000000..197587f1b3a9
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.6.7.md
@@ -0,0 +1,17 @@
+# Release 3.6.7 (2025-06-24)
+
+* Based on [upstream Nix 2.29.1](../release-notes/rl-2.29.md).
+
+## What's Changed
+
+### Security contents
+
+* Patched against GHSA-g948-229j-48j3
+
+### Lazy trees:
+
+* Lazy trees now produces `flake.lock` files with NAR hashes unless `lazy-locks` is set to `true` by @edolstra in [DeterminateSystems/nix-src#113](https://github.com/DeterminateSystems/nix-src/pull/113)
+* Improved caching with lazy-trees when using --impure, with enhanced testing by @edolstra in [DeterminateSystems/nix-src#117](https://github.com/DeterminateSystems/nix-src/pull/117)
+
+
+**Full Changelog**: [v3.6.6...v3.6.7](https://github.com/DeterminateSystems/nix-src/compare/v3.6.6...v3.6.7)
diff --git a/doc/manual/source/release-notes-determinate/rl-3.6.8.md b/doc/manual/source/release-notes-determinate/rl-3.6.8.md
new file mode 100644
index 000000000000..c4b4b96c9e73
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.6.8.md
@@ -0,0 +1,12 @@
+# Release 3.6.8 (2025-06-25)
+
+* Based on [upstream Nix 2.29.1](../release-notes/rl-2.29.md).
+
+## What's Changed
+* Fix fetchToStore() caching with --impure, improve testing by @edolstra in [DeterminateSystems/nix-src#117](https://github.com/DeterminateSystems/nix-src/pull/117)
+* Add lazy-locks setting by @edolstra in [DeterminateSystems/nix-src#113](https://github.com/DeterminateSystems/nix-src/pull/113)
+* Sync 2.29.1 by @edolstra in [DeterminateSystems/nix-src#124](https://github.com/DeterminateSystems/nix-src/pull/124)
+* Release v3.6.7 by @github-actions in [DeterminateSystems/nix-src#126](https://github.com/DeterminateSystems/nix-src/pull/126)
+
+
+**Full Changelog**: [v3.6.6...v3.6.8](https://github.com/DeterminateSystems/nix-src/compare/v3.6.6...v3.6.8)
diff --git a/doc/manual/source/release-notes-determinate/rl-3.7.0.md b/doc/manual/source/release-notes-determinate/rl-3.7.0.md
new file mode 100644
index 000000000000..615e858592e2
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.7.0.md
@@ -0,0 +1,63 @@
+# Release 3.7.0 (2025-07-03)
+
+- Based on [upstream Nix 2.29.1](../release-notes/rl-2.29.md).
+
+## What's Changed
+
+### Prefetch flake inputs in parallel
+
+By @edolstra in [DeterminateSystems/nix-src#127](https://github.com/DeterminateSystems/nix-src/pull/127)
+
+This release brings the command `nix flake prefetch-inputs`.
+
+Flake inputs are typically fetched "just in time."
+That means Nix fetches a flake input when the evaluator needs it, and not before.
+When the evaluator needs an input, evaluation is paused until the source is available.
+
+This causes a significant slow-down on projects with lots of flake inputs.
+
+The new command `nix flake prefetch-inputs` fetches all flake inputs in parallel.
+We expect running this new command before building will dramatically improve evaluation performance for most projects, especially in CI.
+Note that projects which with many unused flake inputs may not benefit from this change, since the new command fetches every input whether they're used or not.
+
+### Deep flake input overrides now work as expected
+
+By @edolstra in [DeterminateSystems/nix-src#108](https://github.com/DeterminateSystems/nix-src/pull/108)
+
+An override like:
+
+```
+inputs.foo.inputs.bar.inputs.nixpkgs.follows = "nixpkgs";
+```
+
+implicitly set `inputs.foo.inputs.bar` to `flake:bar`, which led to an unexpected error like:
+
+```
+error: cannot find flake 'flake:bar' in the flake registries
+```
+
+We now no longer create a parent override (like for `foo.bar` in the example above) if it doesn't set an explicit ref or follows attribute.
+We only recursively apply its child overrides.
+
+### `nix store delete` now shows you why deletion was not possible
+
+By @edolstra in [DeterminateSystems/nix-src#130](https://github.com/DeterminateSystems/nix-src/pull/130)
+
+For example:
+
+```
+error: Cannot delete path '/nix/store/6fcrjgfjip2ww3sx51rrmmghfsf60jvi-patchelf-0.14.3'
+ because it's referenced by the GC root '/home/eelco/Dev/nix-master/build/result'.
+
+error: Cannot delete path '/nix/store/lf3lrf8bjfn8xvr0az9q96y989sxs5r9-cowsay-3.8.4'
+ because it's referenced by the GC root '/proc/3600568/environ'.
+
+error: Cannot delete path '/nix/store/klyng5rpdkwi5kbxkncy4gjwb490dlhb-foo.drv'
+ because it's in use by '{nix-process:3605324}'.
+```
+
+### Lazy-tree improvements
+
+- Improved lazy-tree evaluation caching for flakes accessed with a `path` flakeref by @edolstra in [DeterminateSystems/nix-src#131](https://github.com/DeterminateSystems/nix-src/pull/131)
+
+**Full Changelog**: [v3.6.8...v3.7.0](https://github.com/DeterminateSystems/nix-src/compare/v3.6.8...v3.7.0)
diff --git a/doc/manual/source/release-notes-determinate/rl-3.8.0.md b/doc/manual/source/release-notes-determinate/rl-3.8.0.md
new file mode 100644
index 000000000000..4103d6df94e0
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.8.0.md
@@ -0,0 +1,29 @@
+# Release 3.8.0 (2025-07-10)
+
+* Based on [upstream Nix 2.30.0](../release-notes/rl-2.30.md).
+
+## What's Changed
+
+### Faster CI with `nix flake check`
+
+`nix flake check` no longer downloads flake outputs if no building is necessary.
+
+This command is intended to validate that a flake can fully evaluate and all outputs can build.
+If the outputs are available in a binary cache then both properties are confirmed to be true.
+Notably, downloading the output from the binary cache is not strictly necessary for the validation.
+
+Previously, `nix flake check` would download a flake output if the full build is available in a binary cache.
+
+Some users will find this change significantly reduces costly bandwidth and CI workflow time.
+
+PR: [DeterminateSystems/nix-src#134](https://github.com/DeterminateSystems/nix-src/pull/134)
+
+### Improved flake locking of transitive dependencies
+
+Determinate Nix now re-locks all transitive dependencies when changing a flake input's source URL.
+
+This fixes an issue where in some scenarios Nix would not re-lock those inputs and incorrectly use the old inputs' dependencies.
+
+PR: [DeterminateSystems/nix-src#137](https://github.com/DeterminateSystems/nix-src/pull/137)
+
+**Full Changelog**: [v3.7.0...v3.8.0](https://github.com/DeterminateSystems/nix-src/compare/v3.7.0...v3.8.0)
diff --git a/doc/manual/source/release-notes-determinate/rl-3.8.1.md b/doc/manual/source/release-notes-determinate/rl-3.8.1.md
new file mode 100644
index 000000000000..90dc328f6ec2
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.8.1.md
@@ -0,0 +1,9 @@
+# Release 3.8.1 (2025-07-11)
+
+* Based on [upstream Nix 2.30.0](../release-notes/rl-2.30.md).
+
+## What's Changed
+* Address ifdef problem with macOS/BSD sandboxing by @gustavderdrache in [DeterminateSystems/nix-src#142](https://github.com/DeterminateSystems/nix-src/pull/142)
+
+
+**Full Changelog**: [v3.8.0...v3.8.1](https://github.com/DeterminateSystems/nix-src/compare/v3.8.0...v3.8.1)
diff --git a/doc/manual/source/release-notes-determinate/rl-3.8.2.md b/doc/manual/source/release-notes-determinate/rl-3.8.2.md
new file mode 100644
index 000000000000..638d90f6841b
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.8.2.md
@@ -0,0 +1,10 @@
+# Release 3.8.2 (2025-07-12)
+
+* Based on [upstream Nix 2.30.0](../release-notes/rl-2.30.md).
+
+## What's Changed
+* ci: don't run the full test suite for x86_64-darwin by @grahamc in [DeterminateSystems/nix-src#144](https://github.com/DeterminateSystems/nix-src/pull/144)
+* Try publishing the manual again by @grahamc in [DeterminateSystems/nix-src#145](https://github.com/DeterminateSystems/nix-src/pull/145)
+
+
+**Full Changelog**: [v3.8.1...v3.8.2](https://github.com/DeterminateSystems/nix-src/compare/v3.8.1...v3.8.2)
diff --git a/doc/manual/source/release-notes-determinate/rl-3.8.3.md b/doc/manual/source/release-notes-determinate/rl-3.8.3.md
new file mode 100644
index 000000000000..d3eb02bc7ea5
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.8.3.md
@@ -0,0 +1,26 @@
+# Release 3.8.3 (2025-07-18)
+
+* Based on [upstream Nix 2.30.1](../release-notes/rl-2.30.md).
+
+## What's Changed
+
+### Non-blocking evaluation caching
+
+Users reported evaluation would occasionally block other evaluation processes.
+
+The evaluation cache database is now opened in write-ahead mode to prevent delaying evaluations.
+
+PR: [DeterminateSystems/nix-src#150](https://github.com/DeterminateSystems/nix-src/pull/150)
+
+### New experimental feature: `external-builders`
+
+This experimental feature allows Nix to call an external program for the build environment.
+
+The interface and behavior of this feature may change at any moment without a correspondingly major semver version change.
+
+PRs:
+- [DeterminateSystems/nix-src#141](https://github.com/DeterminateSystems/nix-src/pull/141)
+- [DeterminateSystems/nix-src#152](https://github.com/DeterminateSystems/nix-src/pull/152)
+- [DeterminateSystems/nix-src#78](https://github.com/DeterminateSystems/nix-src/pull/78)
+
+**Full Changelog**: [v3.8.2...v3.8.3](https://github.com/DeterminateSystems/nix-src/compare/v3.8.2...v3.8.3)
diff --git a/doc/manual/source/release-notes-determinate/rl-3.8.4.md b/doc/manual/source/release-notes-determinate/rl-3.8.4.md
new file mode 100644
index 000000000000..7c73e75ca023
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.8.4.md
@@ -0,0 +1,9 @@
+# Release 3.8.4 (2025-07-21)
+
+* Based on [upstream Nix 2.30.1](../release-notes/rl-2.30.md).
+
+## What's Changed
+* Revert "Use WAL mode for SQLite cache databases" by @grahamc in [DeterminateSystems/nix-src#155](https://github.com/DeterminateSystems/nix-src/pull/155)
+
+
+**Full Changelog**: [v3.8.3...v3.8.4](https://github.com/DeterminateSystems/nix-src/compare/v3.8.3...v3.8.4)
diff --git a/doc/manual/source/release-notes-determinate/rl-3.8.5.md b/doc/manual/source/release-notes-determinate/rl-3.8.5.md
new file mode 100644
index 000000000000..0f1bbe6f99d7
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/rl-3.8.5.md
@@ -0,0 +1,58 @@
+## What's Changed
+
+### Less time "unpacking into the Git cache"
+
+Unpacking sources into the user's cache is now takes 1/2 to 1/4 of the time it used to.
+Previously, Nix serially unpacked sources into the cache.
+This change takes better advantage of our users' hardware by parallelizing the import.
+Real life testing shows an initial Nixpkgs import takes 3.6s on Linux, when it used to take 11.7s.
+
+PR: [DeterminateSystems/nix-src#149](https://github.com/DeterminateSystems/nix-src/pull/149)
+
+### Copy paths to the daemon in parallel
+
+Determinate Nix's evaluator no longer blocks evaluation when copying paths to the store.
+Previously, Nix would pause evaluation when it needed to add files to the store.
+Now, the copying is performed in the background allowing evaluation to proceed.
+
+PR: [DeterminateSystems/nix-src#162](https://github.com/DeterminateSystems/nix-src/pull/162)
+
+### Faster Nix evaluation by reducing duplicate Nix daemon queries
+
+Determinate Nix more effectively caches store path validity data within a single evaluation.
+Previously, the Nix client would perform many thousands of exra Nix daemon requests.
+Each extra request takes real time, and this change reduced a sample evaluation by over 12,000 requests.
+
+PR: [DeterminateSystems/nix-src#157](https://github.com/DeterminateSystems/nix-src/pull/157)
+
+### More responsive tab completion
+
+Tab completion now implies the "--offline" flag, which disables most network requests.
+Previously, tab completing Nix arguments would attempt to fetch sources and access binary caches.
+Operating in offline mode improves the interactive experience of Nix when tab completing.
+
+PR: [DeterminateSystems/nix-src#161](https://github.com/DeterminateSystems/nix-src/pull/161)
+
+### ZFS users: we fixed the mysterious stall.
+
+Opening the Nix database is usually instantaneous but sometimes has a several second latency.
+Determinate Nix works around this issue, eliminating the frustrating random stall when running Nix commands.
+
+PR: [DeterminateSystems/nix-src#158](https://github.com/DeterminateSystems/nix-src/pull/158)
+
+### Other changes
+
+* Determinate Nix is now fully formatted by clang-format, making it easier than ever to contribute to the project.
+
+PR: [DeterminateSystems/nix-src#159](https://github.com/DeterminateSystems/nix-src/pull/159)
+
+* Determinate Nix is now based on upstream Nix 2.30.2.
+
+PR: [DeterminateSystems/nix-src#160](https://github.com/DeterminateSystems/nix-src/pull/160)
+
+* Determinate Nix now uses `main` as our development branch, moving away from `detsys-main`.
+
+PRs:
+* [DeterminateSystems/nix-src#164](https://github.com/DeterminateSystems/nix-src/pull/164)
+* [DeterminateSystems/nix-src#166](https://github.com/DeterminateSystems/nix-src/pull/166)
+
diff --git a/doc/manual/source/release-notes-determinate/v3.10.0.md b/doc/manual/source/release-notes-determinate/v3.10.0.md
new file mode 100644
index 000000000000..c644dd787446
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.10.0.md
@@ -0,0 +1,10 @@
+# Release 3.10.0 (2025-09-02)
+
+* Based on [upstream Nix 2.31.0](../release-notes/rl-2.31.md).
+
+## What's Changed
+
+This release rebases Determinate Nix on upstream Nix 2.31.0.
+
+
+**Full Changelog**: [v3.9.1...v3.10.0](https://github.com/DeterminateSystems/nix-src/compare/v3.9.1...v3.10.0)
diff --git a/doc/manual/source/release-notes-determinate/v3.10.1.md b/doc/manual/source/release-notes-determinate/v3.10.1.md
new file mode 100644
index 000000000000..08cbe4fd0583
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.10.1.md
@@ -0,0 +1,9 @@
+# Release 3.10.1 (2025-09-02)
+
+* Based on [upstream Nix 2.31.1](../release-notes/rl-2.31.md).
+
+## What's Changed
+This release rebases Determinate Nix on upstream Nix 2.31.1.
+
+
+**Full Changelog**: [v3.10.0...v3.10.1](https://github.com/DeterminateSystems/nix-src/compare/v3.10.0...v3.10.1)
diff --git a/doc/manual/source/release-notes-determinate/v3.11.0.md b/doc/manual/source/release-notes-determinate/v3.11.0.md
new file mode 100644
index 000000000000..7abb665a5a9f
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.11.0.md
@@ -0,0 +1,36 @@
+# Release 3.11.0 (2025-09-03)
+
+- Based on [upstream Nix 2.31.1](../release-notes/rl-2.31.md).
+
+## What's Changed
+
+### Parallel evaluation
+
+The following commands are now able to evaluate Nix expressions in parallel:
+
+- `nix search`
+- `nix flake check`
+- `nix flake show`
+- `nix eval --json`
+
+This is currently in developer preview, and we'll be turning it on for more users in the coming weeks.
+If you would like to try it right away, specify `eval-cores` in your `/etc/nix/nix.custom.conf`:
+
+```ini
+eval-cores = 0 # Evaluate across all cores
+```
+
+Further, we introduced a new builtin: `builtins.parallel`.
+This new builtin allows users to explicitly parallelize evaluation within a Nix expression.
+
+Using this new builtin requires turning on an additional experimental feature:
+
+```ini
+extra-experimental-features = parallel-eval
+```
+
+Please note that this new builtin is subject to change semantics or even go away during the developer preview.
+
+PR: [DeterminateSystems/nix-src#125](https://github.com/DeterminateSystems/nix-src/pull/125)
+
+**Full Changelog**: [v3.10.1...v3.11.0](https://github.com/DeterminateSystems/nix-src/compare/v3.10.1...v3.11.0)
diff --git a/doc/manual/source/release-notes-determinate/v3.11.1.md b/doc/manual/source/release-notes-determinate/v3.11.1.md
new file mode 100644
index 000000000000..305971643330
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.11.1.md
@@ -0,0 +1,9 @@
+# Release 3.11.1 (2025-09-04)
+
+* Based on [upstream Nix 2.31.1](../release-notes/rl-2.31.md).
+
+## What's Changed
+* Fix race condition in Value::isTrivial() by @edolstra in [DeterminateSystems/nix-src#192](https://github.com/DeterminateSystems/nix-src/pull/192)
+
+
+**Full Changelog**: [v3.11.0...v3.11.1](https://github.com/DeterminateSystems/nix-src/compare/v3.11.0...v3.11.1)
diff --git a/doc/manual/source/release-notes-determinate/v3.11.2.md b/doc/manual/source/release-notes-determinate/v3.11.2.md
new file mode 100644
index 000000000000..ac4fe569dffe
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.11.2.md
@@ -0,0 +1,24 @@
+# Release 3.11.2 (2025-09-12)
+
+* Based on [upstream Nix 2.31.1](../release-notes/rl-2.31.md).
+
+## What's Changed
+
+### Fix some interactions with the registry and flakes that include a `?dir=` parameter
+
+Some users were experiencing issues when their flake registry contained a flake that included a `?dir=` parameter, causing commands like `nix eval registry-with-flake-in-subdir#output` and those that used --inputs-from` to fail or behave incorrectly.
+
+This is now fixed, so use your flakes inside subdirs without fear!
+
+PRs: [DeterminateSystems/nix-src#196](https://github.com/DeterminateSystems/nix-src/pull/196), [DeterminateSystems/nix-src#199](https://github.com/DeterminateSystems/nix-src/pull/199)
+
+### Only substitute inputs if they haven't already been fetched
+
+When using `lazy-trees`, you might have noticed Nix fetching some source inputs from a cache, even though you could have sworn it already fetched those inputs!
+
+This fixes that behavior such that Nix will try to fetch inputs from their original location, and only if that fails fall back to fetching from a substituter.
+
+PR: [DeterminateSystems/nix-src#202](https://github.com/DeterminateSystems/nix-src/pull/202)
+
+
+**Full Changelog**: [v3.11.1...v3.11.2](https://github.com/DeterminateSystems/nix-src/compare/v3.11.1...v3.11.2)
diff --git a/doc/manual/source/release-notes-determinate/v3.11.3.md b/doc/manual/source/release-notes-determinate/v3.11.3.md
new file mode 100644
index 000000000000..fab5ed51a4b5
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.11.3.md
@@ -0,0 +1,34 @@
+# Release 3.11.3 (2025-10-09)
+
+* Based on [upstream Nix 2.31.2](../release-notes/rl-2.31.md).
+
+## What's Changed
+
+### Fix some bugs and interactions with parallel eval
+
+We received some reports of parallel eval having issues, such as not being able to be interrupted, infinite recursion hanging forever, and segfaults when using the experimental `builtins.parallel`.
+
+Those have now been fixed.
+
+Additionally, the debugger now disables parallel eval, because the two features are incompatible.
+
+PRs: [DeterminateSystems/nix-src#206](https://github.com/DeterminateSystems/nix-src/pull/206), [DeterminateSystems/nix-src#213](https://github.com/DeterminateSystems/nix-src/pull/213), [DeterminateSystems/nix-src#218](https://github.com/DeterminateSystems/nix-src/pull/218), [DeterminateSystems/nix-src#205](https://github.com/DeterminateSystems/nix-src/pull/205)
+
+### `NIX_SSHOPTS` + `ssh-ng://root@localhost` fix
+
+We noticed that specifying `NIX_SSHOPTS=-p2222` when using a command that uses SSH (such as `nix copy --to ssh-ng://root@localhost`) stopped respecting the `NIX_SSHOPTS` setting because of an incorrect comparison.
+
+This has been fixed, so `NIX_SSHOPTS` and SSH stores that are accessed like `user@localhost` work again.
+
+PR: [DeterminateSystems/nix-src#219](https://github.com/DeterminateSystems/nix-src/pull/219)
+
+### Fix `error: [json.exception.type_error.302] type must be string, but is array` when using `exportReferencesGraph`
+
+We received a report of a `nix build` failing on a specific flake due to its expression using `exportReferencesGraph` with a heterogeneous array of dependencies, causing this inscrutable error.
+
+This specific case has been broken since Nix 2.29.0, and is now fixed.
+
+PRs: [DeterminateSystems/nix-src#221](https://github.com/DeterminateSystems/nix-src/pull/221), [DeterminateSystems/nix-src#225](https://github.com/DeterminateSystems/nix-src/pull/225)
+
+
+**Full Changelog**: [v3.11.2...v3.11.3](https://github.com/DeterminateSystems/nix-src/compare/v3.11.2...v3.11.3)
diff --git a/doc/manual/source/release-notes-determinate/v3.12.0.md b/doc/manual/source/release-notes-determinate/v3.12.0.md
new file mode 100644
index 000000000000..55c1f10bf15f
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.12.0.md
@@ -0,0 +1,17 @@
+# Release 3.12.0 (2025-10-23)
+
+* Based on [upstream Nix 2.32.1](../release-notes/rl-2.32.md).
+
+## What's Changed
+
+### `nix nario`
+
+Determinate Nix has a new command, `nix nario`, that replaces the commands `nix-store --export` and `nix-store --import` from the old CLI. `nix nario` allows you to serialize store paths to a file that can be imported into another Nix store. It is backwards compatible with the file format generated by `nix-store --export`. It also provides a new format (selected by passing `--format 2`) that supports store path attributes such as signatures, and allows store paths to be imported more efficiently.
+
+### Other changes
+
+`nix flake clone` now supports arbitrary input types. In particular, this allows you to clone tarball flakes, such as flakes on FlakeHub.
+
+When using `-vv`, Determinate Nix now prints the Nix version. This is useful when diagnosing Nix problems from the debug output of a Nix run.
+
+**Full Changelog**: [v3.11.3...v3.12.0](https://github.com/DeterminateSystems/nix-src/compare/v3.11.3...v3.12.0)
diff --git a/doc/manual/source/release-notes-determinate/v3.12.1.md b/doc/manual/source/release-notes-determinate/v3.12.1.md
new file mode 100644
index 000000000000..1be2b48e26d8
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.12.1.md
@@ -0,0 +1,10 @@
+# Release 3.12.1 (2025-11-04)
+
+* Based on [upstream Nix 2.32.1](../release-notes/rl-2.32.md).
+
+## What's Changed
+* Allow access to the result of fetchClosure by @edolstra in [DeterminateSystems/nix-src#241](https://github.com/DeterminateSystems/nix-src/pull/241)
+* libstore/build: fixup JSON logger missing the resBuildResult result event by @cole-h in [DeterminateSystems/nix-src#246](https://github.com/DeterminateSystems/nix-src/pull/246)
+
+
+**Full Changelog**: [v3.12.0...v3.12.1](https://github.com/DeterminateSystems/nix-src/compare/v3.12.0...v3.12.1)
diff --git a/doc/manual/source/release-notes-determinate/v3.12.2.md b/doc/manual/source/release-notes-determinate/v3.12.2.md
new file mode 100644
index 000000000000..4c8c3169aa72
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.12.2.md
@@ -0,0 +1,42 @@
+# Release 3.12.2 (2025-11-05)
+
+* Based on [upstream Nix 2.32.2](../release-notes/rl-2.32.md).
+
+## What's Changed
+
+### Faster `revCount` computation
+
+When using Git repositories with a long history, calculating the `revCount` attribute can take a long time. Determinate Nix now computes `revCount` using multiple threads, making it much faster.
+
+Note that if you don't need `revCount`, you can disable it altogether by setting the flake input attribute `shallow = true`.
+
+PR: [DeterminateSystems/nix-src#245](https://github.com/DeterminateSystems/nix-src/pull/245)
+
+### More readable error messages
+
+Previously, Nix showed full flakerefs in error messages such as stack traces, e.g.
+```
+ … from call site
+ at «github:NixOS/nixpkgs/3bea86e918d8b54aa49780505d2d4cd9261413be?narHash=sha256-Ica%2B%2BSXFuLyxX9Q7YxhfZulUif6/gwM8AEQYlUxqSgE%3D»/lib/customisation.nix:69:16:
+ 68| let
+ 69| result = f origArgs;
+ | ^
+ 70|
+```
+It now abbreviates these by leaving out `narHash` and shortening Git revisions:
+```
+ … from call site
+ at «github:NixOS/nixpkgs/3bea86e»/lib/customisation.nix:69:16:
+ 68| let
+ 69| result = f origArgs;
+ | ^
+ 70|
+```
+
+PR: [DeterminateSystems/nix-src#243](https://github.com/DeterminateSystems/nix-src/pull/243)
+
+### Other changes
+
+This release fixes an assertion failure in `nix flake check`. PR: [DeterminateSystems/nix-src#252](https://github.com/DeterminateSystems/nix-src/pull/252)
+
+**Full Changelog**: [v3.12.1...v3.12.2](https://github.com/DeterminateSystems/nix-src/compare/v3.12.1...v3.12.2)
diff --git a/doc/manual/source/release-notes-determinate/v3.13.0.md b/doc/manual/source/release-notes-determinate/v3.13.0.md
new file mode 100644
index 000000000000..09041c2acda0
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.13.0.md
@@ -0,0 +1,45 @@
+# Release 3.13.0 (2025-11-09)
+
+* Based on [upstream Nix 2.32.3](../release-notes/rl-2.32.md).
+
+## What's Changed
+
+
+### Git sources have a progress indicator again
+
+Nix used to feel "stuck" while it was cloning large repositories.
+Determinate Nix now shows git's native progress indicator while fetching.
+
+PR: [DeterminateSystems/nix-src#250](https://github.com/DeterminateSystems/nix-src/pull/250)
+
+### C API improvements
+
+We've invested in the C API to support our work on closure analysis for SBOM generation, and made a couple of changes:
+
+* C API: add nix_locked_flake_read_path for flake file reading
+* C API: make nix_store_get_fs_closure compatible with upstream
+
+PRs:
+* [DeterminateSystems/nix-src#244](https://github.com/DeterminateSystems/nix-src/pull/244)
+* [DeterminateSystems/nix-src#254](https://github.com/DeterminateSystems/nix-src/pull/254)
+
+### Dropping support for Intel Macs
+
+Determinate Nix no longer supports being installed on Intel Macs.
+Determinate Nix will continue to support building for Intel macOS targets, but only from an Apple Silicon host.
+
+From our intent-to-ship:
+> Over the past year, we’ve watched usage of Determinate on Intel macOS hosts dwindle to a minuscule fraction of total usage.
+> It currently stands at approximately 0.02% of all installations.
+> The vast majority are run in managed CI environments that, we anticipate, will be able to easily convert to using Apple Silicon runners.
+
+For more information: https://github.com/DeterminateSystems/nix-src/issues/224
+
+PR: [DeterminateSystems/nix-src#257](https://github.com/DeterminateSystems/nix-src/pull/257)
+
+### Bugs fixed
+
+* IPv6 Store URLs now handles zone ID references like it did in previous releases [NixOS/nix#14434](https://github.com/NixOS/nix/pull/14434)
+
+
+**Full Changelog**: [v3.12.2...v3.13.0](https://github.com/DeterminateSystems/nix-src/compare/v3.12.2...v3.13.0)
diff --git a/doc/manual/source/release-notes-determinate/v3.13.1.md b/doc/manual/source/release-notes-determinate/v3.13.1.md
new file mode 100644
index 000000000000..025a192c44ee
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.13.1.md
@@ -0,0 +1,10 @@
+# Release 3.13.1 (2025-11-12)
+
+* Based on [upstream Nix 2.32.4](../release-notes/rl-2.32.md).
+
+## What's Changed
+* nix bundle: Wait for async path writer by @edolstra in [DeterminateSystems/nix-src#260](https://github.com/DeterminateSystems/nix-src/pull/260)
+* Sync with upstream 2.32.4 by @edolstra in [DeterminateSystems/nix-src#261](https://github.com/DeterminateSystems/nix-src/pull/261)
+
+
+**Full Changelog**: [v3.13.0...v3.13.1](https://github.com/DeterminateSystems/nix-src/compare/v3.13.0...v3.13.1)
diff --git a/doc/manual/source/release-notes-determinate/v3.13.2.md b/doc/manual/source/release-notes-determinate/v3.13.2.md
new file mode 100644
index 000000000000..2490b865e6bc
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.13.2.md
@@ -0,0 +1,68 @@
+# Release 3.13.2 (2025-11-19)
+
+* Based on [upstream Nix 2.32.4](../release-notes/rl-2.32.md).
+
+## What's Changed
+
+### Abbreviate flakerefs in lockfile diffs and `nix flake metadata`
+
+Flake refs are now abbreviated when possible, to reduce visual clutter.
+
+For example, this changes
+
+```
+• Updated input 'blender-bin':
+ 'https://api.flakehub.com/f/pinned/edolstra/blender-bin/1.0.19/01993ca7-2aa8-746f-96f5-ca8d2c2b962d/source.tar.gz?narHash=sha256-ZqVhVl9UYVErF8HW8lcvqss005VWYjuX//rZ%2BOmXyHg%3D' (2025-09-12)
+ → 'https://api.flakehub.com/f/pinned/edolstra/blender-bin/1.0.20/019a8772-b044-7738-8c03-109bdc9f0a01/source.tar.gz?narHash=sha256-sVj9Gmx0kwTDQPJ5kgQYszE3Hdjevu0zx0b/bL2fyUc%3D' (2025-11-15)
+• Updated input 'nix':
+ 'github:DeterminateSystems/nix-src/236ebef6514f3a2a9765c8a1d80dd503b8e672be?narHash=sha256-s6/Err0yqOp5fM3OdCF1vhmEYpeElbPOWX88YrW2qj4%3D' (2025-10-23)
+ → 'github:DeterminateSystems/nix-src/ef054dc06e9701597bce0b0572af18cb4c7e7277?narHash=sha256-uqYmH0KA8caQqX5u4BMarZsuDlC%2B71HRsH3h4f3DPCA%3D' (2025-11-12)
+```
+
+to
+
+```
+• Updated input 'blender-bin':
+ 'https://api.flakehub.com/f/pinned/edolstra/blender-bin/1.0.19/01993ca7-2aa8-746f-96f5-ca8d2c2b962d/source.tar.gz' (2025-09-12)
+ → 'https://api.flakehub.com/f/pinned/edolstra/blender-bin/1.0.20/019a8772-b044-7738-8c03-109bdc9f0a01/source.tar.gz' (2025-11-15)
+• Updated input 'nix':
+ 'github:DeterminateSystems/nix-src/236ebef' (2025-10-23)
+ → 'github:DeterminateSystems/nix-src/ef054dc' (2025-11-12)
+```
+
+PR: [DeterminateSystems/nix-src#264](https://github.com/DeterminateSystems/nix-src/pull/264)
+
+### `nix flake prefetch-inputs` now skips build-time inputs
+
+Build-time inputs can already be fetched in parallel, so prefetching them is usually not what you want.
+
+This can be especially noticeable in projects that make extensive use of build-time flake inputs.
+
+PR: [DeterminateSystems/nix-src#263](https://github.com/DeterminateSystems/nix-src/pull/263)
+
+### Don't compute `revCount`/`lastModified` if they're already specified
+
+We don't care if the user (or more likely the lock file) specifies an incorrect value for these attributes, since it doesn't matter for security (unlike content hashes like `narHash`).
+
+This can save time when operating on large repos -- having to recalculate these attributes could slow things down greatly.
+
+PR: [DeterminateSystems/nix-src#269](https://github.com/DeterminateSystems/nix-src/pull/269)
+
+### Avoid unnecessary Git refetches
+
+This fixes the issue where updating a Git input does a non-shallow fetch, and then a subsequent eval does a shallow refetch because the `revCount` is already known.
+
+Now the subsequent eval will reuse the repo used in the first fetch.
+
+PR: [DeterminateSystems/nix-src#270](https://github.com/DeterminateSystems/nix-src/pull/270)
+
+### Use our mirrored flake registry
+
+The flake registry is security-critical and thus should have high availability.
+
+By mirroring the upstream Nix flake registry, we can make it less likely that a GitHub outage affects being able to resolve from the registry.
+
+PR: [DeterminateSystems/nix-src#271](https://github.com/DeterminateSystems/nix-src/pull/271)
+
+
+**Full Changelog**: [v3.13.1...v3.13.2](https://github.com/DeterminateSystems/nix-src/compare/v3.13.1...v3.13.2)
diff --git a/doc/manual/source/release-notes-determinate/v3.14.0.md b/doc/manual/source/release-notes-determinate/v3.14.0.md
new file mode 100644
index 000000000000..d72d5d21468c
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.14.0.md
@@ -0,0 +1,159 @@
+# Release 3.14.0 (2025-12-08)
+
+* Based on [upstream Nix 2.32.4](../release-notes/rl-2.32.md).
+
+## What is going on?! `nix ps` to the rescue
+
+Determinate Nix now features a `nix ps` command to summarize all of the active builds and child processes:
+
+```
+$ nix ps
+USER PID CPU DERIVATION/COMMAND
+_nixbld1 30167 0.4s /nix/store/h431bcfml83czhpyzljhp9mw4yrq95vs-determinate-nix-manual-3.14.0.drv (wall=9s)
+_nixbld1 30167 0.2s └───bash -e /nix/store/jwqf79v5p51x9mv8vx20fv9mzm2x7kig-source-stdenv.sh /nix/store/285whzixr5k1kfj6nidyj29mqqgv7n0b-default-builder.s
+_nixbld1 30278 0.0s └───ninja -j14
+_nixbld1 30279 0.0s ├───/nix/store/p7rag2cw99d7alp6749rjqp71qc0mnzl-python3-3.12.11/bin/python3.12 /nix/store/8k5fancbc5fjmxq6izn0z4inwnmpj09y-mes
+_nixbld1 30286 0.0s │ └───/nix/store/z59zm01pjwzil2qkvv0s4ibk54risy9a-determinate-nix-3.14.0/bin/nix config show --json
+_nixbld1 30280 0.0s ├───/nix/store/p7rag2cw99d7alp6749rjqp71qc0mnzl-python3-3.12.11/bin/python3.12 /nix/store/8k5fancbc5fjmxq6izn0z4inwnmpj09y-mes
+_nixbld1 30287 0.0s │ └───/nix/store/z59zm01pjwzil2qkvv0s4ibk54risy9a-determinate-nix-3.14.0/bin/nix __dump-language
+_nixbld1 30281 0.0s ├───/nix/store/p7rag2cw99d7alp6749rjqp71qc0mnzl-python3-3.12.11/bin/python3.12 /nix/store/8k5fancbc5fjmxq6izn0z4inwnmpj09y-mes
+_nixbld1 30288 0.0s │ └───/nix/store/z59zm01pjwzil2qkvv0s4ibk54risy9a-determinate-nix-3.14.0/bin/nix __dump-cli
+_nixbld1 30282 0.0s ├───/nix/store/p7rag2cw99d7alp6749rjqp71qc0mnzl-python3-3.12.11/bin/python3.12 /nix/store/8k5fancbc5fjmxq6izn0z4inwnmpj09y-mes
+_nixbld1 30284 0.0s │ └───/nix/store/z59zm01pjwzil2qkvv0s4ibk54risy9a-determinate-nix-3.14.0/bin/nix __dump-xp-features
+_nixbld1 30283 0.0s └───/nix/store/p7rag2cw99d7alp6749rjqp71qc0mnzl-python3-3.12.11/bin/python3.12 /nix/store/8k5fancbc5fjmxq6izn0z4inwnmpj09y-mes
+_nixbld1 30285 0.0s └───/nix/store/bs1pvy8margy5sj0jwahchxbjnqzi14i-bash-5.2p37/bin/bash -euo pipefail -c if type -p build-release-notes > /de
+_nixbld1 30289 0.0s └───changelog-d ../source/release-notes/../../rl-next
+```
+
+For the integrators out there, it also has a `--json` flag with all the raw data.
+
+PRs:
+* [DeterminateSystems/nix-src#282](https://github.com/DeterminateSystems/nix-src/pull/282)
+* [DeterminateSystems/nix-src#287](https://github.com/DeterminateSystems/nix-src/pull/287)
+
+
+## Nix `build`, `profile`, and `flake check` commands tell you what output failed
+
+These commands now tell you exactly what flake outputs failed to build.
+Previously, the error would indicate only what derivation failed to build -- but not which output.
+
+Now, `nix build` and `nix profile` commands provide the specific output:
+
+```
+$ nix build .#oneFakeHash .#badSystem --keep-going
+❌ git+file:///Users/grahamc/src/github.com/DeterminateSystems/samples#oneFakeHash
+error: hash mismatch in fixed-output derivation '/nix/store/58pp1y74j4f5zxfq50xncv2wvnxf7w3y-one-fake-hash.drv':
+ specified: sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+ got: sha256-i7j83d71sibS/ssSjLJ5PMKmbhjAM+BHW0aElvkgEwY=
+❌ git+file:///Users/grahamc/src/github.com/DeterminateSystems/samples#badSystem
+error: Cannot build '/nix/store/5vsaxi730yl2icngkyvn8wiflik5wfmq-bad-system.drv'.
+ Reason: required system or feature not available
+ Required system: 'bogus' with features {}
+ Current system: 'aarch64-darwin' with features {apple-virt, benchmark, big-parallel, nixos-test}
+```
+
+And in a great change for CI, `nix flake check` users get improved summaries too:
+
+```
+$ nix flake check
+❓ checks.aarch64-darwin.twoFakeHashes (cancelled)
+❓ checks.aarch64-darwin.badSystemNested (cancelled)
+❓ checks.aarch64-darwin.oneFakeHash (cancelled)
+❓ checks.aarch64-darwin.failure (cancelled)
+❓ checks.aarch64-darwin.badSystem (cancelled)
+❓ checks.aarch64-darwin.weirdHash (cancelled)
+❓ checks.aarch64-darwin.all (cancelled)
+❓ checks.aarch64-darwin.fakeHashes (cancelled)
+❓ checks.aarch64-darwin.incorrectHashes (cancelled)
+❓ checks.aarch64-darwin.badFeaturesNested (cancelled)
+❓ checks.aarch64-darwin.failureNested (cancelled)
+❌ checks.aarch64-darwin.badFeatures
+error: Cannot build '/nix/store/sc1cyhrpsm9yjx55cl2zzyr5lypwigi6-bad-feature.drv'.
+ Reason: required system or feature not available
+ Required system: 'aarch64-darwin' with features {bogus}
+ Current system: 'aarch64-darwin' with features {apple-virt, benchmark, big-parallel, nixos-test}
+```
+
+PRs:
+* [DeterminateSystems/nix-src#281](https://github.com/DeterminateSystems/nix-src/pull/281)
+* [DeterminateSystems/nix-src#285](https://github.com/DeterminateSystems/nix-src/pull/285)
+
+
+## More seamless upgrades from Nix 2.18 and Nix 2.19
+
+We've heard from some users who are trying to upgrade from Nix 2.18.
+
+These users are primarily experiencing problems caused by Nix 2.20 switching from `git-archive` to `libgit2` for fetching repositories.
+This change caused some `git-archive` filters to stop executing, like autocrlf.
+Not running those filters is an improvement, and running those filters *can cause* instability in source hashes.
+However, this switch *did* cause previously valid hashes to become invalid.
+
+Determinate Nix now retries fetching an old archive with `git-archive` as a fallback when libgit2 fails to provide the correct source.
+
+Further, to support a progressive migration Determinate Nix has a new option: `nix-219-compat`.
+Set `nix-219-compat=true` to cause Nix to author new flake.nix files with a `git-archive` based source hash.
+
+Finally, a user identified `builtins.path` changed since 2.18 and stopped propagating references.
+We have corrected this regression.
+
+PRs:
+* [DeterminateSystems/nix-src#283](https://github.com/DeterminateSystems/nix-src/pull/283)
+* [DeterminateSystems/nix-src#278](https://github.com/DeterminateSystems/nix-src/pull/278)
+
+## Flake registry mirroring
+
+Determinate Nix now includes a fallback copy of the Nix Registry.
+This change builds on top of v3.13.2, where we changed from the upstream Nix registry to a mirrored copy hosted by `install.determinate.systems`.
+
+Combined, these changes increase the reliability of Nix in the face of network outages.
+
+> [!NOTE]
+> Flake registry URLs for `flake.nix` inputs is deprecated.
+> The flake registry should only be used for interactive use.
+> See: https://github.com/DeterminateSystems/nix-src/issues/37
+
+PR: [DeterminateSystems/nix-src#273](https://github.com/DeterminateSystems/nix-src/pull/273)
+
+## Flake registry resolution CLI
+
+We added the new command `nix registry resolve` to help debug issues with Flake registries.
+This command looks up a flake registry input name and returns the flakeref it resolves to.
+
+For example, looking up Nixpkgs:
+
+```
+$ nix registry resolve nixpkgs
+github:NixOS/nixpkgs/nixpkgs-unstable
+```
+
+Or looking up the 25.11 branch of Nixpkgs:
+```
+$ nix registry resolve nixpkgs/release-25.11
+github:NixOS/nixpkgs/release-25.11
+```
+
+> [!NOTE]
+> Flake registry URLs for `flake.nix` inputs is deprecated.
+> The flake registry should only be used for interactive use.
+> See: https://github.com/DeterminateSystems/nix-src/issues/37
+
+PR: [DeterminateSystems/nix-src#273](https://github.com/DeterminateSystems/nix-src/pull/273)
+
+## Improved Docker image packaging
+
+Thanks to `employee-64c7dcd530593118dcccc3fb`, the OCI / Docker images built by the Determinate Nix flake.nix can be further customized.
+
+Users can specify their own base image by specifying `fromImage`.
+
+Additionally, users can specify additional directories to include at the beginning or end of the PATH variable with `extraPrePaths` and `extraPostPaths`.
+
+PRs:
+* [DeterminateSystems/nix-src#277](https://github.com/DeterminateSystems/nix-src/pull/277)
+* [DeterminateSystems/nix-src#280](https://github.com/DeterminateSystems/nix-src/pull/280)
+
+## Bug fixes
+
+* Corrected an error with parallel evaluation which ([DeterminateSystems/nix-src#286](https://github.com/DeterminateSystems/nix-src/pull/286))
+* Fixed compatibility with updated Nixpkgs versions. Thank you SandaruKasa! ([DeterminateSystems/nix-src#284](https://github.com/DeterminateSystems/nix-src/pull/284))
+
+**Full Changelog**: [v3.13.2...v3.14.0](https://github.com/DeterminateSystems/nix-src/compare/v3.13.2...v3.14.0)
diff --git a/doc/manual/source/release-notes-determinate/v3.15.0.md b/doc/manual/source/release-notes-determinate/v3.15.0.md
new file mode 100644
index 000000000000..fb568374c3f2
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.15.0.md
@@ -0,0 +1,28 @@
+# Release 3.15.0 (2025-12-19)
+
+* Based on [upstream Nix 2.33.0](../release-notes/rl-2.33.md).
+
+## `fetchTree` improvement
+
+`builtins.fetchTree` now implicitly treats the fetched tree as "final" when a `narHash` is supplied, meaning that it will not return attributes like `lastModified` or `revCount` unless they were specified by the caller. This makes it possible to substitute the tree from a binary cache, which is often more efficient. Furthermore, for Git inputs, it allows Nix to perform a shallow fetch, which is much faster.
+
+This is primarily useful for users of `flake-compat`, since it uses `builtins.fetchTree` internally.
+
+PR: [DeterminateSystems/nix-src#297](https://github.com/DeterminateSystems/nix-src/pull/297)
+
+## New builtin function `builtins.filterAttrs`
+
+Nixpkgs heavily relies on this function to select attributes from an attribute set:
+
+```nix
+filterAttrs = pred: set: removeAttrs set (filter (name: !pred name set.${name}) (attrNames set));
+```
+
+Determinate Nix now has this function built-in, which makes it much faster.
+
+PR: [DeterminateSystems/nix-src#291](https://github.com/DeterminateSystems/nix-src/pull/291)
+
+## New Contributors
+* @not-ronjinger made their first contribution in [DeterminateSystems/nix-src#291](https://github.com/DeterminateSystems/nix-src/pull/291)
+
+**Full Changelog**: [v3.14.0...v3.15.0](https://github.com/DeterminateSystems/nix-src/compare/v3.14.0...v3.15.0)
diff --git a/doc/manual/source/release-notes-determinate/v3.15.1.md b/doc/manual/source/release-notes-determinate/v3.15.1.md
new file mode 100644
index 000000000000..9243962cf4b5
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.15.1.md
@@ -0,0 +1,15 @@
+# Release 3.15.1 (2025-12-24)
+
+* Based on [upstream Nix 2.33.0](../release-notes/rl-2.33.md).
+
+## What's Changed
+Users reported the v3.15.0 tarball could not be fetched in a fixed-output derivation due to current stdenv paths present in the documentation. This release eliminated those paths.
+
+PR: [DeterminateSystems/nix-src#306](https://github.com/DeterminateSystems/nix-src/pull/306)
+
+Additionally, this change re-enables CodeRabbit's code review on our changes. CodeRabit was disabled by the upstream project, and we inadvertently included that change.
+
+PR: [DeterminateSystems/nix-src#305](https://github.com/DeterminateSystems/nix-src/pull/305)
+
+
+**Full Changelog**: [v3.15.0...v3.15.1](https://github.com/DeterminateSystems/nix-src/compare/v3.15.0...v3.15.1)
diff --git a/doc/manual/source/release-notes-determinate/v3.15.2.md b/doc/manual/source/release-notes-determinate/v3.15.2.md
new file mode 100644
index 000000000000..c5e5339990b5
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.15.2.md
@@ -0,0 +1,44 @@
+# Release 3.15.2 (2026-01-20)
+
+* Based on [upstream Nix 2.33.1](../release-notes/rl-2.33.md).
+
+## What's Changed
+
+### Improved performance for users with a lot of dependencies
+
+If you even had the occasion to query your binary cache for over 110,000 store path simultaneously you might have found it rather slow.
+Previously, Nix would enqueue all the downloads at once.
+This appears to trigger quadratic behavior in curl.
+
+Determinate Nix now enqueues a reasonable number of subtitutions once.
+At the same time, we fixed a performance issue in the progress bar with so many dependencies.
+
+PR: [DeterminateSystems/nix-src#315](https://github.com/DeterminateSystems/nix-src/pull/315)
+
+### Lazy trees update: path inputs are now lazy
+
+Previously inputs like `path:///path/to/a/dependency` were eagerly fetched when lazy-trees is enabled.
+In Determinate Nix 3.15.2, path input types are also fetched lazily.
+This change saves time and improves performance for users with path inputs.
+
+PRs:
+* [DeterminateSystems/nix-src#312](https://github.com/DeterminateSystems/nix-src/pull/312)
+* [DeterminateSystems/nix-src#317](https://github.com/DeterminateSystems/nix-src/pull/317)
+
+### `nix repl` now reports the Determinate version
+
+A small change, but now `nix repl` correctly reports the Determinate Nix version:
+
+```
+$ nix repl
+Nix (Determinate Nix 3.15.1) 2.33.0
+Type :? for help.
+nix-repl>
+```
+
+PR: [DeterminateSystems/nix-src#316](https://github.com/DeterminateSystems/nix-src/pull/316)
+
+## New Contributors
+* @dliberalesso made their first contribution in [DeterminateSystems/nix-src#313](https://github.com/DeterminateSystems/nix-src/pull/313)
+
+**Full Changelog**: [v3.15.1...v3.15.2](https://github.com/DeterminateSystems/nix-src/compare/v3.15.1...v3.15.2)
diff --git a/doc/manual/source/release-notes-determinate/v3.16.0.md b/doc/manual/source/release-notes-determinate/v3.16.0.md
new file mode 100644
index 000000000000..8e80ac68402a
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.16.0.md
@@ -0,0 +1,53 @@
+# Release 3.16.0 (2026-02-12)
+
+* Based on [upstream Nix 2.33.3](../release-notes/rl-2.33.md).
+
+## Support `.gitattributes` in subdirectories
+
+For performance, the Git backwards compatibility hack was only applied to repositories that had a `.gitattributes` in the root directory.
+However, it is possible to have a `.gitattributes` file in a subdirectory, and there are real-world repos that do this, so we have dropped that restriction.
+
+PR: [DeterminateSystems/nix-src#335](https://github.com/DeterminateSystems/nix-src/pull/335)
+
+## Fix hung downloads when `http-connections = 0`
+
+When we started limiting the number of active cURL handles in [DeterminateSystems/nix-src#315](https://github.com/DeterminateSystems/nix-src/pull/315), we did not take into account that `http-connections = 0` is a special value that means, roughly "as many connections as possible" (the exact behavior is up to cURL).
+
+This should now be fixed.
+
+PR: [DeterminateSystems/nix-src#327](https://github.com/DeterminateSystems/nix-src/pull/327)
+
+## `builtins.getFlake` now supports relative paths
+
+`builtins.getFlake` now supports using relative paths, like:
+
+```nix
+builtins.getFlake ./..
+```
+
+instead of the hacky
+
+```nix
+builtins.getFlake (builtins.flakeRefToString { type = "path"; path = self.sourceInfo.outPath; narHash = self.narHash; });
+```
+
+Note that allowing `builtins.getFlake` to fetch from store paths is probably a bad idea, since it's ambiguous when using chroot stores, so a warning will be printed when this is encountered.
+
+PRs:
+* [DeterminateSystems/nix-src#337](https://github.com/DeterminateSystems/nix-src/pull/337)
+* [DeterminateSystems/nix-src#338](https://github.com/DeterminateSystems/nix-src/pull/338)
+
+## Fixed a bug with too many open files
+
+Recently, some users have reported seeing errors like:
+
+```
+error: creating git packfile indexer: failed to create temporary file '/Users/anon/.cache/nix/tarball-cache-v2/objects/pack/pack_git2_56d617039ac17c2b': Too many open files
+```
+
+This should now be fixed.
+
+PR: [DeterminateSystems/nix-src#347](https://github.com/DeterminateSystems/nix-src/pull/347)
+
+
+**Full Changelog**: [v3.15.2...v3.16.0](https://github.com/DeterminateSystems/nix-src/compare/v3.15.2...v3.16.0)
diff --git a/doc/manual/source/release-notes-determinate/v3.16.1.md b/doc/manual/source/release-notes-determinate/v3.16.1.md
new file mode 100644
index 000000000000..6ecd5262b7c9
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.16.1.md
@@ -0,0 +1,24 @@
+# Release 3.16.1 (2026-02-22)
+
+* Based on [upstream Nix 2.33.3](../release-notes/rl-2.33.md).
+
+## What's Changed
+
+### `nix store info` now correctly support `--refresh` and `--offline`
+
+Previously, Nix had a hard-coded TTL of seven days.
+Determinate Nix moved that TTL to a new setting `narinfo-cache-meta-ttl` and now `nix store info` respects the `--refresh` and `--offline` flags.
+
+This change makes it possible to freshly validate authenticating to a remote store.
+
+PR: [DeterminateSystems/nix-src#355](https://github.com/DeterminateSystems/nix-src/pull/355)
+
+### Corrected `builtins.hashString` behavior under lazy trees
+
+`builtins.hashString` now devirtualizes lazy paths, making the hash result stable.
+
+PR: [DeterminateSystems/nix-src#360](https://github.com/DeterminateSystems/nix-src/pull/360)
+
+
+
+**Full Changelog**: [v3.16.0...v3.16.1](https://github.com/DeterminateSystems/nix-src/compare/v3.16.0...v3.16.1)
diff --git a/doc/manual/source/release-notes-determinate/v3.16.2.md b/doc/manual/source/release-notes-determinate/v3.16.2.md
new file mode 100644
index 000000000000..73a1b25f21c8
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.16.2.md
@@ -0,0 +1,8 @@
+# Release 3.16.2 (2026-02-23)
+
+* Based on [upstream Nix 2.33.3](../release-notes/rl-2.33.md).
+
+## What's Changed
+This release is exclusively improvements to `determinate-nixd`.
+
+
diff --git a/doc/manual/source/release-notes-determinate/v3.16.3.md b/doc/manual/source/release-notes-determinate/v3.16.3.md
new file mode 100644
index 000000000000..fcc6fefa33c7
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.16.3.md
@@ -0,0 +1,6 @@
+# Release 3.16.3 (2026-02-24)
+
+* Based on [upstream Nix 2.33.3](../release-notes/rl-2.33.md).
+
+## What's Changed
+This release only includes changes in determinate-nixd.
diff --git a/doc/manual/source/release-notes-determinate/v3.17.0.md b/doc/manual/source/release-notes-determinate/v3.17.0.md
new file mode 100644
index 000000000000..e09938786e55
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.17.0.md
@@ -0,0 +1,10 @@
+# Release 3.17.0 (2026-03-04)
+
+* Based on [upstream Nix 2.33.3](../release-notes/rl-2.33.md).
+
+## What's Changed
+Determinate Nix 3.17.0 brings exciting improvements like Flake Schemas, provenance, and Wasm / WASI.
+We'll be posting more details over the next week or so on our blog: https://determinate.systems/blog/.
+
+
+**Full Changelog**: [v3.16.3...v3.17.0](https://github.com/DeterminateSystems/nix-src/compare/v3.16.3...v3.17.0)
diff --git a/doc/manual/source/release-notes-determinate/v3.8.6.md b/doc/manual/source/release-notes-determinate/v3.8.6.md
new file mode 100644
index 000000000000..8f917f2362ff
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.8.6.md
@@ -0,0 +1,14 @@
+# Release 3.8.6 (2025-08-19)
+
+* Based on [upstream Nix 2.30.2](../release-notes/rl-2.30.md).
+
+## What's Changed
+* Auto update release notes by @grahamc in [DeterminateSystems/nix-src#170](https://github.com/DeterminateSystems/nix-src/pull/170)
+* Use WAL mode for SQLite cache databases (2nd attempt) by @edolstra in [DeterminateSystems/nix-src#167](https://github.com/DeterminateSystems/nix-src/pull/167)
+* Enable parallel marking in boehm-gc by @edolstra in [DeterminateSystems/nix-src#168](https://github.com/DeterminateSystems/nix-src/pull/168)
+* BasicClientConnection::queryPathInfo(): Don't throw exception for invalid paths by @edolstra in [DeterminateSystems/nix-src#172](https://github.com/DeterminateSystems/nix-src/pull/172)
+* Fix queryPathInfo() negative caching by @edolstra in [DeterminateSystems/nix-src#173](https://github.com/DeterminateSystems/nix-src/pull/173)
+* forceDerivation(): Wait for async path write after forcing value by @edolstra in [DeterminateSystems/nix-src#176](https://github.com/DeterminateSystems/nix-src/pull/176)
+
+
+**Full Changelog**: [v3.8.5...v3.8.6](https://github.com/DeterminateSystems/nix-src/compare/v3.8.5...v3.8.6)
diff --git a/doc/manual/source/release-notes-determinate/v3.9.0.md b/doc/manual/source/release-notes-determinate/v3.9.0.md
new file mode 100644
index 000000000000..66deb69b6192
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.9.0.md
@@ -0,0 +1,45 @@
+# Release 3.9.0 (2025-08-26)
+
+* Based on [upstream Nix 2.30.2](../release-notes/rl-2.30.md).
+
+## What's Changed
+
+### Build-time flake inputs
+
+Some of our users have hundreds or thousands of flake inputs.
+In those cases, it is painfully slow for Nix to fetch all the inputs during evaluation of the flake.
+
+Determinate Nix has an experimental feature for deferring the fetching to build time of the dependent derivations.
+
+This is currently in developer preview.
+If you would like to try it, add the experimental feature to your `/etc/nix/nix.custom.conf`:
+
+```ini
+extra-experimental-features = build-time-fetch-tree
+```
+
+Then, mark an input to be fetched at build time:
+
+```nix
+inputs.example = {
+ type = "github";
+ owner = "DeterminateSystems";
+ repo = "example";
+ flake = false; # <-- currently required
+ buildTime = true;
+};
+```
+
+Let us know what you think!
+
+PR: [DeterminateSystems/nix-src#49](https://github.com/DeterminateSystems/nix-src/pull/49)
+
+### Corrected inconsistent behavior of `nix flake check`
+
+Users reported that `nix flake check` would not consistently validate the entire flake.
+
+We've fixed this issue and improved our testing around `nix flake check`.
+
+PR: [DeterminateSystems/nix-src#182](https://github.com/DeterminateSystems/nix-src/pull/182)
+
+**Full Changelog**: [v3.8.6...v3.9.0](https://github.com/DeterminateSystems/nix-src/compare/v3.8.6...v3.9.0)
diff --git a/doc/manual/source/release-notes-determinate/v3.9.1.md b/doc/manual/source/release-notes-determinate/v3.9.1.md
new file mode 100644
index 000000000000..38d17199c2c0
--- /dev/null
+++ b/doc/manual/source/release-notes-determinate/v3.9.1.md
@@ -0,0 +1,20 @@
+# Release 3.9.1 (2025-08-28)
+
+- Based on [upstream Nix 2.30.2](../release-notes/rl-2.30.md).
+
+### A useful `nix flake init` template default
+
+Nix's default flake template is [extremely bare bones](https://github.com/NixOS/templates/blob/ad0e221dda33c4b564fad976281130ce34a20cb9/trivial/flake.nix), and not a useful starting point.
+
+Deteminate Nix now uses [a more fleshed out default template](https://github.com/DeterminateSystems/flake-templates/blob/8af99b99627da41f16897f60eb226db30c775e76/default/flake.nix), including targeting multiple systems.
+
+PR: [DeterminateSystems/nix-src#180](https://github.com/DeterminateSystems/nix-src/pull/180)
+
+### Build cancellation is repaired on macOS
+
+A recent macOS update changed how signals are handled by Nix and broke using Ctrl-C to stop a build.
+Determinate Nix on macOS correctly handles these signals and stops the build.
+
+PR: [DeterminateSystems/nix-src#184](https://github.com/DeterminateSystems/nix-src/pull/184)
+
+**Full Changelog**: [v3.9.0...v3.9.1](https://github.com/DeterminateSystems/nix-src/compare/v3.9.0...v3.9.1)
diff --git a/doc/manual/source/release-notes/rl-0.12.md b/doc/manual/source/release-notes/rl-0.12.md
index 3a4aba07d693..3541b6487e73 100644
--- a/doc/manual/source/release-notes/rl-0.12.md
+++ b/doc/manual/source/release-notes/rl-0.12.md
@@ -80,7 +80,7 @@
...
the following paths will be downloaded/copied (30.02 MiB):
/nix/store/4m8pvgy2dcjgppf5b4cj5l6wyshjhalj-samba-3.2.4
- /nix/store/7h1kwcj29ip8vk26rhmx6bfjraxp0g4l-libunwind-0.98.6
+ /nix/store/spc1m987vlibchdx369qwa391s738s7l-libunwind-0.98.6
...
- Language features:
diff --git a/doc/manual/source/release-notes/rl-0.8.md b/doc/manual/source/release-notes/rl-0.8.md
index 5ba6e0e7217c..2bc6352c3540 100644
--- a/doc/manual/source/release-notes/rl-0.8.md
+++ b/doc/manual/source/release-notes/rl-0.8.md
@@ -63,7 +63,7 @@ Nix 0.8 has the following improvements:
can query all paths that directly or indirectly use a certain Glibc:
$ nix-store -q --referrers-closure \
- /nix/store/8lz9yc6zgmc0vlqmn2ipcpkjlmbi51vv-glibc-2.3.4
+ /nix/store/1a6mdrjz4wn7b9sfmcw5ggbk1mi281mh-glibc-2.3.4
- The concept of fixed-output derivations has been formalised.
Previously, functions such as `fetchurl` in Nixpkgs used a hack
diff --git a/doc/manual/source/release-notes/rl-2.0.md b/doc/manual/source/release-notes/rl-2.0.md
index 25cc5e0a5f38..181940f616f9 100644
--- a/doc/manual/source/release-notes/rl-2.0.md
+++ b/doc/manual/source/release-notes/rl-2.0.md
@@ -66,7 +66,7 @@ This release has the following new features:
nix copy --to ssh://machine nixpkgs.hello
- nix copy --to ssh://machine /nix/store/0i2jd68mp5g6h2sa5k9c85rb80sn8hi9-hello-2.10
+ nix copy --to ssh://machine /nix/store/qbhyj3blxpw2i6pb7c6grc9185nbnpvy-hello-2.10
nix copy --to ssh://machine '(with import {}; hello)'
@@ -187,7 +187,7 @@ This release has the following new features:
former is primarily useful in conjunction with remote stores,
e.g.
- nix ls-store --store https://cache.nixos.org/ -lR /nix/store/0i2jd68mp5g6h2sa5k9c85rb80sn8hi9-hello-2.10
+ nix ls-store --store https://cache.nixos.org/ -lR /nix/store/qbhyj3blxpw2i6pb7c6grc9185nbnpvy-hello-2.10
lists the contents of path in a binary cache.
diff --git a/doc/manual/source/release-notes/rl-2.13.md b/doc/manual/source/release-notes/rl-2.13.md
index 168708113ea9..6976f91501be 100644
--- a/doc/manual/source/release-notes/rl-2.13.md
+++ b/doc/manual/source/release-notes/rl-2.13.md
@@ -25,7 +25,7 @@
* Allow explicitly selecting outputs in a store derivation installable, just like we can do with other sorts of installables.
For example,
```shell-session
- # nix build /nix/store/gzaflydcr6sb3567hap9q6srzx8ggdgg-glibc-2.33-78.drv^dev
+ # nix build /nix/store/fpq78s2h8ffh66v2iy0q1838mhff06y8-glibc-2.33-78.drv^dev
```
now works just as
```shell-session
diff --git a/doc/manual/source/release-notes/rl-2.15.md b/doc/manual/source/release-notes/rl-2.15.md
index e7e52631ba40..1d30c70a4c0c 100644
--- a/doc/manual/source/release-notes/rl-2.15.md
+++ b/doc/manual/source/release-notes/rl-2.15.md
@@ -18,13 +18,13 @@
For example,
```shell-session
- $ nix path-info /nix/store/gzaflydcr6sb3567hap9q6srzx8ggdgg-glibc-2.33-78.drv
+ $ nix path-info /nix/store/fpq78s2h8ffh66v2iy0q1838mhff06y8-glibc-2.33-78.drv
```
now gives info about the derivation itself, while
```shell-session
- $ nix path-info /nix/store/gzaflydcr6sb3567hap9q6srzx8ggdgg-glibc-2.33-78.drv^*
+ $ nix path-info /nix/store/fpq78s2h8ffh66v2iy0q1838mhff06y8-glibc-2.33-78.drv^*
```
provides information about each of its outputs.
diff --git a/doc/manual/source/release-notes/rl-2.19.md b/doc/manual/source/release-notes/rl-2.19.md
index 04f8c9c28d29..0596ef909619 100644
--- a/doc/manual/source/release-notes/rl-2.19.md
+++ b/doc/manual/source/release-notes/rl-2.19.md
@@ -45,7 +45,7 @@
```json5
[
{
- "path": "/nix/store/8fv91097mbh5049i9rglc73dx6kjg3qk-bash-5.2-p15",
+ "path": "/nix/store/fvqsvk65d38p8qqir371ii0hyqxvjcw6-bash-5.2-p15",
"valid": true,
// ...
},
@@ -60,7 +60,7 @@
```json5
{
- "/nix/store/8fv91097mbh5049i9rglc73dx6kjg3qk-bash-5.2-p15": {
+ "/nix/store/fvqsvk65d38p8qqir371ii0hyqxvjcw6-bash-5.2-p15": {
// ...
},
"/nix/store/wffw7l0alvs3iw94cbgi1gmmbmw99sqb-home-manager-path": null,
@@ -69,7 +69,7 @@
This makes it match `nix derivation show`, which also maps store paths to information.
-- When Nix is installed using the [binary installer](@docroot@/installation/installing-binary.md), in supported shells (Bash, Zsh, Fish)
+- When Nix is installed using the binary installer, in supported shells (Bash, Zsh, Fish)
[`XDG_DATA_DIRS`](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html#variables) is now populated with the path to the `/share` subdirectory of the current profile.
This means that command completion scripts, `.desktop` files, and similar artifacts installed via [`nix-env`](@docroot@/command-ref/nix-env.md) or [`nix profile`](@docroot@/command-ref/new-cli/nix3-profile.md)
(experimental) can be found by any program that follows the [XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html).
diff --git a/doc/manual/source/release-notes/rl-2.20.md b/doc/manual/source/release-notes/rl-2.20.md
index eb724f600aa7..d54646379c88 100644
--- a/doc/manual/source/release-notes/rl-2.20.md
+++ b/doc/manual/source/release-notes/rl-2.20.md
@@ -182,7 +182,7 @@
«partially applied primop map»
nix-repl> builtins.trace lib.id "my-value"
- trace: «lambda id @ /nix/store/8rrzq23h2zq7sv5l2vhw44kls5w0f654-source/lib/trivial.nix:26:5»
+ trace: «lambda id @ /nix/store/kgr5lnaiiv08wb7k324yv1i1npjmrvjc-source/lib/trivial.nix:26:5»
"my-value"
```
diff --git a/doc/manual/source/release-notes/rl-2.24.md b/doc/manual/source/release-notes/rl-2.24.md
index e9b46bb22b70..f608fb54f7d9 100644
--- a/doc/manual/source/release-notes/rl-2.24.md
+++ b/doc/manual/source/release-notes/rl-2.24.md
@@ -268,6 +268,21 @@
be configured using the `warn-large-path-threshold` setting,
e.g. `--warn-large-path-threshold 100M`.
+- Wrap filesystem exceptions more correctly [#11378](https://github.com/NixOS/nix/pull/11378)
+
+ With the switch to `std::filesystem` in different places, Nix started to throw `std::filesystem::filesystem_error` in many places instead of its own exceptions.
+
+ This led to no longer generating error traces, for example when listing a non-existing directory.
+
+ This version catches these types of exception correctly and wraps them into Nix's own exeception type.
+
+ Author: [**@Mic92**](https://github.com/Mic92)
+
+- `` uses TLS verification [#11585](https://github.com/NixOS/nix/pull/11585)
+
+ Previously `` did not do TLS verification. This was because the Nix sandbox in the past did not have access to TLS certificates, and Nix checks the hash of the fetched file anyway. However, this can expose authentication data from `netrc` and URLs to man-in-the-middle attackers. In addition, Nix now in some cases (such as when using impure derivations) does *not* check the hash. Therefore we have now enabled TLS verification. This means that downloads by `` will now fail if you're fetching from a HTTPS server that does not have a valid certificate.
+
+ `` is also known as the builtin derivation builder `builtin:fetchurl`. It's not to be confused with the evaluation-time function `builtins.fetchurl`, which was not affected by this issue.
## Contributors
diff --git a/doc/manual/source/release-notes/rl-2.33.md b/doc/manual/source/release-notes/rl-2.33.md
index bed697029389..810dcad00b15 100644
--- a/doc/manual/source/release-notes/rl-2.33.md
+++ b/doc/manual/source/release-notes/rl-2.33.md
@@ -279,3 +279,35 @@ This release was made possible by the following 33 contributors:
- Henry [**(@cootshk)**](https://github.com/cootshk)
- Martin Joerg [**(@mjoerg)**](https://github.com/mjoerg)
- Farid Zakaria [**(@fzakaria)**](https://github.com/fzakaria)
+# Release 2.33.3 (2026-02-13)
+
+- S3 binary caches now use virtual-hosted-style addressing by default [#15208](https://github.com/NixOS/nix/issues/15208)
+
+ S3 binary caches now use virtual-hosted-style URLs
+ (`https://bucket.s3.region.amazonaws.com/key`) instead of path-style URLs
+ (`https://s3.region.amazonaws.com/bucket/key`) when connecting to standard AWS
+ S3 endpoints. This enables HTTP/2 multiplexing and fixes TCP connection
+ exhaustion (TIME_WAIT socket accumulation) under high-concurrency workloads.
+
+ A new `addressing-style` store option controls this behavior:
+
+ - `auto` (default): virtual-hosted-style for standard AWS endpoints, path-style
+ for custom endpoints.
+ - `path`: forces path-style addressing (deprecated by AWS).
+ - `virtual`: forces virtual-hosted-style addressing (bucket names must not
+ contain dots).
+
+ Bucket names containing dots (e.g., `my.bucket.name`) automatically fall back
+ to path-style addressing in `auto` mode, because dotted names create
+ multi-level subdomains that break TLS wildcard certificate validation.
+
+ Example using path-style for backwards compatibility:
+
+ ```
+ s3://my-bucket/key?region=us-east-1&addressing-style=path
+ ```
+
+ Additionally, TCP keep-alive is now enabled on all HTTP connections, preventing
+ idle connections from being silently dropped by intermediate network devices
+ (NATs, firewalls, load balancers).
+
diff --git a/doc/manual/source/store/store-path.md b/doc/manual/source/store/store-path.md
index 4061f3653f68..08b024e4a846 100644
--- a/doc/manual/source/store/store-path.md
+++ b/doc/manual/source/store/store-path.md
@@ -2,7 +2,7 @@
> **Example**
>
-> `/nix/store/a040m110amc4h71lds2jmr8qrkj2jhxd-git-2.38.1`
+> `/nix/store/jf6gn2dzna4nmsfbdxsd7kwhsk6gnnlr-git-2.38.1`
>
> A rendered store path
@@ -22,7 +22,7 @@ Store paths are pairs of
> **Example**
>
-> - Digest: `b6gvzjyb2pg0kjfwrjmg1vfhh54ad73z`
+> - Digest: `q06x3jll2yfzckz2bzqak089p43ixkkq`
> - Name: `firefox-33.1`
To make store objects accessible to operating system processes, stores have to expose store objects through the file system.
@@ -38,7 +38,7 @@ A store path is rendered to a file system path as the concatenation of
> **Example**
>
> ```
-> /nix/store/b6gvzjyb2pg0kjfwrjmg1vfhh54ad73z-firefox-33.1
+> /nix/store/q06x3jll2yfzckz2bzqak089p43ixkkq-firefox-33.1
> |--------| |------------------------------| |----------|
> store directory digest name
> ```
diff --git a/doc/manual/source/store/types/index.md.in b/doc/manual/source/store/types/index.md.in
index a35161ce8fa4..b211ac98fe3a 100644
--- a/doc/manual/source/store/types/index.md.in
+++ b/doc/manual/source/store/types/index.md.in
@@ -8,7 +8,7 @@ Stores are specified using a URL-like syntax. For example, the command
```console
# nix path-info --store https://cache.nixos.org/ --json \
- /nix/store/a7gvj343m05j2s32xcnwr35v31ynlypr-coreutils-9.1
+ /nix/store/1542dip9i7k4f24y6hqgd04hmvid9hr5-coreutils-9.1
```
fetches information about a store path in the HTTP binary cache
diff --git a/docker.nix b/docker.nix
index 32205224b734..72c13663488d 100644
--- a/docker.nix
+++ b/docker.nix
@@ -8,6 +8,7 @@
# Image configuration
name ? "nix",
tag ? "latest",
+ fromImage ? null,
bundleNixpkgs ? true,
channelName ? "nixpkgs",
channelURL ? "https://channels.nixos.org/nixpkgs-unstable",
@@ -27,6 +28,8 @@
"org.opencontainers.image.description" = "Nix container image";
},
Cmd ? [ (lib.getExe bashInteractive) ],
+ extraPrePaths ? [ ],
+ extraPostPaths ? [ ],
# Default Packages
nix ? pkgs.nix,
bashInteractive ? pkgs.bashInteractive,
@@ -336,7 +339,7 @@ let
globalFlakeRegistryPath="$nixCacheDir/flake-registry.json"
ln -s ${flake-registry-path} $out$globalFlakeRegistryPath
mkdir -p $out/nix/var/nix/gcroots/auto
- rootName=$(${lib.getExe' nix "nix"} --extra-experimental-features nix-command hash file --type sha1 --base32 <(echo -n $globalFlakeRegistryPath))
+ rootName=$(${lib.getExe' nix "nix"} hash file --type sha1 --base32 <(echo -n $globalFlakeRegistryPath))
ln -s $globalFlakeRegistryPath $out/nix/var/nix/gcroots/auto/$rootName
'')
);
@@ -352,6 +355,7 @@ dockerTools.buildLayeredImageWithNixDb {
gid
uname
gname
+ fromImage
;
contents = [ baseSystem ];
@@ -373,11 +377,15 @@ dockerTools.buildLayeredImageWithNixDb {
Env = [
"USER=${uname}"
"PATH=${
- lib.concatStringsSep ":" [
- "${userHome}/.nix-profile/bin"
- "/nix/var/nix/profiles/default/bin"
- "/nix/var/nix/profiles/default/sbin"
- ]
+ lib.concatStringsSep ":" (
+ extraPrePaths
+ ++ [
+ "${userHome}/.nix-profile/bin"
+ "/nix/var/nix/profiles/default/bin"
+ "/nix/var/nix/profiles/default/sbin"
+ ]
+ ++ extraPostPaths
+ )
}"
"MANPATH=${
lib.concatStringsSep ":" [
diff --git a/flake.lock b/flake.lock
index 19f7b0c1c21f..f56706ec761e 100644
--- a/flake.lock
+++ b/flake.lock
@@ -3,11 +3,11 @@
"flake-compat": {
"flake": false,
"locked": {
- "lastModified": 1733328505,
- "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=",
+ "lastModified": 1696426674,
+ "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
"owner": "edolstra",
"repo": "flake-compat",
- "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec",
+ "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
"type": "github"
},
"original": {
@@ -23,55 +23,51 @@
]
},
"locked": {
- "lastModified": 1733312601,
- "narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=",
- "owner": "hercules-ci",
- "repo": "flake-parts",
- "rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9",
- "type": "github"
+ "lastModified": 1748821116,
+ "narHash": "sha256-F82+gS044J1APL0n4hH50GYdPRv/5JWm34oCJYmVKdE=",
+ "rev": "49f0870db23e8c1ca0b5259734a02cd9e1e371a1",
+ "revCount": 377,
+ "type": "tarball",
+ "url": "https://api.flakehub.com/f/pinned/hercules-ci/flake-parts/0.1.377%2Brev-49f0870db23e8c1ca0b5259734a02cd9e1e371a1/01972f28-554a-73f8-91f4-d488cc502f08/source.tar.gz"
},
"original": {
- "owner": "hercules-ci",
- "repo": "flake-parts",
- "type": "github"
+ "type": "tarball",
+ "url": "https://flakehub.com/f/hercules-ci/flake-parts/0.1"
}
},
"git-hooks-nix": {
"inputs": {
- "flake-compat": [],
+ "flake-compat": "flake-compat",
"gitignore": [],
"nixpkgs": [
"nixpkgs"
- ],
- "nixpkgs-stable": [
- "nixpkgs"
]
},
"locked": {
- "lastModified": 1734279981,
- "narHash": "sha256-NdaCraHPp8iYMWzdXAt5Nv6sA3MUzlCiGiR586TCwo0=",
- "owner": "cachix",
- "repo": "git-hooks.nix",
- "rev": "aa9f40c906904ebd83da78e7f328cd8aeaeae785",
- "type": "github"
+ "lastModified": 1747372754,
+ "narHash": "sha256-2Y53NGIX2vxfie1rOW0Qb86vjRZ7ngizoo+bnXU9D9k=",
+ "rev": "80479b6ec16fefd9c1db3ea13aeb038c60530f46",
+ "revCount": 1026,
+ "type": "tarball",
+ "url": "https://api.flakehub.com/f/pinned/cachix/git-hooks.nix/0.1.1026%2Brev-80479b6ec16fefd9c1db3ea13aeb038c60530f46/0196d79a-1b35-7b8e-a021-c894fb62163d/source.tar.gz"
},
"original": {
- "owner": "cachix",
- "repo": "git-hooks.nix",
- "type": "github"
+ "type": "tarball",
+ "url": "https://flakehub.com/f/cachix/git-hooks.nix/0.1.941"
}
},
"nixpkgs": {
"locked": {
- "lastModified": 1763948260,
- "narHash": "sha256-zZk7fn2ARAqmLwaYTpxBJmj81KIdz11NiWt7ydHHD/M=",
- "rev": "1c8ba8d3f7634acac4a2094eef7c32ad9106532c",
+ "lastModified": 1761597516,
+ "narHash": "sha256-wxX7u6D2rpkJLWkZ2E932SIvDJW8+ON/0Yy8+a5vsDU=",
+ "rev": "daf6dc47aa4b44791372d6139ab7b25269184d55",
+ "revCount": 811874,
"type": "tarball",
- "url": "https://releases.nixos.org/nixos/25.05/nixos-25.05.813095.1c8ba8d3f763/nixexprs.tar.xz"
+ "url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.2505.811874%2Brev-daf6dc47aa4b44791372d6139ab7b25269184d55/019a3494-3498-707e-9086-1fb81badc7fe/source.tar.gz"
},
"original": {
"type": "tarball",
- "url": "https://channels.nixos.org/nixos-25.05/nixexprs.tar.xz"
+ "url": "https://flakehub.com/f/NixOS/nixpkgs/0.2505"
}
},
"nixpkgs-23-11": {
@@ -108,7 +104,6 @@
},
"root": {
"inputs": {
- "flake-compat": "flake-compat",
"flake-parts": "flake-parts",
"git-hooks-nix": "git-hooks-nix",
"nixpkgs": "nixpkgs",
diff --git a/flake.nix b/flake.nix
index d35363ab2e53..b32a95b06a23 100644
--- a/flake.nix
+++ b/flake.nix
@@ -1,24 +1,18 @@
{
description = "The purely functional package manager";
- inputs.nixpkgs.url = "https://channels.nixos.org/nixos-25.05/nixexprs.tar.xz";
+ inputs.nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.2505";
inputs.nixpkgs-regression.url = "github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2";
inputs.nixpkgs-23-11.url = "github:NixOS/nixpkgs/a62e6edd6d5e1fa0329b8653c801147986f8d446";
- inputs.flake-compat = {
- url = "github:edolstra/flake-compat";
- flake = false;
- };
# dev tooling
- inputs.flake-parts.url = "github:hercules-ci/flake-parts";
- inputs.git-hooks-nix.url = "github:cachix/git-hooks.nix";
+ inputs.flake-parts.url = "https://flakehub.com/f/hercules-ci/flake-parts/0.1";
+ inputs.git-hooks-nix.url = "https://flakehub.com/f/cachix/git-hooks.nix/0.1.941";
# work around https://github.com/NixOS/nix/issues/7730
inputs.flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs";
inputs.git-hooks-nix.inputs.nixpkgs.follows = "nixpkgs";
- inputs.git-hooks-nix.inputs.nixpkgs-stable.follows = "nixpkgs";
# work around 7730 and https://github.com/NixOS/nix/issues/7807
- inputs.git-hooks-nix.inputs.flake-compat.follows = "";
inputs.git-hooks-nix.inputs.gitignore.follows = "";
outputs =
@@ -34,26 +28,24 @@
officialRelease = true;
- linux32BitSystems = [ "i686-linux" ];
+ linux32BitSystems = [ ];
linux64BitSystems = [
"x86_64-linux"
"aarch64-linux"
];
linuxSystems = linux32BitSystems ++ linux64BitSystems;
darwinSystems = [
- "x86_64-darwin"
"aarch64-darwin"
];
systems = linuxSystems ++ darwinSystems;
crossSystems = [
- "armv6l-unknown-linux-gnueabihf"
- "armv7l-unknown-linux-gnueabihf"
- "riscv64-unknown-linux-gnu"
+ #"armv6l-unknown-linux-gnueabihf"
+ #"armv7l-unknown-linux-gnueabihf"
+ #"riscv64-unknown-linux-gnu"
# Disabled because of https://github.com/NixOS/nixpkgs/issues/344423
# "x86_64-unknown-netbsd"
- "x86_64-unknown-freebsd"
- "x86_64-w64-mingw32"
+ #"x86_64-unknown-freebsd"
];
stdenvs = [
@@ -372,6 +364,40 @@
nix-manual-manpages-only = nixpkgsFor.${system}.native.nixComponents2.nix-manual-manpages-only;
nix-internal-api-docs = nixpkgsFor.${system}.native.nixComponents2.nix-internal-api-docs;
nix-external-api-docs = nixpkgsFor.${system}.native.nixComponents2.nix-external-api-docs;
+
+ fallbackPathsNix =
+ let
+ pkgs = nixpkgsFor.${system}.native;
+
+ closures = forAllSystems (system: self.packages.${system}.default.outPath);
+
+ closures_json =
+ pkgs.runCommand "versions.json"
+ {
+ buildInputs = [ pkgs.jq ];
+ passAsFile = [ "json" ];
+ json = builtins.toJSON closures;
+ }
+ ''
+ cat "$jsonPath" | jq . > $out
+ '';
+
+ closures_nix =
+ pkgs.runCommand "versions.nix"
+ {
+ buildInputs = [ pkgs.jq ];
+ passAsFile = [ "template" ];
+ jsonPath = closures_json;
+ template = ''
+ builtins.fromJSON('''@closures@''')
+ '';
+ }
+ ''
+ export closures=$(cat "$jsonPath");
+ substituteAll "$templatePath" "$out"
+ '';
+ in
+ closures_nix;
}
# We need to flatten recursive attribute sets of derivations to pass `flake check`.
//
@@ -434,8 +460,6 @@
{
# These attributes go right into `packages.`.
"${pkgName}" = nixpkgsFor.${system}.native.nixComponents2.${pkgName};
- "${pkgName}-static" = nixpkgsFor.${system}.native.pkgsStatic.nixComponents2.${pkgName};
- "${pkgName}-llvm" = nixpkgsFor.${system}.native.pkgsLLVM.nixComponents2.${pkgName};
}
// lib.optionalAttrs supportsCross (
flatMapAttrs (lib.genAttrs crossSystems (_: { })) (
@@ -446,6 +470,9 @@
"${pkgName}-${crossSystem}" = nixpkgsFor.${system}.cross.${crossSystem}.nixComponents2.${pkgName};
}
)
+ // {
+ "${pkgName}-static" = nixpkgsFor.${system}.native.pkgsStatic.nixComponents2.${pkgName};
+ }
)
// flatMapAttrs (lib.genAttrs stdenvs (_: { })) (
stdenvName:
@@ -455,6 +482,10 @@
"${pkgName}-${stdenvName}" =
nixpkgsFor.${system}.nativeForStdenv.${stdenvName}.nixComponents2.${pkgName};
}
+ // lib.optionalAttrs supportsCross {
+ "${pkgName}-${stdenvName}-static" =
+ nixpkgsFor.${system}.nativeForStdenv.${stdenvName}.pkgsStatic.nixComponents2.${pkgName};
+ }
)
)
// lib.optionalAttrs (builtins.elem system linux64BitSystems) {
@@ -512,32 +543,6 @@
}
)
)
- // lib.optionalAttrs (!nixpkgsFor.${system}.native.stdenv.isDarwin) (
- prefixAttrs "static" (
- forAllStdenvs (
- stdenvName:
- makeShell {
- pkgs = nixpkgsFor.${system}.nativeForStdenv.${stdenvName}.pkgsStatic;
- }
- )
- )
- // prefixAttrs "llvm" (
- forAllStdenvs (
- stdenvName:
- makeShell {
- pkgs = nixpkgsFor.${system}.nativeForStdenv.${stdenvName}.pkgsLLVM;
- }
- )
- )
- // prefixAttrs "cross" (
- forAllCrossSystems (
- crossSystem:
- makeShell {
- pkgs = nixpkgsFor.${system}.cross.${crossSystem};
- }
- )
- )
- )
// {
native = self.devShells.${system}.native-stdenv;
default = self.devShells.${system}.native;
diff --git a/maintainers/flake-module.nix b/maintainers/flake-module.nix
index 414e6c570ab4..7f7447b19e49 100644
--- a/maintainers/flake-module.nix
+++ b/maintainers/flake-module.nix
@@ -102,6 +102,7 @@
# Don't format vendored code
''^doc/manual/redirects\.js$''
''^doc/manual/theme/highlight\.js$''
+ ''^src/libfetchers/builtin-flake-registry\.json$''
];
};
shellcheck = {
diff --git a/maintainers/invalidate-store-paths.sh b/maintainers/invalidate-store-paths.sh
new file mode 100755
index 000000000000..a075e2621834
--- /dev/null
+++ b/maintainers/invalidate-store-paths.sh
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+set -euo pipefail
+set -x
+
+git ls-files -z \
+ | xargs -0 grep -o '[0123456789abcdfghijklmnpqrsvwxyz]\{32\}' 2> /dev/null \
+ | rev \
+ | cut -d: -f1 \
+ | rev \
+ | sort \
+ | uniq \
+ | while read -r oldhash; do
+ if ! curl --fail -I "https://cache.nixos.org/$oldhash.narinfo" > /dev/null 2>&1; then
+ continue
+ fi
+
+ newhash=$(
+ nix eval --expr "builtins.toFile \"006c6ssvddri1sg34wnw65mzd05pcp3qliylxlhv49binldajba5\" \"$oldhash\"" \
+ | cut -d- -f1 \
+ | cut -d/ -f4
+ )
+
+ msg=$(printf "bad: %s -> %s" "$oldhash" "$newhash")
+ echo "$msg"
+ git ls-files -z \
+ | xargs -0 grep -a -l "$oldhash" 2> /dev/null \
+ | while read -r file; do
+ [ -L "$file" ] && continue
+ perl -pi -e "s/$oldhash/$newhash/g" "$file" || true
+ done || true
+ git commit -am "$msg"
+ done
diff --git a/maintainers/link-headers b/maintainers/link-headers
new file mode 100755
index 000000000000..2457a2dc8295
--- /dev/null
+++ b/maintainers/link-headers
@@ -0,0 +1,83 @@
+#!/usr/bin/env python3
+
+# This script must be run from the root of the Nix repository.
+#
+# For include path hygiene, we need to put headers in a separate
+# directory than sources. But during development, it is nice to paths
+# that are similar for headers and source files, e.g.
+# `foo/bar/baz.{cc,hh}`, e.g. for less typing when opening one file, and
+# then opening the other file.
+#
+# This script symlinks the headers next to the source files to
+# facilitate such a development workflows. It also updates
+# `.git/info/exclude` so that the symlinks are not accidentally committed
+# by mistake.
+
+from pathlib import Path
+import subprocess
+import os
+
+
+def main() -> None:
+ # Path to the source directory
+ GIT_TOPLEVEL = Path(
+ subprocess.run(
+ ["git", "rev-parse", "--show-toplevel"],
+ text=True,
+ stdout=subprocess.PIPE,
+ check=True,
+ ).stdout.strip()
+ )
+
+ # Get header files from git
+ result = subprocess.run(
+ ["git", "-C", str(GIT_TOPLEVEL), "ls-files", "*/include/nix/**.hh"],
+ text=True,
+ stdout=subprocess.PIPE,
+ check=True,
+ )
+ header_files = result.stdout.strip().split("\n")
+ header_files.sort()
+
+ links = []
+ for file_str in header_files:
+ project_str, header_str = file_str.split("/include/nix/", 1)
+ project = Path(project_str)
+ header = Path(header_str)
+
+ # Reconstruct the full path (relative to SRC_DIR) to the header file.
+ file = project / "include" / "nix" / header
+
+ # The symlink should be created at "project/header", i.e. next to the project's sources.
+ link = project / header
+
+ # Compute a relative path from the symlink's parent directory to the actual header file.
+ relative_source = os.path.relpath(
+ GIT_TOPLEVEL / file, GIT_TOPLEVEL / link.parent
+ )
+
+ # Create the symbolic link.
+ full_link_path = GIT_TOPLEVEL / link
+ full_link_path.parent.mkdir(parents=True, exist_ok=True)
+ if full_link_path.is_symlink():
+ full_link_path.unlink()
+ full_link_path.symlink_to(relative_source)
+ links.append(link)
+
+ # Generate .gitignore file
+ gitignore_path = GIT_TOPLEVEL / ".git" / "info" / "exclude"
+ gitignore_path.parent.mkdir(parents=True, exist_ok=True)
+ with gitignore_path.open("w") as gitignore:
+ gitignore.write("# DO NOT EDIT! Autogenerated\n")
+ gitignore.write(
+ "# Symlinks for headers to be next to sources for development\n"
+ )
+ gitignore.write('# Run "maintainers/link-headers" to regenerate\n\n')
+ gitignore.write('# Run "maintainers/link-headers" to regenerate\n\n')
+
+ for link in links:
+ gitignore.write(f"/{link}\n")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/nix-meson-build-support/common/meson.build b/nix-meson-build-support/common/meson.build
index 5fcf557e70ba..b192c0d03521 100644
--- a/nix-meson-build-support/common/meson.build
+++ b/nix-meson-build-support/common/meson.build
@@ -65,5 +65,14 @@ endif
# Darwin ld doesn't like "X.Y.ZpreABCD+W"
nix_soversion = meson.project_version().split('+')[0].split('pre')[0]
+cxx = meson.get_compiler('cpp')
+
+# Clang does not support prelinking on static builds
+if cxx.get_id() == 'clang' and get_option('default_library') == 'static'
+ prelink = false
+else
+ prelink = true
+endif
+
subdir('assert-fail')
subdir('asan-options')
diff --git a/nix-meson-build-support/default-system-cpu/meson.build b/nix-meson-build-support/default-system-cpu/meson.build
index f63b07975b6e..3e872578efca 100644
--- a/nix-meson-build-support/default-system-cpu/meson.build
+++ b/nix-meson-build-support/default-system-cpu/meson.build
@@ -14,6 +14,6 @@ if (host_machine.cpu_family() in [ 'ppc64', 'ppc' ]) and host_machine.endian() =
nix_system_cpu += 'le'
elif host_machine.cpu_family() in [ 'mips64', 'mips' ] and host_machine.endian() == 'little'
nix_system_cpu += 'el'
-elif host_machine.cpu_family() == 'arm'
+elif host_machine.cpu_family() in [ 'arm', 'arm64' ]
nix_system_cpu = host_machine.cpu()
endif
diff --git a/packaging/components.nix b/packaging/components.nix
index dbf2180e8942..6402e8b7b2f8 100644
--- a/packaging/components.nix
+++ b/packaging/components.nix
@@ -27,7 +27,7 @@ let
pkg-config
;
- baseVersion = lib.fileContents ../.version;
+ baseVersion = lib.fileContents ../.version-determinate;
versionSuffix = lib.optionalString (!officialRelease) "pre";
@@ -51,15 +51,6 @@ let
exts: userFn: stdenv.mkDerivation (lib.extends (lib.composeManyExtensions exts) userFn);
setVersionLayer = finalAttrs: prevAttrs: {
- preConfigure =
- prevAttrs.preConfigure or ""
- +
- # Update the repo-global .version file.
- # Symlink ./.version points there, but by default only workDir is writable.
- ''
- chmod u+w ./.version
- echo ${finalAttrs.version} > ./.version
- '';
};
localSourceLayer =
diff --git a/packaging/dependencies.nix b/packaging/dependencies.nix
index 7b7ee0ecf4d8..f5e39e6e005f 100644
--- a/packaging/dependencies.nix
+++ b/packaging/dependencies.nix
@@ -16,9 +16,41 @@ in
scope: {
inherit stdenv;
+ libblake3 =
+ (pkgs.libblake3.override {
+ inherit stdenv;
+ # Nixpkgs disables tbb on static
+ useTBB = !stdenv.hostPlatform.isStatic;
+ })
+ # For some reason that is not clear, it is wanting to use libgcc_eh which is not available.
+ # Force this to be built with compiler-rt & libunwind over libgcc_eh works.
+ # Issue: https://github.com/NixOS/nixpkgs/issues/177129
+ .overrideAttrs
+ (
+ attrs:
+ lib.optionalAttrs
+ (
+ stdenv.cc.isClang
+ && stdenv.hostPlatform.isStatic
+ && stdenv.cc.libcxx != null
+ && stdenv.cc.libcxx.isLLVM
+ )
+ {
+ NIX_CFLAGS_COMPILE = [
+ "-rtlib=compiler-rt"
+ "-unwindlib=libunwind"
+ ];
+
+ buildInputs = [
+ pkgs.llvmPackages.libunwind
+ ];
+ }
+ );
+
boehmgc =
(pkgs.boehmgc.override {
enableLargeConfig = true;
+ inherit stdenv;
}).overrideAttrs
(attrs: {
# Increase the initial mark stack size to avoid stack
@@ -27,20 +59,51 @@ scope: {
# small, run Nix with GC_PRINT_STATS=1 and look for messages
# such as `Mark stack overflow`, `No room to copy back mark
# stack`, and `Grew mark stack to ... frames`.
- NIX_CFLAGS_COMPILE = "-DINITIAL_MARK_STACK_SIZE=1048576";
+ NIX_CFLAGS_COMPILE = [
+ "-DINITIAL_MARK_STACK_SIZE=1048576"
+ ]
+ # For some reason that is not clear, it is wanting to use libgcc_eh which is not available.
+ # Force this to be built with compiler-rt & libunwind over libgcc_eh works.
+ # Issue: https://github.com/NixOS/nixpkgs/issues/177129
+ ++
+ lib.optionals
+ (
+ stdenv.cc.isClang
+ && stdenv.hostPlatform.isStatic
+ && stdenv.cc.libcxx != null
+ && stdenv.cc.libcxx.isLLVM
+ )
+ [
+ "-rtlib=compiler-rt"
+ "-unwindlib=libunwind"
+ ];
+
+ buildInputs =
+ (attrs.buildInputs or [ ])
+ ++ lib.optional (
+ stdenv.cc.isClang
+ && stdenv.hostPlatform.isStatic
+ && stdenv.cc.libcxx != null
+ && stdenv.cc.libcxx.isLLVM
+ ) pkgs.llvmPackages.libunwind;
});
- lowdown = pkgs.lowdown.overrideAttrs (prevAttrs: rec {
- version = "2.0.2";
- src = pkgs.fetchurl {
- url = "https://kristaps.bsd.lv/lowdown/snapshots/lowdown-${version}.tar.gz";
- hash = "sha512-cfzhuF4EnGmLJf5EGSIbWqJItY3npbRSALm+GarZ7SMU7Hr1xw0gtBFMpOdi5PBar4TgtvbnG4oRPh+COINGlA==";
- };
- nativeBuildInputs = prevAttrs.nativeBuildInputs ++ [ pkgs.buildPackages.bmake ];
- postInstall =
- lib.replaceStrings [ "lowdown.so.1" "lowdown.1.dylib" ] [ "lowdown.so.2" "lowdown.2.dylib" ]
- (prevAttrs.postInstall or "");
- });
+ lowdown =
+ if lib.versionAtLeast pkgs.lowdown.version "2.0.2" then
+ pkgs.lowdown
+ else
+ pkgs.lowdown.overrideAttrs (prevAttrs: rec {
+ version = "2.0.2";
+ src = pkgs.fetchurl {
+ url = "https://kristaps.bsd.lv/lowdown/snapshots/lowdown-${version}.tar.gz";
+ hash = "sha512-cfzhuF4EnGmLJf5EGSIbWqJItY3npbRSALm+GarZ7SMU7Hr1xw0gtBFMpOdi5PBar4TgtvbnG4oRPh+COINGlA==";
+ };
+ patches = [ ];
+ nativeBuildInputs = prevAttrs.nativeBuildInputs ++ [ pkgs.buildPackages.bmake ];
+ postInstall =
+ lib.replaceStrings [ "lowdown.so.1" "lowdown.1.dylib" ] [ "lowdown.so.2" "lowdown.2.dylib" ]
+ (prevAttrs.postInstall or "");
+ });
# TODO: Remove this when https://github.com/NixOS/nixpkgs/pull/442682 is included in a stable release
toml11 =
@@ -66,12 +129,22 @@ scope: {
"--with-coroutine"
"--with-iostreams"
"--with-url"
+ "--with-thread"
];
enableIcu = false;
+ inherit stdenv;
}).overrideAttrs
(old: {
# Need to remove `--with-*` to use `--with-libraries=...`
buildPhase = lib.replaceStrings [ "--without-python" ] [ "" ] old.buildPhase;
installPhase = lib.replaceStrings [ "--without-python" ] [ "" ] old.installPhase;
});
+
+ wasmtime = pkgs.callPackage ./wasmtime.nix { };
+
+ curl = pkgs.curl.override {
+ # libpsl uses a data file needed at runtime, not useful for nix.
+ pslSupport = !stdenv.hostPlatform.isStatic;
+ idnSupport = !stdenv.hostPlatform.isStatic;
+ };
}
diff --git a/packaging/dev-shell.nix b/packaging/dev-shell.nix
index eecfa2ea84c0..8f963f961fb1 100644
--- a/packaging/dev-shell.nix
+++ b/packaging/dev-shell.nix
@@ -215,7 +215,7 @@ pkgs.nixComponents2.nix-util.overrideAttrs (
};
# Remove the version suffix to avoid unnecessary attempts to substitute in nix develop
- version = lib.fileContents ../.version;
+ version = lib.fileContents ../.version-determinate;
name = finalAttrs.pname;
installFlags = "sysconfdir=$(out)/etc";
@@ -259,10 +259,13 @@ pkgs.nixComponents2.nix-util.overrideAttrs (
# We use this shell with the local checkout, not unpackPhase.
src = null;
+
# Workaround https://sourceware.org/pipermail/gdb-patches/2025-October/221398.html
# Remove when gdb fix is rolled out everywhere.
separateDebugInfo = false;
+ mesonBuildType = "debugoptimized";
+
env = {
# For `make format`, to work without installing pre-commit
_NIX_PRE_COMMIT_HOOKS_CONFIG = "${(pkgs.formats.yaml { }).generate "pre-commit-config.yaml"
diff --git a/packaging/everything.nix b/packaging/everything.nix
index f6bdad4907b6..3206b8ba4235 100644
--- a/packaging/everything.nix
+++ b/packaging/everything.nix
@@ -75,7 +75,7 @@ let
};
devdoc = buildEnv {
- name = "nix-${nix-cli.version}-devdoc";
+ name = "determinate-nix-${nix-cli.version}-devdoc";
paths = [
nix-internal-api-docs
nix-external-api-docs
@@ -84,7 +84,7 @@ let
in
stdenv.mkDerivation (finalAttrs: {
- pname = "nix";
+ pname = "determinate-nix";
version = nix-cli.version;
/**
diff --git a/packaging/hydra.nix b/packaging/hydra.nix
index 3a31314f709e..9839dd621639 100644
--- a/packaging/hydra.nix
+++ b/packaging/hydra.nix
@@ -122,77 +122,6 @@ rec {
system: self.devShells.${system}.default.inputDerivation
)) [ "i686-linux" ];
- buildStatic = forAllPackages (
- pkgName:
- lib.genAttrs linux64BitSystems (
- system: nixpkgsFor.${system}.native.pkgsStatic.nixComponents2.${pkgName}
- )
- );
-
- buildCross = forAllPackages (
- pkgName:
- # Hack to avoid non-evaling package
- (
- if pkgName == "nix-functional-tests" then
- lib.flip builtins.removeAttrs [ "x86_64-w64-mingw32" ]
- else
- lib.id
- )
- (
- forAllCrossSystems (
- crossSystem:
- lib.genAttrs [ "x86_64-linux" ] (
- system: nixpkgsFor.${system}.cross.${crossSystem}.nixComponents2.${pkgName}
- )
- )
- )
- );
-
- # Builds with sanitizers already have GC disabled, so this buildNoGc can just
- # point to buildWithSanitizers in order to reduce the load on hydra.
- buildNoGc = buildWithSanitizers;
-
- buildWithSanitizers =
- let
- components = forAllSystems (
- system:
- let
- pkgs = nixpkgsFor.${system}.native;
- in
- pkgs.nixComponents2.overrideScope (
- self: super: {
- # Boost coroutines fail with ASAN on darwin.
- withASan = !pkgs.stdenv.buildPlatform.isDarwin;
- withUBSan = true;
- nix-expr = super.nix-expr.override { enableGC = false; };
- # Unclear how to make Perl bindings work with a dynamically linked ASAN.
- nix-perl-bindings = null;
- }
- )
- );
- in
- forAllPackages (pkgName: forAllSystems (system: components.${system}.${pkgName}));
-
- buildNoTests = forAllSystems (system: nixpkgsFor.${system}.native.nixComponents2.nix-cli);
-
- # Toggles some settings for better coverage. Windows needs these
- # library combinations, and Debian build Nix with GNU readline too.
- buildReadlineNoMarkdown =
- let
- components = forAllSystems (
- system:
- nixpkgsFor.${system}.native.nixComponents2.overrideScope (
- self: super: {
- nix-cmd = super.nix-cmd.override {
- enableMarkdown = false;
- readlineFlavor = "readline";
- };
- }
- )
- );
- in
- forAllPackages (pkgName: forAllSystems (system: components.${system}.${pkgName}));
-
# Perl bindings for various platforms.
perlBindings = forAllSystems (system: nixpkgsFor.${system}.native.nixComponents2.nix-perl-bindings);
@@ -203,30 +132,6 @@ rec {
system: nixpkgsFor.${system}.native.callPackage ./binary-tarball.nix { }
);
- binaryTarballCross = lib.genAttrs [ "x86_64-linux" ] (
- system:
- forAllCrossSystems (
- crossSystem: nixpkgsFor.${system}.cross.${crossSystem}.callPackage ./binary-tarball.nix { }
- )
- );
-
- # The first half of the installation script. This is uploaded
- # to https://nixos.org/nix/install. It downloads the binary
- # tarball for the user's system and calls the second half of the
- # installation script.
- installerScript = installScriptFor [
- # Native
- self.hydraJobs.binaryTarball."x86_64-linux"
- self.hydraJobs.binaryTarball."i686-linux"
- self.hydraJobs.binaryTarball."aarch64-linux"
- self.hydraJobs.binaryTarball."x86_64-darwin"
- self.hydraJobs.binaryTarball."aarch64-darwin"
- # Cross
- self.hydraJobs.binaryTarballCross."x86_64-linux"."armv6l-unknown-linux-gnueabihf"
- self.hydraJobs.binaryTarballCross."x86_64-linux"."armv7l-unknown-linux-gnueabihf"
- self.hydraJobs.binaryTarballCross."x86_64-linux"."riscv64-unknown-linux-gnu"
- ];
-
installerScriptForGHA = forAllSystems (
system:
nixpkgsFor.${system}.native.callPackage ./installer {
@@ -294,6 +199,19 @@ rec {
pkgs = nixpkgsFor.${system}.native;
}
);
+
+ nixpkgsLibTestsLazy = forAllSystems (
+ system:
+ lib.overrideDerivation
+ (import (nixpkgs + "/lib/tests/test-with-nix.nix") {
+ lib = nixpkgsFor.${system}.native.lib;
+ nix = self.packages.${system}.nix-cli;
+ pkgs = nixpkgsFor.${system}.native;
+ })
+ (_: {
+ "NIX_CONFIG" = "lazy-trees = true";
+ })
+ );
};
metrics.nixpkgs = import "${nixpkgs-regression}/pkgs/top-level/metrics.nix" {
@@ -308,17 +226,12 @@ rec {
in
pkgs.runCommand "install-tests" {
againstSelf = testNixVersions pkgs pkgs.nix;
- againstCurrentLatest =
- # FIXME: temporarily disable this on macOS because of #3605.
- if system == "x86_64-linux" then testNixVersions pkgs pkgs.nixVersions.latest else null;
+ #againstCurrentLatest =
+ # # FIXME: temporarily disable this on macOS because of #3605.
+ # if system == "x86_64-linux" then testNixVersions pkgs pkgs.nixVersions.latest else null;
# Disabled because the latest stable version doesn't handle
# `NIX_DAEMON_SOCKET_PATH` which is required for the tests to work
# againstLatestStable = testNixVersions pkgs pkgs.nixStable;
} "touch $out"
);
-
- installerTests = import ../tests/installer {
- binaryTarballs = self.hydraJobs.binaryTarball;
- inherit nixpkgsFor;
- };
}
diff --git a/packaging/installer/default.nix b/packaging/installer/default.nix
index e171f36f99f7..a8e344b496c8 100644
--- a/packaging/installer/default.nix
+++ b/packaging/installer/default.nix
@@ -32,7 +32,7 @@ runCommand "installer-script"
in
''
\
- --replace '@tarballHash_${system}@' $(nix --experimental-features nix-command hash-file --base16 --type sha256 ${tarball}/*.tar.xz) \
+ --replace '@tarballHash_${system}@' $(nix hash-file --base16 --type sha256 ${tarball}/*.tar.xz) \
--replace '@tarballPath_${system}@' $(tarballPath ${tarball}/*.tar.xz) \
''
) tarballs
diff --git a/packaging/wasmtime.nix b/packaging/wasmtime.nix
new file mode 100644
index 000000000000..3e8b71280c07
--- /dev/null
+++ b/packaging/wasmtime.nix
@@ -0,0 +1,74 @@
+# Stripped-down version of https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/wa/wasmtime/package.nix,
+# license: https://github.com/NixOS/nixpkgs/blob/master/COPYING
+{
+ lib,
+ stdenv,
+ rust_1_89,
+ fetchFromGitHub,
+ cmake,
+ enableShared ? !stdenv.hostPlatform.isStatic,
+ enableStatic ? stdenv.hostPlatform.isStatic,
+}:
+rust_1_89.packages.stable.rustPlatform.buildRustPackage (finalAttrs: {
+ pname = "wasmtime";
+ version = "40.0.2";
+
+ src = fetchFromGitHub {
+ owner = "bytecodealliance";
+ repo = "wasmtime";
+ tag = "v${finalAttrs.version}";
+ hash = "sha256-4y9WpCdyuF/Tp2k/1d5rZxwYunWNdeibEsFgHcBC52Q=";
+ fetchSubmodules = true;
+ };
+
+ # Disable cargo-auditable until https://github.com/rust-secure-code/cargo-auditable/issues/124 is solved.
+ auditable = false;
+
+ cargoHash = "sha256-aTPgnuBvOIqg1+Sa2ZLdMTLujm8dKGK5xpZ3qHpr3f8=";
+ cargoBuildFlags = [
+ "--package"
+ "wasmtime-c-api"
+ "--no-default-features"
+ "--features cranelift,wasi,pooling-allocator,wat,demangle,gc-null"
+ ];
+
+ outputs = [
+ "out"
+ "lib"
+ ];
+
+ nativeBuildInputs = [
+ cmake
+ ];
+
+ doCheck =
+ with stdenv.buildPlatform;
+ # SIMD tests are only executed on platforms that support all
+ # required processor features (e.g. SSE3, SSSE3 and SSE4.1 on x86_64):
+ # https://github.com/bytecodealliance/wasmtime/blob/v9.0.0/cranelift/codegen/src/isa/x64/mod.rs#L220
+ (isx86_64 -> sse3Support && ssse3Support && sse4_1Support)
+ &&
+ # The dependency `wasi-preview1-component-adapter` fails to build because of:
+ # error: linker `rust-lld` not found
+ !isAarch64;
+
+ postInstall =
+ let
+ inherit (stdenv.hostPlatform.rust) cargoShortTarget;
+ in
+ ''
+ moveToOutput lib $lib
+ ${lib.optionalString (!enableShared) "rm -f $lib/lib/*.so{,.*}"}
+ ${lib.optionalString (!enableStatic) "rm -f $lib/lib/*.a"}
+
+ # copy the build.rs generated c-api headers
+ # https://github.com/rust-lang/cargo/issues/9661
+ mkdir -p $out
+ cp -r target/${cargoShortTarget}/release/build/wasmtime-c-api-impl-*/out/include $out/include
+ ''
+ + lib.optionalString stdenv.hostPlatform.isDarwin ''
+ install_name_tool -id \
+ $lib/lib/libwasmtime.dylib \
+ $lib/lib/libwasmtime.dylib
+ '';
+})
diff --git a/scripts/install-multi-user.sh b/scripts/install-multi-user.sh
index 5ff760a6143f..683beca10fde 100644
--- a/scripts/install-multi-user.sh
+++ b/scripts/install-multi-user.sh
@@ -53,8 +53,8 @@ readonly PROFILE_NIX_FILE_FISH="$NIX_ROOT/var/nix/profiles/default/etc/profile.d
readonly NIX_INSTALLED_NIX="@nix@"
readonly NIX_INSTALLED_CACERT="@cacert@"
-#readonly NIX_INSTALLED_NIX="/nix/store/j8dbv5w6jl34caywh2ygdy88knx1mdf7-nix-2.3.6"
-#readonly NIX_INSTALLED_CACERT="/nix/store/7dxhzymvy330i28ii676fl1pqwcahv2f-nss-cacert-3.49.2"
+#readonly NIX_INSTALLED_NIX="/nix/store/byi37zv50wnfrpp4d81z3spswd5zva37-nix-2.3.6"
+#readonly NIX_INSTALLED_CACERT="/nix/store/7pi45g541xa8ahwgpbpy7ggsl0xj1jj6-nss-cacert-3.49.2"
EXTRACTED_NIX_PATH="$(dirname "$0")"
readonly EXTRACTED_NIX_PATH
diff --git a/shell.nix b/shell.nix
deleted file mode 100644
index 918f4bbd9e9e..000000000000
--- a/shell.nix
+++ /dev/null
@@ -1,3 +0,0 @@
-(import (fetchTarball "https://github.com/edolstra/flake-compat/archive/master.tar.gz") {
- src = ./.;
-}).shellNix
diff --git a/src/external-api-docs/package.nix b/src/external-api-docs/package.nix
index b194e16d4608..28cde8c09e69 100644
--- a/src/external-api-docs/package.nix
+++ b/src/external-api-docs/package.nix
@@ -14,7 +14,7 @@ let
in
mkMesonDerivation (finalAttrs: {
- pname = "nix-external-api-docs";
+ pname = "determinate-nix-external-api-docs";
inherit version;
workDir = ./.;
diff --git a/src/internal-api-docs/package.nix b/src/internal-api-docs/package.nix
index 6c4f354aee5c..636c19653eab 100644
--- a/src/internal-api-docs/package.nix
+++ b/src/internal-api-docs/package.nix
@@ -14,7 +14,7 @@ let
in
mkMesonDerivation (finalAttrs: {
- pname = "nix-internal-api-docs";
+ pname = "determinate-nix-internal-api-docs";
inherit version;
workDir = ./.;
diff --git a/src/libcmd/builtin-flake-schemas.nix b/src/libcmd/builtin-flake-schemas.nix
new file mode 100644
index 000000000000..f326b413c9e6
--- /dev/null
+++ b/src/libcmd/builtin-flake-schemas.nix
@@ -0,0 +1,438 @@
+{
+ description = "Schemas for well-known Nix flake output types";
+
+ outputs =
+ { self }:
+ let
+ mapAttrsToList = f: attrs: map (name: f name attrs.${name}) (builtins.attrNames attrs);
+
+ checkModule = module: builtins.isAttrs module || builtins.isFunction module;
+
+ schemasSchema = {
+ version = 1;
+ doc = ''
+ The `schemas` flake output is used to define and document flake outputs.
+ For the expected format, consult the Nix manual.
+ '';
+ inventory =
+ output:
+ self.lib.mkChildren (
+ builtins.mapAttrs (schemaName: schemaDef: {
+ shortDescription = "A schema checker for the `${schemaName}` flake output";
+ evalChecks.isValidSchema =
+ schemaDef.version or 0 == 1
+ && schemaDef ? doc
+ && builtins.isString (schemaDef.doc)
+ && schemaDef ? inventory
+ && builtins.isFunction (schemaDef.inventory);
+ what = "flake schema";
+ }) output
+ );
+ };
+
+ appsSchema = {
+ version = 1;
+ doc = ''
+ The `apps` output provides commands available via `nix run`.
+ '';
+ roles.nix-run = { };
+ appendSystem = true;
+ defaultAttrPath = [ "default" ];
+ inventory =
+ output:
+ self.lib.mkChildren (
+ builtins.mapAttrs (
+ system: apps:
+ let
+ forSystems = [ system ];
+ in
+ {
+ inherit forSystems;
+ children = builtins.mapAttrs (appName: app: {
+ inherit forSystems;
+ evalChecks.isValidApp =
+ app ? type
+ && app.type == "app"
+ && app ? program
+ && builtins.isString app.program
+ &&
+ builtins.removeAttrs app [
+ "type"
+ "program"
+ "meta"
+ ] == { };
+ what = "app";
+ }) apps;
+ }
+ ) output
+ );
+ };
+
+ packagesSchema = {
+ version = 1;
+ doc = ''
+ The `packages` flake output contains packages that can be added to a shell using `nix shell`.
+ '';
+ roles.nix-build = { };
+ roles.nix-run = { };
+ roles.nix-develop = { };
+ roles.nix-search = { };
+ appendSystem = true;
+ defaultAttrPath = [ "default" ];
+ inventory = self.lib.derivationsInventory "package" false;
+ };
+
+ dockerImagesSchema = {
+ version = 1;
+ doc = ''
+ The `dockerImages` flake output contains derivations that build valid Docker images.
+ '';
+ inventory = self.lib.derivationsInventory "Docker image" false;
+ };
+
+ legacyPackagesSchema = {
+ version = 1;
+ doc = ''
+ The `legacyPackages` flake output is similar to `packages` but different in that it can be nested and thus contain attribute sets that contain more packages.
+ Since enumerating packages in nested attribute sets can be inefficient, you should favor `packages` over `legacyPackages`.
+ '';
+ roles.nix-build = { };
+ roles.nix-run = { };
+ roles.nix-search = { };
+ appendSystem = true;
+ inventory =
+ output:
+ self.lib.mkChildren (
+ builtins.mapAttrs (systemType: packagesForSystem: {
+ forSystems = [ systemType ];
+ children =
+ let
+ recurse =
+ prefix: attrs:
+ builtins.mapAttrs (
+ attrName: attrs:
+ # Necessary to deal with `AAAAAASomeThingsFailToEvaluate` etc. in Nixpkgs.
+ self.lib.try (
+ if attrs.type or null == "derivation" then
+ {
+ forSystems = [ attrs.system ];
+ shortDescription = attrs.meta.description or "";
+ derivationAttrPath = [ ];
+ what = "package";
+ }
+ else
+ # Recurse at the first and second levels, or if the
+ # recurseForDerivations attribute if set.
+ if attrs.recurseForDerivations or false then
+ {
+ children = recurse (prefix + attrName + ".") attrs;
+ }
+ else
+ {
+ what = "unknown";
+ }
+ ) (throw "failed")
+ ) attrs;
+ in
+ # The top-level cannot be a derivation.
+ assert packagesForSystem.type or null != "derivation";
+ recurse (systemType + ".") packagesForSystem;
+ }) output
+ );
+ };
+
+ checksSchema = {
+ version = 1;
+ doc = ''
+ The `checks` flake output contains derivations that will be built by `nix flake check`.
+ '';
+ # FIXME: add role
+ inventory = self.lib.derivationsInventory "CI test" true;
+ };
+
+ devShellsSchema = {
+ version = 1;
+ doc = ''
+ The `devShells` flake output contains derivations that provide a development environment for `nix develop`.
+ '';
+ roles.nix-develop = { };
+ appendSystem = true;
+ defaultAttrPath = [ "default" ];
+ inventory = self.lib.derivationsInventory "development environment" false;
+ };
+
+ formatterSchema = {
+ version = 1;
+ doc = ''
+ The `formatter` output specifies the package to use to format the project.
+ '';
+ roles.nix-fmt = { };
+ appendSystem = true;
+ defaultAttrPath = [ ];
+ inventory =
+ output:
+ self.lib.mkChildren (
+ builtins.mapAttrs (system: formatter: {
+ forSystems = [ system ];
+ shortDescription = formatter.meta.description or "";
+ derivationAttrPath = [ ];
+ what = "formatter";
+ isFlakeCheck = false;
+ }) output
+ );
+ };
+
+ templatesSchema = {
+ version = 1;
+ doc = ''
+ The `templates` output provides project templates.
+ '';
+ roles.nix-template = { };
+ defaultAttrPath = [ "default" ];
+ inventory =
+ output:
+ self.lib.mkChildren (
+ builtins.mapAttrs (templateName: template: {
+ shortDescription = template.description or "";
+ evalChecks.isValidTemplate =
+ template ? path
+ && builtins.isPath template.path
+ && template ? description
+ && builtins.isString template.description;
+ what = "template";
+ }) output
+ );
+ };
+
+ hydraJobsSchema = {
+ version = 1;
+ doc = ''
+ The `hydraJobs` flake output defines derivations to be built by the Hydra continuous integration system.
+ '';
+ allowIFD = false;
+ inventory =
+ output:
+ let
+ recurse =
+ prefix: attrs:
+ self.lib.mkChildren (
+ builtins.mapAttrs (
+ attrName: attrs:
+ if attrs.type or null == "derivation" then
+ {
+ forSystems = [ attrs.system ];
+ shortDescription = attrs.meta.description or "";
+ derivationAttrPath = [ ];
+ what = "Hydra CI test";
+ }
+ else
+ recurse (prefix + attrName + ".") attrs
+ ) attrs
+ );
+ in
+ # The top-level cannot be a derivation.
+ assert output.type or null != "derivation";
+ recurse "" output;
+ };
+
+ overlaysSchema = {
+ version = 1;
+ doc = ''
+ The `overlays` flake output defines ["overlays"](https://nixos.org/manual/nixpkgs/stable/#chap-overlays) that can be plugged into Nixpkgs.
+ Overlays add additional packages or modify or replace existing packages.
+ '';
+ inventory =
+ output:
+ self.lib.mkChildren (
+ builtins.mapAttrs (overlayName: overlay: {
+ what = "Nixpkgs overlay";
+ evalChecks.isOverlay =
+ # FIXME: should try to apply the overlay to an actual
+ # Nixpkgs. But we don't have access to a nixpkgs
+ # flake here. Maybe this schema should be moved to the
+ # nixpkgs flake, where it does have access.
+ if !builtins.isFunction overlay then
+ throw "overlay is not a function, but a set instead"
+ else
+ builtins.isAttrs (overlay { } { });
+ }) output
+ );
+ };
+
+ nixosConfigurationsSchema = {
+ version = 1;
+ doc = ''
+ The `nixosConfigurations` flake output defines [NixOS system configurations](https://nixos.org/manual/nixos/stable/#ch-configuration).
+ '';
+ inventory =
+ output:
+ self.lib.mkChildren (
+ builtins.mapAttrs (configName: machine: {
+ what = "NixOS configuration";
+ derivationAttrPath = [
+ "config"
+ "system"
+ "build"
+ "toplevel"
+ ];
+ forSystems = [ machine.pkgs.stdenv.system ];
+ }) output
+ );
+ };
+
+ nixosModulesSchema = {
+ version = 1;
+ doc = ''
+ The `nixosModules` flake output defines importable [NixOS modules](https://nixos.org/manual/nixos/stable/#sec-writing-modules).
+ '';
+ inventory =
+ output:
+ self.lib.mkChildren (
+ builtins.mapAttrs (moduleName: module: {
+ what = "NixOS module";
+ evalChecks.isFunctionOrAttrs = checkModule module;
+ }) output
+ );
+ };
+
+ homeConfigurationsSchema = {
+ version = 1;
+ doc = ''
+ The `homeConfigurations` flake output defines [Home Manager configurations](https://github.com/nix-community/home-manager).
+ '';
+ inventory =
+ output:
+ self.lib.mkChildren (
+ builtins.mapAttrs (configName: this: {
+ what = "Home Manager configuration";
+ derivationAttrPath = [ "activationPackage" ];
+ forSystems = [ this.activationPackage.system ];
+ }) output
+ );
+ };
+
+ homeModulesSchema = {
+ version = 1;
+ doc = ''
+ The `homeModules` flake output defines importable [Home Manager](https://github.com/nix-community/home-manager) modules.
+ '';
+ inventory =
+ output:
+ self.lib.mkChildren (
+ builtins.mapAttrs (moduleName: module: {
+ what = "Home Manager module";
+ evalChecks.isFunctionOrAttrs = checkModule module;
+ }) output
+ );
+ };
+
+ darwinConfigurationsSchema = {
+ version = 1;
+ doc = ''
+ The `darwinConfigurations` flake output defines [nix-darwin configurations](https://github.com/nix-darwin/nix-darwin).
+ '';
+ inventory =
+ output:
+ self.lib.mkChildren (
+ builtins.mapAttrs (configName: this: {
+ what = "nix-darwin configuration";
+ derivationAttrPath = [ "system" ];
+ forSystems = [ this.system.system ];
+ }) output
+ );
+ };
+
+ darwinModulesSchema = {
+ version = 1;
+ doc = ''
+ The `darwinModules` flake output defines importable [nix-darwin modules](https://github.com/nix-darwin/nix-darwin).
+ '';
+ inventory =
+ output:
+ self.lib.mkChildren (
+ builtins.mapAttrs (moduleName: module: {
+ what = "nix-darwin module";
+ evalChecks.isFunctionOrAttrs = checkModule module;
+ }) output
+ );
+ };
+
+ bundlersSchema = {
+ version = 1;
+ doc = ''
+ The `bundlers` flake output defines ["bundlers"](https://nix.dev/manual/nix/latest/command-ref/new-cli/nix3-bundle) that transform derivation outputs into other formats, typically self-extracting executables or container images.
+ '';
+ roles.nix-bundler = { };
+ appendSystem = true;
+ defaultAttrPath = [ "default" ];
+ inventory =
+ output:
+ self.lib.mkChildren (
+ builtins.mapAttrs (
+ system: bundlers:
+ let
+ forSystems = [ system ];
+ in
+ {
+ inherit forSystems;
+ children = builtins.mapAttrs (bundlerName: bundler: {
+ inherit forSystems;
+ evalChecks.isValidBundler = builtins.isFunction bundler;
+ what = "bundler";
+ }) bundlers;
+ }
+ ) output
+ );
+ };
+
+ in
+
+ {
+ # Helper functions
+ lib = {
+ try =
+ e: default:
+ let
+ res = builtins.tryEval e;
+ in
+ if res.success then res.value else default;
+
+ mkChildren = children: { inherit children; };
+
+ derivationsInventory =
+ what: isFlakeCheck: output:
+ self.lib.mkChildren (
+ builtins.mapAttrs (systemType: packagesForSystem: {
+ forSystems = [ systemType ];
+ children = builtins.mapAttrs (packageName: package: {
+ forSystems = [ systemType ];
+ shortDescription = package.meta.description or "";
+ derivationAttrPath = [ ];
+ inherit what;
+ isFlakeCheck = isFlakeCheck;
+ }) packagesForSystem;
+ }) output
+ );
+ };
+
+ # FIXME: distinguish between available and active schemas?
+ schemas.schemas = schemasSchema;
+ schemas.apps = appsSchema;
+ schemas.packages = packagesSchema;
+ schemas.legacyPackages = legacyPackagesSchema;
+ schemas.checks = checksSchema;
+ schemas.devShells = devShellsSchema;
+ schemas.formatter = formatterSchema;
+ schemas.templates = templatesSchema;
+ schemas.hydraJobs = hydraJobsSchema;
+ schemas.overlays = overlaysSchema;
+ schemas.nixosConfigurations = nixosConfigurationsSchema;
+ schemas.nixosModules = nixosModulesSchema;
+ schemas.homeConfigurations = homeConfigurationsSchema;
+ schemas.homeModules = homeModulesSchema;
+ schemas.darwinConfigurations = darwinConfigurationsSchema;
+ schemas.darwinModules = darwinModulesSchema;
+ schemas.dockerImages = dockerImagesSchema;
+ schemas.bundlers = bundlersSchema;
+ };
+}
diff --git a/src/libcmd/call-flake-schemas.nix b/src/libcmd/call-flake-schemas.nix
new file mode 100644
index 000000000000..f1604259aef7
--- /dev/null
+++ b/src/libcmd/call-flake-schemas.nix
@@ -0,0 +1,38 @@
+# The flake providing default schemas.
+defaultSchemasFlake:
+
+# The flake whose contents we want to extract.
+flake:
+
+let
+
+ # Helper functions.
+
+ mapAttrsToList = f: attrs: map (name: f name attrs.${name}) (builtins.attrNames attrs);
+
+ outputNames = builtins.attrNames flake.outputs;
+
+ schemas = flake.outputs.schemas or defaultSchemasFlake.schemas;
+
+in
+
+{
+ outputs = flake.outputs;
+
+ inventory = builtins.mapAttrs (
+ outputName: _:
+ if schemas ? ${outputName} && schemas.${outputName}.version == 1 then
+ schemas.${outputName}
+ // (
+ if flake.outputs ? ${outputName} then
+ {
+ output = schemas.${outputName}.inventory flake.outputs.${outputName};
+ }
+ else
+ {
+ }
+ )
+ else
+ { unknown = true; }
+ ) (schemas // flake.outputs);
+}
diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc
index 798ef072eb14..226b65f4a7c3 100644
--- a/src/libcmd/command.cc
+++ b/src/libcmd/command.cc
@@ -138,6 +138,13 @@ ref EvalCommand::getEvalStore()
ref EvalCommand::getEvalState()
{
if (!evalState) {
+ if (startReplOnEvalErrors && evalSettings.evalCores != 1U) {
+ // Disable parallel eval if the debugger is enabled, since
+ // they're incompatible at the moment.
+ warn("using the debugger disables multi-threaded evaluation");
+ evalSettings.evalCores = 1;
+ }
+
evalState = std::allocate_shared(
traceable_allocator(), lookupPath, getEvalStore(), fetchSettings, evalSettings, getStore());
diff --git a/src/libcmd/common-eval-args.cc b/src/libcmd/common-eval-args.cc
index 30e76b2455d4..865901febf48 100644
--- a/src/libcmd/common-eval-args.cc
+++ b/src/libcmd/common-eval-args.cc
@@ -19,17 +19,12 @@
namespace nix {
-fetchers::Settings fetchSettings;
-
-static GlobalConfig::Register rFetchSettings(&fetchSettings);
-
EvalSettings evalSettings{
settings.readOnlyMode,
{
{
"flake",
[](EvalState & state, std::string_view rest) {
- experimentalFeatureSettings.require(Xp::Flakes);
// FIXME `parseFlakeRef` should take a `std::string_view`.
auto flakeRef = parseFlakeRef(fetchSettings, std::string{rest}, {}, true, false);
debug("fetching flake search path element '%s''", rest);
@@ -186,7 +181,6 @@ SourcePath lookupFileArg(EvalState & state, std::string_view s, const std::files
}
else if (hasPrefix(s, "flake:")) {
- experimentalFeatureSettings.require(Xp::Flakes);
auto flakeRef = parseFlakeRef(fetchSettings, std::string(s.substr(6)), {}, true, false);
auto [accessor, lockedRef] =
flakeRef.resolve(fetchSettings, *state.store).lazyFetch(fetchSettings, *state.store);
diff --git a/src/libcmd/flake-schemas.cc b/src/libcmd/flake-schemas.cc
new file mode 100644
index 000000000000..725326c0fd75
--- /dev/null
+++ b/src/libcmd/flake-schemas.cc
@@ -0,0 +1,362 @@
+#include "nix/cmd/flake-schemas.hh"
+#include "nix/expr/eval-settings.hh"
+#include "nix/fetchers/fetch-to-store.hh"
+#include "nix/util/memory-source-accessor.hh"
+#include "nix/util/mounted-source-accessor.hh"
+
+namespace nix::flake_schemas {
+
+using namespace eval_cache;
+using namespace flake;
+
+static LockedFlake getBuiltinDefaultSchemasFlake(EvalState & state)
+{
+ auto accessor = make_ref();
+
+ accessor->setPathDisplay("«builtin-flake-schemas»");
+
+ accessor->addFile(
+ CanonPath("flake.nix"),
+#include "builtin-flake-schemas.nix.gen.hh"
+ );
+
+ auto [storePath, narHash] = state.store->computeStorePath("source", {accessor});
+
+ state.allowPath(storePath); // FIXME: should just whitelist the entire virtual store
+
+ state.storeFS->mount(CanonPath(state.store->printStorePath(storePath)), accessor);
+
+ // Construct a dummy flakeref.
+ auto flakeRef = parseFlakeRef(
+ fetchSettings,
+ fmt("tarball+https://builtin-flake-schemas?narHash=%s", narHash.to_string(HashFormat::SRI, true)));
+
+ auto flake = readFlake(state, flakeRef, flakeRef, flakeRef, state.storePath(storePath), {});
+
+ return lockFlake(flakeSettings, state, flakeRef, {}, flake);
+}
+
+ref call(
+ EvalState & state,
+ std::shared_ptr lockedFlake,
+ std::optional defaultSchemasFlake,
+ bool allowEvalCache)
+{
+ auto fingerprint = lockedFlake->getFingerprint(*state.store, state.fetchSettings);
+
+ std::string callFlakeSchemasNix =
+#include "call-flake-schemas.nix.gen.hh"
+ ;
+
+ auto lockedDefaultSchemasFlake = defaultSchemasFlake
+ ? flake::lockFlake(flakeSettings, state, *defaultSchemasFlake, {})
+ : getBuiltinDefaultSchemasFlake(state);
+ auto lockedDefaultSchemasFlakeFingerprint =
+ lockedDefaultSchemasFlake.getFingerprint(*state.store, state.fetchSettings);
+
+ std::optional fingerprint2;
+ if (fingerprint && lockedDefaultSchemasFlakeFingerprint)
+ fingerprint2 = hashString(
+ HashAlgorithm::SHA256,
+ fmt("app:%s:%s:%s",
+ hashString(HashAlgorithm::SHA256, callFlakeSchemasNix).to_string(HashFormat::Base16, false),
+ fingerprint->to_string(HashFormat::Base16, false),
+ lockedDefaultSchemasFlakeFingerprint->to_string(HashFormat::Base16, false)));
+
+ auto cache = make_ref(
+ allowEvalCache && evalSettings.useEvalCache && evalSettings.pureEval ? fingerprint2 : std::nullopt,
+ state,
+ [&state, lockedFlake, callFlakeSchemasNix, lockedDefaultSchemasFlake]() {
+ auto vCallFlakeSchemas = state.allocValue();
+ state.eval(
+ state.parseExprFromString(callFlakeSchemasNix, state.rootPath(CanonPath::root)), *vCallFlakeSchemas);
+
+ auto vFlake = state.allocValue();
+ flake::callFlake(state, *lockedFlake, *vFlake);
+
+ auto vDefaultSchemasFlake = state.allocValue();
+ if (vFlake->type() == nAttrs && vFlake->attrs()->get(state.symbols.create("schemas")))
+ vDefaultSchemasFlake->mkNull();
+ else
+ flake::callFlake(state, lockedDefaultSchemasFlake, *vDefaultSchemasFlake);
+
+ auto vRes = state.allocValue();
+ Value * args[] = {vDefaultSchemasFlake, vFlake};
+ state.callFunction(*vCallFlakeSchemas, args, *vRes, noPos);
+
+ return vRes;
+ });
+
+ /* Derive the flake output attribute path from the cursor used to
+ traverse the inventory. We do this so we don't have to maintain
+ a separate attrpath for that. */
+ cache->cleanupAttrPath = [&](AttrPath && attrPath) {
+ AttrPath res;
+ auto i = attrPath.begin();
+ if (i == attrPath.end())
+ return attrPath;
+
+ if (state.symbols[*i] == "inventory") {
+ ++i;
+ if (i != attrPath.end()) {
+ res.push_back(*i++); // copy output name
+ if (i != attrPath.end())
+ ++i; // skip "outputs"
+ while (i != attrPath.end()) {
+ ++i; // skip "children"
+ if (i != attrPath.end())
+ res.push_back(*i++);
+ }
+ }
+ }
+
+ else if (state.symbols[*i] == "outputs") {
+ res.insert(res.begin(), ++i, attrPath.end());
+ }
+
+ else
+ abort();
+
+ return res;
+ };
+
+ return cache;
+}
+
+void forEachOutput(
+ ref inventory,
+ std::function output, const std::string & doc, bool isLast)> f)
+{
+ auto outputNames = inventory->getAttrs();
+
+ auto doOutputs = [&](bool allowIFD) {
+ evalSettings.enableImportFromDerivation.setDefault(allowIFD);
+ for (const auto & [i, outputName] : enumerate(outputNames)) {
+ auto outputInfo = inventory->getAttr(outputName);
+ try {
+ auto allowIFDAttr = outputInfo->maybeGetAttr("allowIFD");
+ if (allowIFD != (!allowIFDAttr || allowIFDAttr->getBool()))
+ continue;
+ auto isUnknown = (bool) outputInfo->maybeGetAttr("unknown");
+ auto output = outputInfo->maybeGetAttr("output");
+ if (!output && !isUnknown)
+ // We have a schema but no corresponding output, so skip this.
+ continue;
+ Activity act(*logger, lvlInfo, actUnknown, fmt("evaluating '%s'", outputInfo->getAttrPathStr()));
+ f(outputName,
+ isUnknown ? std::shared_ptr() : output,
+ isUnknown ? "" : outputInfo->getAttr("doc")->getString(),
+ i + 1 == outputNames.size());
+ } catch (Error & e) {
+ e.addTrace(nullptr, "while evaluating the flake output '%s':", outputInfo->getAttrPathStr());
+ throw;
+ }
+ }
+ };
+
+ // Do outputs that disallow import-from-derivation first. That way, they can't depend on outputs that do allow it.
+ doOutputs(false);
+ doOutputs(true);
+}
+
+void visit(
+ std::optional system,
+ ref node,
+ std::function visitLeaf,
+ std::function)> visitNonLeaf,
+ std::function node, const std::vector & systems)> visitFiltered)
+{
+ Activity act(*logger, lvlInfo, actUnknown, fmt("evaluating '%s'", node->getAttrPathStr()));
+
+ /* Apply the system type filter. */
+ if (system) {
+ if (auto forSystems = Node(node).forSystems()) {
+ if (std::find(forSystems->begin(), forSystems->end(), *system) == forSystems->end()) {
+ visitFiltered(node, *forSystems);
+ return;
+ }
+ }
+ }
+
+ if (auto children = node->maybeGetAttr("children")) {
+ visitNonLeaf([&](ForEachChild f) {
+ auto attrNames = children->getAttrs();
+ for (const auto & [i, attrName] : enumerate(attrNames)) {
+ try {
+ f(attrName, children->getAttr(attrName), i + 1 == attrNames.size());
+ } catch (Error & e) {
+ // FIXME: make it a flake schema attribute whether to ignore evaluation errors.
+ if (node->root->state.symbols[node->getAttrPath()[0]] != "legacyPackages") {
+ e.addTrace(
+ nullptr, "while evaluating the flake output attribute '%s':", node->getAttrPathStr());
+ throw;
+ }
+ }
+ }
+ });
+ }
+
+ else
+ visitLeaf(Leaf(node));
+}
+
+std::optional> Node::forSystems() const
+{
+ if (auto forSystems = node->maybeGetAttr("forSystems"))
+ return forSystems->getListOfStrings();
+ else
+ return std::nullopt;
+}
+
+ref Node::getOutput(const ref & outputs) const
+{
+ auto res = outputs->findAlongAttrPath(node->getAttrPath());
+ if (!res)
+ throw Error("flake output '%s' should exist according to its schema, but it doesn't", node->getAttrPathStr());
+ return *res;
+}
+
+std::optional Leaf::what() const
+{
+ if (auto what = node->maybeGetAttr("what"))
+ return what->getString();
+ else
+ return std::nullopt;
+}
+
+std::optional Leaf::shortDescription() const
+{
+ if (auto what = node->maybeGetAttr("shortDescription"))
+ return what->getString();
+ return std::nullopt;
+}
+
+std::optional Leaf::derivationAttrPath() const
+{
+ auto n = node->maybeGetAttr("derivationAttrPath");
+ if (!n)
+ return std::nullopt;
+ return AttrPath::fromStrings(node->root->state, n->getListOfStrings());
+}
+
+std::shared_ptr Leaf::derivation(const ref & outputs) const
+{
+ auto path = derivationAttrPath();
+ if (!path) {
+ auto n = node->maybeGetAttr("derivation");
+ if (n)
+ warn(
+ "Flake output '%s' has a schema that uses the deprecated 'derivation' attribute instead of 'derivationAttrPath'. "
+ "Please update the schema to use 'derivationAttrPath' instead. "
+ "You may want to upgrade to version 0.3.0 or higher of https://github.com/DeterminateSystems/flake-schemas.",
+ node->getAttrPathStr());
+ return n;
+ }
+ auto drv = getOutput(outputs)->findAlongAttrPath(*path);
+ if (!drv)
+ throw Error(
+ "flake output '%s' does not have a derivation attribute '%s'",
+ node->getAttrPathStr(),
+ path->to_string(node->root->state));
+ return *drv;
+}
+
+bool Leaf::isFlakeCheck() const
+{
+ auto isFlakeCheck = node->maybeGetAttr("isFlakeCheck");
+ return isFlakeCheck && isFlakeCheck->getBool();
+}
+
+std::optional getOutputInfo(ref inventory, AttrPath attrPath)
+{
+ if (attrPath.empty())
+ return std::nullopt;
+
+ auto outputName = attrPath.front();
+
+ auto schemaInfo = inventory->maybeGetAttr(outputName);
+ if (!schemaInfo)
+ return std::nullopt;
+
+ auto node = schemaInfo->maybeGetAttr("output");
+ if (!node)
+ return std::nullopt;
+
+ auto pathLeft = std::span(attrPath).subspan(1);
+
+ while (!pathLeft.empty()) {
+ auto children = node->maybeGetAttr("children");
+ if (!children)
+ break;
+ auto attr = pathLeft.front();
+ node = children->maybeGetAttr(attr);
+ if (!node)
+ return std::nullopt;
+ pathLeft = pathLeft.subspan(1);
+ }
+
+ return OutputInfo{
+ .schemaInfo = ref(schemaInfo),
+ .nodeInfo = ref(node),
+ .leafAttrPath = AttrPath(pathLeft.begin(), pathLeft.end()),
+ };
+}
+
+Schemas getSchemas(ref inventory)
+{
+ auto & state(inventory->root->state);
+
+ Schemas schemas;
+
+ for (auto & schemaName : inventory->getAttrs()) {
+ auto schema = inventory->getAttr(schemaName);
+
+ SchemaInfo schemaInfo;
+
+ if (auto roles = schema->maybeGetAttr("roles")) {
+ for (auto & roleName : roles->getAttrs()) {
+ schemaInfo.roles.insert(std::string(state.symbols[roleName]));
+ }
+ }
+
+ if (auto appendSystem = schema->maybeGetAttr("appendSystem"))
+ schemaInfo.appendSystem = appendSystem->getBool();
+
+ if (auto defaultAttrPath = schema->maybeGetAttr("defaultAttrPath")) {
+ AttrPath attrPath;
+ for (auto & s : defaultAttrPath->getListOfStrings())
+ attrPath.push_back(state.symbols.create(s));
+ schemaInfo.defaultAttrPath = std::move(attrPath);
+ }
+
+ schemas.insert_or_assign(std::string(state.symbols[schemaName]), std::move(schemaInfo));
+ }
+
+ return schemas;
+}
+
+} // namespace nix::flake_schemas
+
+namespace nix {
+
+MixFlakeSchemas::MixFlakeSchemas()
+{
+ addFlag(
+ {.longName = "default-flake-schemas",
+ .description = "The URL of the flake providing default flake schema definitions.",
+ .labels = {"flake-ref"},
+ .handler = {&defaultFlakeSchemas},
+ .completer = {[&](AddCompletions & completions, size_t, std::string_view prefix) {
+ completeFlakeRef(completions, getStore(), prefix);
+ }}});
+}
+
+std::optional MixFlakeSchemas::getDefaultFlakeSchemas()
+{
+ if (!defaultFlakeSchemas)
+ return std::nullopt;
+ else
+ return parseFlakeRef(fetchSettings, *defaultFlakeSchemas, absPath(getCommandBaseDir()));
+}
+
+} // namespace nix
diff --git a/src/libcmd/include/nix/cmd/command.hh b/src/libcmd/include/nix/cmd/command.hh
index d1b528e2477c..ec2e0d9add4c 100644
--- a/src/libcmd/include/nix/cmd/command.hh
+++ b/src/libcmd/include/nix/cmd/command.hh
@@ -132,7 +132,16 @@ struct MixFlakeOptions : virtual Args, EvalCommand
}
};
-struct SourceExprCommand : virtual Args, MixFlakeOptions
+struct MixFlakeSchemas : virtual Args, virtual StoreCommand
+{
+ std::optional defaultFlakeSchemas;
+
+ MixFlakeSchemas();
+
+ std::optional getDefaultFlakeSchemas();
+};
+
+struct SourceExprCommand : virtual Args, MixFlakeOptions, MixFlakeSchemas
{
std::optional file;
std::optional expr;
@@ -143,9 +152,13 @@ struct SourceExprCommand : virtual Args, MixFlakeOptions
ref parseInstallable(ref store, const std::string & installable);
- virtual Strings getDefaultFlakeAttrPaths();
-
- virtual Strings getDefaultFlakeAttrPathPrefixes();
+ /**
+ * Return a set of "roles" that this command implements
+ * (e.g. `nix-build` or `nix-develop`). This is used by flake
+ * schemas to determine which flake outputs are used as default
+ * attrpath prefixes.
+ */
+ virtual StringSet getRoles();
/**
* Complete an installable from the given prefix.
@@ -214,6 +227,8 @@ struct InstallableCommand : virtual Args, SourceExprCommand
{
InstallableCommand();
+ virtual void preRun(ref store);
+
virtual void run(ref store, ref installable) = 0;
void run(ref store) override;
@@ -372,8 +387,7 @@ void completeFlakeRefWithFragment(
AddCompletions & completions,
ref evalState,
flake::LockFlags lockFlags,
- Strings attrPathPrefixes,
- const Strings & defaultFlakeAttrPaths,
+ const StringSet & roles,
std::string_view prefix);
std::string showVersions(const StringSet & versions);
diff --git a/src/libcmd/include/nix/cmd/common-eval-args.hh b/src/libcmd/include/nix/cmd/common-eval-args.hh
index 67cb0714827f..4f9ebb83df53 100644
--- a/src/libcmd/include/nix/cmd/common-eval-args.hh
+++ b/src/libcmd/include/nix/cmd/common-eval-args.hh
@@ -25,9 +25,6 @@ namespace flake {
struct Settings;
}
-/**
- * @todo Get rid of global settings variables
- */
extern fetchers::Settings fetchSettings;
/**
diff --git a/src/libcmd/include/nix/cmd/flake-schemas.hh b/src/libcmd/include/nix/cmd/flake-schemas.hh
new file mode 100644
index 000000000000..c1ceefdc35aa
--- /dev/null
+++ b/src/libcmd/include/nix/cmd/flake-schemas.hh
@@ -0,0 +1,93 @@
+#pragma once
+
+#include "nix/expr/eval-cache.hh"
+#include "nix/flake/flake.hh"
+#include "nix/cmd/command.hh"
+
+namespace nix::flake_schemas {
+
+using namespace eval_cache;
+
+ref call(
+ EvalState & state,
+ std::shared_ptr lockedFlake,
+ std::optional defaultSchemasFlake,
+ bool allowEvalCache = true);
+
+void forEachOutput(
+ ref inventory,
+ std::function output, const std::string & doc, bool isLast)> f);
+
+/**
+ * A convenience wrapper around `AttrCursor` for nodes in the `inventory` tree returned by call-flake-schemas.nix.
+ */
+struct Node
+{
+ const ref node;
+
+ Node(const ref & node)
+ : node(node)
+ {
+ }
+
+ /**
+ * Return the `forSystems` attribute. This can be null, which
+ * means "all systems".
+ */
+ std::optional> forSystems() const;
+
+ /**
+ * Return the actual output corresponding to this info node.
+ */
+ ref getOutput(const ref & outputs) const;
+};
+
+struct Leaf : Node
+{
+ using Node::Node;
+
+ std::optional what() const;
+
+ std::optional shortDescription() const;
+
+ std::optional derivationAttrPath() const;
+
+ /**
+ * Return the attribute corresponding to `derivationAttrPath`, if set.
+ */
+ std::shared_ptr derivation(const ref & outputs) const;
+
+ bool isFlakeCheck() const;
+};
+
+typedef std::function attr, bool isLast)> ForEachChild;
+
+void visit(
+ std::optional system,
+ ref node,
+ std::function visitLeaf,
+ std::function)> visitNonLeaf,
+ std::function node, const std::vector & systems)> visitFiltered);
+
+struct OutputInfo
+{
+ ref schemaInfo;
+ ref nodeInfo;
+ AttrPath leafAttrPath;
+};
+
+std::optional getOutputInfo(ref inventory, AttrPath attrPath);
+
+struct SchemaInfo
+{
+ std::string doc;
+ StringSet roles;
+ bool appendSystem = false;
+ std::optional defaultAttrPath;
+};
+
+using Schemas = std::map;
+
+Schemas getSchemas(ref root);
+
+} // namespace nix::flake_schemas
diff --git a/src/libcmd/include/nix/cmd/installable-flake.hh b/src/libcmd/include/nix/cmd/installable-flake.hh
index 9f449ad48f2e..3acce913dcb7 100644
--- a/src/libcmd/include/nix/cmd/installable-flake.hh
+++ b/src/libcmd/include/nix/cmd/installable-flake.hh
@@ -36,11 +36,14 @@ struct ExtraPathInfoFlake : ExtraPathInfoValue
struct InstallableFlake : InstallableValue
{
FlakeRef flakeRef;
- Strings attrPaths;
- Strings prefixes;
+ std::string fragment;
+ AttrPath parsedFragment;
+ StringSet roles;
ExtendedOutputsSpec extendedOutputsSpec;
const flake::LockFlags & lockFlags;
mutable std::shared_ptr _lockedFlake;
+ bool useEvalCache = true;
+ std::optional defaultFlakeSchemas;
InstallableFlake(
SourceExprCommand * cmd,
@@ -48,17 +51,15 @@ struct InstallableFlake : InstallableValue
FlakeRef && flakeRef,
std::string_view fragment,
ExtendedOutputsSpec extendedOutputsSpec,
- Strings attrPaths,
- Strings prefixes,
- const flake::LockFlags & lockFlags);
+ StringSet roles,
+ const flake::LockFlags & lockFlags,
+ std::optional defaultFlakeSchemas);
std::string what() const override
{
- return flakeRef.to_string() + "#" + *attrPaths.begin();
+ return flakeRef.to_string() + "#" + fragment;
}
- std::vector getActualAttrPaths();
-
DerivedPathsWithInfo toDerivedPaths() override;
std::pair toValue(EvalState & state) override;
@@ -67,11 +68,23 @@ struct InstallableFlake : InstallableValue
* Get a cursor to every attrpath in getActualAttrPaths() that
* exists. However if none exists, throw an exception.
*/
- std::vector> getCursors(EvalState & state) override;
+ std::vector> getCursors(EvalState & state, bool useDefaultAttrPath) override;
+
+ void getCompletions(const std::string & flakeRefS, AddCompletions & completions);
ref getLockedFlake() const;
FlakeRef nixpkgsFlakeRef() const;
+
+ std::shared_ptr makeProvenance(std::string_view attrPath) const;
+
+ ref openEvalCache() const;
+
+private:
+
+ mutable std::shared_ptr _evalCache;
+
+ std::vector getAttrPaths(bool useDefaultAttrPath, ref inventory);
};
/**
diff --git a/src/libcmd/include/nix/cmd/installable-value.hh b/src/libcmd/include/nix/cmd/installable-value.hh
index 27a1fb9815d4..09178c96c972 100644
--- a/src/libcmd/include/nix/cmd/installable-value.hh
+++ b/src/libcmd/include/nix/cmd/installable-value.hh
@@ -93,7 +93,7 @@ struct InstallableValue : Installable
* However if none exists, throw exception instead of returning
* empty vector.
*/
- virtual std::vector> getCursors(EvalState & state);
+ virtual std::vector> getCursors(EvalState & state, bool useDefaultAttrPath = true);
/**
* Get the first and most preferred cursor this Installable could
diff --git a/src/libcmd/include/nix/cmd/installables.hh b/src/libcmd/include/nix/cmd/installables.hh
index 530334e037b7..2ea35261c7fa 100644
--- a/src/libcmd/include/nix/cmd/installables.hh
+++ b/src/libcmd/include/nix/cmd/installables.hh
@@ -96,6 +96,22 @@ typedef std::vector DerivedPathsWithInfo;
struct Installable;
+struct InstallableWithBuildResult
+{
+ ref installable;
+
+ using Success = BuiltPathWithResult;
+
+ using Failure = BuildResult; // must be a `BuildResult::Failure`
+
+ std::variant result;
+
+ /**
+ * Throw an exception if this represents a failure, otherwise returns a `BuiltPathWithResult`.
+ */
+ const BuiltPathWithResult & getSuccess() const;
+};
+
/**
* Shorthand, for less typing and helping us keep the choice of
* collection in sync.
@@ -160,13 +176,15 @@ struct Installable
const Installables & installables,
BuildMode bMode = bmNormal);
- static std::vector, BuiltPathWithResult>> build2(
+ static std::vector build2(
ref evalStore,
ref store,
Realise mode,
const Installables & installables,
BuildMode bMode = bmNormal);
+ static void throwBuildErrors(std::vector & buildResults, const Store & store);
+
static std::set toStorePathSet(
ref evalStore, ref store, Realise mode, OperateOn operateOn, const Installables & installables);
diff --git a/src/libcmd/include/nix/cmd/meson.build b/src/libcmd/include/nix/cmd/meson.build
index 119d0814b9f1..7ab3e596ae40 100644
--- a/src/libcmd/include/nix/cmd/meson.build
+++ b/src/libcmd/include/nix/cmd/meson.build
@@ -9,6 +9,7 @@ headers = files(
'common-eval-args.hh',
'compatibility-settings.hh',
'editor-for.hh',
+ 'flake-schemas.hh',
'installable-attr-path.hh',
'installable-derived-path.hh',
'installable-flake.hh',
diff --git a/src/libcmd/installable-attr-path.cc b/src/libcmd/installable-attr-path.cc
index 28c3db3fc79a..3a80aa384de4 100644
--- a/src/libcmd/installable-attr-path.cc
+++ b/src/libcmd/installable-attr-path.cc
@@ -89,7 +89,8 @@ DerivedPathsWithInfo InstallableAttrPath::toDerivedPaths()
}
DerivedPathsWithInfo res;
- for (auto & [drvPath, outputs] : byDrvPath)
+ for (auto & [drvPath, outputs] : byDrvPath) {
+ state->waitForPath(drvPath);
res.push_back({
.path =
DerivedPath::Built{
@@ -102,6 +103,7 @@ DerivedPathsWithInfo InstallableAttrPath::toDerivedPaths()
so we can fill in this info. */
}),
});
+ }
return res;
}
diff --git a/src/libcmd/installable-flake.cc b/src/libcmd/installable-flake.cc
index 11bbdbf8429d..84b6ccfa9d07 100644
--- a/src/libcmd/installable-flake.cc
+++ b/src/libcmd/installable-flake.cc
@@ -17,6 +17,8 @@
#include "nix/util/url.hh"
#include "nix/fetchers/registry.hh"
#include "nix/store/build-result.hh"
+#include "nix/flake/provenance.hh"
+#include "nix/cmd/flake-schemas.hh"
#include
#include
@@ -25,32 +27,14 @@
namespace nix {
-std::vector InstallableFlake::getActualAttrPaths()
-{
- std::vector res;
- if (attrPaths.size() == 1 && attrPaths.front().starts_with(".")) {
- attrPaths.front().erase(0, 1);
- res.push_back(attrPaths.front());
- return res;
- }
-
- for (auto & prefix : prefixes)
- res.push_back(prefix + *attrPaths.begin());
-
- for (auto & s : attrPaths)
- res.push_back(s);
-
- return res;
-}
-
-static std::string showAttrPaths(const std::vector & paths)
+static std::string showAttrPaths(EvalState & state, const std::vector & paths)
{
std::string s;
for (const auto & [n, i] : enumerate(paths)) {
if (n > 0)
s += n + 1 == paths.size() ? " or " : ", ";
s += '\'';
- s += i;
+ s += i.to_string(state);
s += '\'';
}
return s;
@@ -62,15 +46,17 @@ InstallableFlake::InstallableFlake(
FlakeRef && flakeRef,
std::string_view fragment,
ExtendedOutputsSpec extendedOutputsSpec,
- Strings attrPaths,
- Strings prefixes,
- const flake::LockFlags & lockFlags)
+ StringSet roles,
+ const flake::LockFlags & lockFlags,
+ std::optional defaultFlakeSchemas)
: InstallableValue(state)
, flakeRef(flakeRef)
- , attrPaths(fragment == "" ? attrPaths : Strings{(std::string) fragment})
- , prefixes(fragment == "" ? Strings{} : prefixes)
+ , fragment(fragment)
+ , parsedFragment(AttrPath::parse(*state, fragment))
+ , roles(roles)
, extendedOutputsSpec(std::move(extendedOutputsSpec))
, lockFlags(lockFlags)
+ , defaultFlakeSchemas(defaultFlakeSchemas)
{
if (cmd && cmd->getAutoArgs(*state)->size())
throw UsageError("'--arg' and '--argstr' are incompatible with flakes");
@@ -84,6 +70,8 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
auto attrPath = attr->getAttrPathStr();
+ PushProvenance pushedProvenance(*state, makeProvenance(attrPath));
+
if (!attr->isDerivation()) {
// FIXME: use eval cache?
@@ -102,6 +90,7 @@ DerivedPathsWithInfo InstallableFlake::toDerivedPaths()
}
auto drvPath = attr->forceDerivation();
+ state->waitForPath(drvPath);
std::optional priority;
@@ -157,34 +146,166 @@ std::pair InstallableFlake::toValue(EvalState & state)
return {&getCursor(state)->forceValue(), noPos};
}
-std::vector> InstallableFlake::getCursors(EvalState & state)
+std::vector InstallableFlake::getAttrPaths(bool useDefaultAttrPath, ref inventory)
{
- auto evalCache = openEvalCache(state, getLockedFlake());
+ if (fragment.starts_with("."))
+ return {AttrPath::parse(*state, fragment.substr(1))};
+
+ std::vector attrPaths;
+
+ auto schemas = flake_schemas::getSchemas(inventory);
+
+ // FIXME: Ugly hack to preserve the historical precedence
+ // between outputs. We should add a way for schemas to declare
+ // priorities.
+ std::vector schemasSorted;
+ std::set schemasSeen;
+ auto doSchema = [&](const std::string & schema) {
+ if (schemas.contains(schema)) {
+ schemasSorted.push_back(schema);
+ schemasSeen.insert(schema);
+ }
+ };
+ doSchema("apps");
+ doSchema("devShells");
+ doSchema("packages");
+ doSchema("legacyPackages");
+ for (auto & schema : schemas)
+ if (!schemasSeen.contains(schema.first))
+ schemasSorted.push_back(schema.first);
+
+ for (auto & role : roles) {
+ for (auto & schemaName : schemasSorted) {
+ auto & schema = schemas.find(schemaName)->second;
+ if (schema.roles.contains(role)) {
+ AttrPath attrPath{state->symbols.create(schemaName)};
+ if (schema.appendSystem)
+ attrPath.push_back(state->symbols.create(settings.thisSystem.get()));
+
+ if (useDefaultAttrPath && parsedFragment.empty()) {
+ if (schema.defaultAttrPath) {
+ auto attrPath2{attrPath};
+ for (auto & x : *schema.defaultAttrPath)
+ attrPath2.push_back(x);
+ attrPaths.push_back(attrPath2);
+ }
+ } else {
+ auto attrPath2{attrPath};
+ for (auto & x : parsedFragment)
+ attrPath2.push_back(x);
+ attrPaths.push_back(attrPath2);
+ }
+ }
+ }
+ }
+
+ if (!parsedFragment.empty())
+ attrPaths.push_back(parsedFragment);
+
+ // FIXME: compatibility hack to get `nix repl` to return all
+ // outputs by default.
+ if (parsedFragment.empty() && roles.contains("nix-repl"))
+ attrPaths.push_back({});
+
+ return attrPaths;
+}
+
+std::vector> InstallableFlake::getCursors(EvalState & state, bool useDefaultAttrPath)
+{
+ auto cache = openEvalCache();
+
+ auto inventory = cache->getRoot()->getAttr("inventory");
+ auto outputs = cache->getRoot()->getAttr("outputs");
- auto root = evalCache->getRoot();
+ auto attrPaths = getAttrPaths(useDefaultAttrPath, inventory);
+
+ if (attrPaths.empty())
+ throw Error(
+ "Flake '%s' does not have any schema that provides a default output for the role(s) %s.",
+ flakeRef,
+ concatStringsSep(", ", roles));
std::vector> res;
Suggestions suggestions;
- auto attrPaths = getActualAttrPaths();
for (auto & attrPath : attrPaths) {
- debug("trying flake output attribute '%s'", attrPath);
+ debug("trying flake output attribute '%s'", attrPath.to_string(state));
+
+ PushProvenance pushedProvenance(state, makeProvenance(attrPath.to_string(state)));
+
+#if 0
+ auto outputInfo = flake_schemas::getOutputInfo(inventory, attrPath);
+
+ if (outputInfo && outputInfo->leafAttrPath.empty()) {
+ if (auto drv = outputInfo->nodeInfo->maybeGetAttr("derivation")) {
+ res.push_back(ref(drv));
+ continue;
+ }
+ }
+#endif
- auto attr = root->findAlongAttrPath(AttrPath::parse(state, attrPath));
- if (attr) {
+ auto attr = outputs->findAlongAttrPath(attrPath);
+ if (attr)
res.push_back(ref(*attr));
- } else {
+ else
suggestions += attr.getSuggestions();
- }
}
if (res.size() == 0)
- throw Error(suggestions, "flake '%s' does not provide attribute %s", flakeRef, showAttrPaths(attrPaths));
+ throw Error(suggestions, "flake '%s' does not provide attribute %s", flakeRef, showAttrPaths(state, attrPaths));
return res;
}
+void InstallableFlake::getCompletions(const std::string & flakeRefS, AddCompletions & completions)
+{
+ auto cache = openEvalCache();
+
+ auto inventory = cache->getRoot()->getAttr("inventory");
+ auto outputs = cache->getRoot()->getAttr("outputs");
+
+ if (fragment.ends_with(".") || fragment.empty())
+ // Represent that we're looking for attributes starting with the empty prefix (i.e. all attributes inside the
+ // parent.
+ parsedFragment.push_back(state->symbols.create(""));
+
+ auto attrPaths = getAttrPaths(true, inventory);
+
+ if (fragment.empty())
+ // Return all top-level flake outputs.
+ attrPaths.push_back(AttrPath{state->symbols.create("")});
+
+ auto lastAttr = fragment.ends_with(".") || parsedFragment.empty() ? std::string_view("")
+ : state->symbols[parsedFragment.back()];
+ std::string prefix;
+ if (auto dot = fragment.rfind('.'); dot != std::string::npos)
+ prefix = fragment.substr(0, dot);
+ if (fragment.starts_with(".") && !prefix.starts_with("."))
+ prefix = "." + prefix;
+
+ for (auto attrPath : attrPaths) {
+ if (attrPath.empty())
+ attrPath.push_back(state->symbols.create(""));
+
+ auto attrPathParent{attrPath};
+ attrPathParent.pop_back();
+
+ auto attr = outputs->findAlongAttrPath(attrPathParent);
+ if (!attr)
+ continue;
+
+ for (auto & childName : (*attr)->getAttrs()) {
+ if (hasPrefix(state->symbols[childName], lastAttr)) {
+ auto attrPathChild = (*attr)->getAttrPath(childName);
+ completions.add(
+ flakeRefS + "#" + prefix + (prefix.empty() || prefix.ends_with(".") ? "" : ".")
+ + state->symbols[childName]);
+ }
+ }
+ }
+}
+
ref InstallableFlake::getLockedFlake() const
{
if (!_lockedFlake) {
@@ -197,6 +318,14 @@ ref InstallableFlake::getLockedFlake() const
return ref(_lockedFlake);
}
+ref InstallableFlake::openEvalCache() const
+{
+ if (!_evalCache) {
+ _evalCache = flake_schemas::call(*state, getLockedFlake(), defaultFlakeSchemas, useEvalCache);
+ }
+ return ref(_evalCache);
+}
+
FlakeRef InstallableFlake::nixpkgsFlakeRef() const
{
auto lockedFlake = getLockedFlake();
@@ -211,4 +340,12 @@ FlakeRef InstallableFlake::nixpkgsFlakeRef() const
return defaultNixpkgsFlakeRef();
}
+std::shared_ptr InstallableFlake::makeProvenance(std::string_view attrPath) const
+{
+ auto provenance = getLockedFlake()->flake.provenance;
+ if (!provenance)
+ return nullptr;
+ return std::make_shared(provenance, std::string(attrPath), evalSettings.pureEval);
+}
+
} // namespace nix
diff --git a/src/libcmd/installable-value.cc b/src/libcmd/installable-value.cc
index 3a167af3db49..6c2fd60efd8e 100644
--- a/src/libcmd/installable-value.cc
+++ b/src/libcmd/installable-value.cc
@@ -4,7 +4,7 @@
namespace nix {
-std::vector> InstallableValue::getCursors(EvalState & state)
+std::vector> InstallableValue::getCursors(EvalState & state, bool useDefaultAttrPath)
{
auto evalCache =
std::make_shared(std::nullopt, state, [&]() { return toValue(state).first; });
@@ -15,7 +15,7 @@ ref InstallableValue::getCursor(EvalState & state)
{
/* Although getCursors should return at least one element, in case it doesn't,
bound check to avoid an undefined behavior for vector[0] */
- return getCursors(state).at(0);
+ return getCursors(state, true).at(0);
}
static UsageError nonValueInstallable(Installable & installable)
@@ -55,7 +55,7 @@ InstallableValue::trySinglePathToDerivedPaths(Value & v, const PosIdx pos, std::
else if (v.type() == nString) {
return {{
- .path = DerivedPath::fromSingle(state->coerceToSingleDerivedPath(pos, v, errorCtx)),
+ .path = DerivedPath::fromSingle(state->devirtualize(state->coerceToSingleDerivedPath(pos, v, errorCtx))),
.info = make_ref(),
}};
}
diff --git a/src/libcmd/installables.cc b/src/libcmd/installables.cc
index 7e3861e2f1d3..740e53d74af4 100644
--- a/src/libcmd/installables.cc
+++ b/src/libcmd/installables.cc
@@ -21,6 +21,7 @@
#include "nix/util/url.hh"
#include "nix/fetchers/registry.hh"
#include "nix/store/build-result.hh"
+#include "nix/util/exit.hh"
#include
#include
@@ -233,19 +234,9 @@ MixReadOnlyOption::MixReadOnlyOption()
});
}
-Strings SourceExprCommand::getDefaultFlakeAttrPaths()
+StringSet SourceExprCommand::getRoles()
{
- return {"packages." + settings.thisSystem.get() + ".default", "defaultPackage." + settings.thisSystem.get()};
-}
-
-Strings SourceExprCommand::getDefaultFlakeAttrPathPrefixes()
-{
- return {// As a convenience, look for the attribute in
- // 'outputs.packages'.
- "packages." + settings.thisSystem.get() + ".",
- // As a temporary hack until Nixpkgs is properly converted
- // to provide a clean 'packages' set, look in 'legacyPackages'.
- "legacyPackages." + settings.thisSystem.get() + "."};
+ return {"nix-build"};
}
Args::CompleterClosure SourceExprCommand::getCompleteInstallable()
@@ -299,13 +290,7 @@ void SourceExprCommand::completeInstallable(AddCompletions & completions, std::s
}
}
} else {
- completeFlakeRefWithFragment(
- completions,
- getEvalState(),
- lockFlags,
- getDefaultFlakeAttrPathPrefixes(),
- getDefaultFlakeAttrPaths(),
- prefix);
+ completeFlakeRefWithFragment(completions, getEvalState(), lockFlags, getRoles(), prefix);
}
} catch (EvalError &) {
// Don't want eval errors to mess-up with the completion engine, so let's just swallow them
@@ -316,91 +301,37 @@ void completeFlakeRefWithFragment(
AddCompletions & completions,
ref evalState,
flake::LockFlags lockFlags,
- Strings attrPathPrefixes,
- const Strings & defaultFlakeAttrPaths,
+ const StringSet & roles,
std::string_view prefix)
-{
- /* Look for flake output attributes that match the
- prefix. */
- try {
- auto hash = prefix.find('#');
- if (hash == std::string::npos) {
- completeFlakeRef(completions, evalState->store, prefix);
- } else {
- completions.setType(AddCompletions::Type::Attrs);
-
- auto fragment = prefix.substr(hash + 1);
- std::string prefixRoot = "";
- if (fragment.starts_with(".")) {
- fragment = fragment.substr(1);
- prefixRoot = ".";
- }
- auto flakeRefS = std::string(prefix.substr(0, hash));
-
- // TODO: ideally this would use the command base directory instead of assuming ".".
- auto flakeRef =
- parseFlakeRef(fetchSettings, expandTilde(flakeRefS), std::filesystem::current_path().string());
-
- auto evalCache = openEvalCache(
- *evalState, make_ref(lockFlake(flakeSettings, *evalState, flakeRef, lockFlags)));
-
- auto root = evalCache->getRoot();
-
- if (prefixRoot == ".") {
- attrPathPrefixes.clear();
- }
- /* Complete 'fragment' relative to all the
- attrpath prefixes as well as the root of the
- flake. */
- attrPathPrefixes.push_back("");
-
- for (auto & attrPathPrefixS : attrPathPrefixes) {
- auto attrPathPrefix = AttrPath::parse(*evalState, attrPathPrefixS);
- auto attrPathS = attrPathPrefixS + std::string(fragment);
- auto attrPath = AttrPath::parse(*evalState, attrPathS);
-
- std::string lastAttr;
- if (!attrPath.empty() && !hasSuffix(attrPathS, ".")) {
- lastAttr = evalState->symbols[attrPath.back()];
- attrPath.pop_back();
- }
+try {
+ auto hash = prefix.find('#');
+ if (hash == std::string::npos) {
+ completeFlakeRef(completions, evalState->store, prefix);
+ return;
+ }
- auto attr = root->findAlongAttrPath(attrPath);
- if (!attr)
- continue;
+ completions.setType(AddCompletions::Type::Attrs);
- for (auto & attr2 : (*attr)->getAttrs()) {
- if (hasPrefix(evalState->symbols[attr2], lastAttr)) {
- auto attrPath2 = (*attr)->getAttrPath(attr2);
- /* Strip the attrpath prefix. */
- attrPath2.erase(attrPath2.begin(), attrPath2.begin() + attrPathPrefix.size());
- // FIXME: handle names with dots
- completions.add(flakeRefS + "#" + prefixRoot + attrPath2.to_string(*evalState));
- }
- }
- }
+ auto fragment = prefix.substr(hash + 1);
+ auto flakeRefS = std::string(prefix.substr(0, hash));
- /* And add an empty completion for the default
- attrpaths. */
- if (fragment.empty()) {
- for (auto & attrPath : defaultFlakeAttrPaths) {
- auto attr = root->findAlongAttrPath(AttrPath::parse(*evalState, attrPath));
- if (!attr)
- continue;
- completions.add(flakeRefS + "#" + prefixRoot);
- }
- }
- }
- } catch (Error & e) {
- warn(e.msg());
- }
+ InstallableFlake{
+ nullptr,
+ evalState,
+ // TODO: ideally this would use the command base directory instead of assuming ".".
+ parseFlakeRef(fetchSettings, expandTilde(flakeRefS), std::filesystem::current_path().string()),
+ fragment,
+ ExtendedOutputsSpec::Default{}, // FIXME: could be that we're completing the outputs spec...
+ roles,
+ lockFlags,
+ {}}
+ .getCompletions(flakeRefS, completions);
+} catch (Error & e) {
+ warn(e.msg());
}
void completeFlakeRef(AddCompletions & completions, ref store, std::string_view prefix)
{
- if (!experimentalFeatureSettings.isEnabled(Xp::Flakes))
- return;
-
if (prefix == "")
completions.add(".");
@@ -510,9 +441,9 @@ Installables SourceExprCommand::parseInstallables(ref store, std::vector<
std::move(flakeRef),
fragment,
std::move(extendedOutputsSpec),
- getDefaultFlakeAttrPaths(),
- getDefaultFlakeAttrPathPrefixes(),
- lockFlags));
+ getRoles(),
+ lockFlags,
+ getDefaultFlakeSchemas()));
continue;
} catch (...) {
ex = std::current_exception();
@@ -554,46 +485,69 @@ static SingleBuiltPath getBuiltPath(ref evalStore, ref store, cons
b.raw());
}
-std::vector Installable::build(
- ref evalStore, ref store, Realise mode, const Installables & installables, BuildMode bMode)
+const BuiltPathWithResult & InstallableWithBuildResult::getSuccess() const
{
- std::vector res;
- for (auto & [_, builtPathWithResult] : build2(evalStore, store, mode, installables, bMode))
- res.push_back(builtPathWithResult);
- return res;
+ if (auto * failure = std::get_if(&result)) {
+ auto failure2 = failure->tryGetFailure();
+ assert(failure2);
+ failure2->rethrow();
+ } else
+ return *std::get_if(&result);
}
-static void throwBuildErrors(std::vector & buildResults, const Store & store)
+void Installable::throwBuildErrors(std::vector & buildResults, const Store & store)
{
- std::vector> failed;
for (auto & buildResult : buildResults) {
- if (auto * failure = buildResult.tryGetFailure()) {
- failed.push_back({&buildResult, failure});
- }
- }
+ if (std::get_if(&buildResult.result)) {
+ // Report success first.
+ for (auto & buildResult : buildResults) {
+ if (std::get_if(&buildResult.result))
+ notice("✅ " ANSI_BOLD "%s" ANSI_NORMAL, buildResult.installable->what());
+ }
- auto failedResult = failed.begin();
- if (failedResult != failed.end()) {
- if (failed.size() == 1) {
- failedResult->second->rethrow();
- } else {
- StringSet failedPaths;
- for (; failedResult != failed.end(); failedResult++) {
- if (!failedResult->second->errorMsg.empty()) {
- logError(
- ErrorInfo{
- .level = lvlError,
- .msg = failedResult->second->errorMsg,
- });
+ // Then cancelled builds.
+ for (auto & buildResult : buildResults) {
+ if (auto failure = std::get_if(&buildResult.result)) {
+ if (failure->isCancelled())
+ notice(
+ "❓ " ANSI_BOLD "%s" ANSI_NORMAL ANSI_FAINT " (cancelled)",
+ buildResult.installable->what());
+ }
+ }
+
+ // Then failures.
+ for (auto & buildResult : buildResults) {
+ if (auto failure = std::get_if(&buildResult.result)) {
+ if (failure->isCancelled())
+ continue;
+ auto failure2 = failure->tryGetFailure();
+ assert(failure2);
+ printError("❌ " ANSI_RED "%s" ANSI_NORMAL, buildResult.installable->what());
+ try {
+ failure2->rethrow();
+ } catch (Error & e) {
+ logError(e.info());
+ }
}
- failedPaths.insert(failedResult->first->path.to_string(store));
}
- throw Error("build of %s failed", concatStringsSep(", ", quoteStrings(failedPaths)));
+
+ throw Exit(1);
}
}
}
-std::vector, BuiltPathWithResult>> Installable::build2(
+std::vector Installable::build(
+ ref evalStore, ref store, Realise mode, const Installables & installables, BuildMode bMode)
+{
+ auto results = build2(evalStore, store, mode, installables, bMode);
+ throwBuildErrors(results, *store);
+ std::vector res;
+ for (auto & b : results)
+ res.push_back(b.getSuccess());
+ return res;
+}
+
+std::vector Installable::build2(
ref evalStore, ref store, Realise mode, const Installables & installables, BuildMode bMode)
{
if (mode == Realise::Nothing)
@@ -615,7 +569,7 @@ std::vector, BuiltPathWithResult>> Installable::build
}
}
- std::vector, BuiltPathWithResult>> res;
+ std::vector res;
switch (mode) {
@@ -630,17 +584,21 @@ std::vector, BuiltPathWithResult>> Installable::build
[&](const DerivedPath::Built & bfd) {
auto outputs = resolveDerivedPath(*store, bfd, &*evalStore);
res.push_back(
- {aux.installable,
- {.path =
- BuiltPath::Built{
- .drvPath =
- make_ref(getBuiltPath(evalStore, store, *bfd.drvPath)),
- .outputs = outputs,
- },
- .info = aux.info}});
+ {.installable = aux.installable,
+ .result = InstallableWithBuildResult::Success{
+ .path =
+ BuiltPath::Built{
+ .drvPath = make_ref(
+ getBuiltPath(evalStore, store, *bfd.drvPath)),
+ .outputs = outputs,
+ },
+ .info = aux.info}});
},
[&](const DerivedPath::Opaque & bo) {
- res.push_back({aux.installable, {.path = BuiltPath::Opaque{bo.path}, .info = aux.info}});
+ res.push_back(
+ {.installable = aux.installable,
+ .result = InstallableWithBuildResult::Success{
+ .path = BuiltPath::Opaque{bo.path}, .info = aux.info}});
},
},
path.raw());
@@ -654,9 +612,13 @@ std::vector, BuiltPathWithResult>> Installable::build
printMissing(store, pathsToBuild, lvlInfo);
auto buildResults = store->buildPathsWithResults(pathsToBuild, bMode, evalStore);
- throwBuildErrors(buildResults, *store);
for (auto & buildResult : buildResults) {
- // If we didn't throw, they must all be sucesses
+ if (buildResult.tryGetFailure()) {
+ for (auto & aux : backmap[buildResult.path]) {
+ res.push_back({.installable = aux.installable, .result = buildResult});
+ }
+ continue;
+ }
auto & success = std::get(buildResult.inner);
for (auto & aux : backmap[buildResult.path]) {
std::visit(
@@ -666,20 +628,22 @@ std::vector, BuiltPathWithResult>> Installable::build
for (auto & [outputName, realisation] : success.builtOutputs)
outputs.emplace(outputName, realisation.outPath);
res.push_back(
- {aux.installable,
- {.path =
- BuiltPath::Built{
- .drvPath =
- make_ref(getBuiltPath(evalStore, store, *bfd.drvPath)),
- .outputs = outputs,
- },
- .info = aux.info,
- .result = buildResult}});
+ {.installable = aux.installable,
+ .result = InstallableWithBuildResult::Success{
+ .path =
+ BuiltPath::Built{
+ .drvPath = make_ref(
+ getBuiltPath(evalStore, store, *bfd.drvPath)),
+ .outputs = outputs,
+ },
+ .info = aux.info,
+ .result = buildResult}});
},
[&](const DerivedPath::Opaque & bo) {
res.push_back(
- {aux.installable,
- {.path = BuiltPath::Opaque{bo.path}, .info = aux.info, .result = buildResult}});
+ {.installable = aux.installable,
+ .result = InstallableWithBuildResult::Success{
+ .path = BuiltPath::Opaque{bo.path}, .info = aux.info, .result = buildResult}});
},
},
buildResult.path.raw());
@@ -840,8 +804,11 @@ InstallableCommand::InstallableCommand()
});
}
+void InstallableCommand::preRun(ref store) {}
+
void InstallableCommand::run(ref store)
{
+ preRun(store);
auto installable = parseInstallable(store, _installable);
run(store, std::move(installable));
}
diff --git a/src/libcmd/meson.build b/src/libcmd/meson.build
index f553afa0ba17..087da84f9293 100644
--- a/src/libcmd/meson.build
+++ b/src/libcmd/meson.build
@@ -67,6 +67,7 @@ config_priv_h = configure_file(
)
subdir('nix-meson-build-support/common')
+subdir('nix-meson-build-support/generate-header')
sources = files(
'built-path.cc',
@@ -74,6 +75,7 @@ sources = files(
'command.cc',
'common-eval-args.cc',
'editor-for.cc',
+ 'flake-schemas.cc',
'installable-attr-path.cc',
'installable-derived-path.cc',
'installable-flake.cc',
@@ -86,6 +88,11 @@ sources = files(
'repl.cc',
)
+sources += [
+ gen_header.process('call-flake-schemas.nix'),
+ gen_header.process('builtin-flake-schemas.nix'),
+]
+
subdir('include/nix/cmd')
subdir('nix-meson-build-support/export-all-symbols')
@@ -99,7 +106,7 @@ this_library = library(
dependencies : deps_public + deps_private + deps_other,
include_directories : include_dirs,
link_args : linker_export_flags,
- prelink : true, # For C++ static initializers
+ prelink : prelink, # For C++ static initializers
install : true,
cpp_pch : do_pch ? [ 'pch/precompiled-headers.hh' ] : [],
)
diff --git a/src/libcmd/package.nix b/src/libcmd/package.nix
index c382f0e5760d..1d677142da1d 100644
--- a/src/libcmd/package.nix
+++ b/src/libcmd/package.nix
@@ -35,7 +35,7 @@ let
in
mkMesonLibrary (finalAttrs: {
- pname = "nix-cmd";
+ pname = "determinate-nix-cmd";
inherit version;
workDir = ./.;
@@ -49,6 +49,8 @@ mkMesonLibrary (finalAttrs: {
./include/nix/cmd/meson.build
(fileset.fileFilter (file: file.hasExt "cc") ./.)
(fileset.fileFilter (file: file.hasExt "hh") ./.)
+ ./call-flake-schemas.nix
+ ./builtin-flake-schemas.nix
];
buildInputs = [
diff --git a/src/libcmd/repl.cc b/src/libcmd/repl.cc
index 8fbb54dd30de..d8e61b5b5205 100644
--- a/src/libcmd/repl.cc
+++ b/src/libcmd/repl.cc
@@ -177,7 +177,7 @@ ReplExitStatus NixRepl::mainLoop()
if (state->debugRepl) {
debuggerNotice = " debugger";
}
- notice("Nix %1%%2%\nType :? for help.", nixVersion, debuggerNotice);
+ notice("Nix %s\nType :? for help.", version(), debuggerNotice);
}
isFirstRepl = false;
@@ -332,6 +332,7 @@ StorePath NixRepl::getDerivationPath(Value & v)
auto drvPath = packageInfo->queryDrvPath();
if (!drvPath)
throw Error("expression did not evaluate to a valid derivation (no 'drvPath' attribute)");
+ state->waitForPath(*drvPath);
if (!state->store->isValidPath(*drvPath))
throw Error("expression evaluated to invalid derivation '%s'", state->store->printStorePath(*drvPath));
return *drvPath;
diff --git a/src/libexpr-c/meson.build b/src/libexpr-c/meson.build
index c47704ce4112..df1e3c05880c 100644
--- a/src/libexpr-c/meson.build
+++ b/src/libexpr-c/meson.build
@@ -54,7 +54,7 @@ this_library = library(
dependencies : deps_public + deps_private + deps_other,
include_directories : include_dirs,
link_args : linker_export_flags,
- prelink : true, # For C++ static initializers
+ prelink : prelink, # For C++ static initializers
install : true,
)
diff --git a/src/libexpr-c/nix_api_expr.cc b/src/libexpr-c/nix_api_expr.cc
index 0dd9fa0a51d8..bfbd0a9c361f 100644
--- a/src/libexpr-c/nix_api_expr.cc
+++ b/src/libexpr-c/nix_api_expr.cc
@@ -71,6 +71,7 @@ nix_err nix_expr_eval_from_string(
nix::Expr * parsedExpr = state->state.parseExprFromString(expr, state->state.rootPath(nix::CanonPath(path)));
state->state.eval(parsedExpr, *value->value);
state->state.forceValue(*value->value, nix::noPos);
+ state->state.waitForAllPaths();
}
NIXC_CATCH_ERRS
}
@@ -82,6 +83,7 @@ nix_err nix_value_call(nix_c_context * context, EvalState * state, Value * fn, n
try {
state->state.callFunction(*fn->value, *arg->value, *value->value, nix::noPos);
state->state.forceValue(*value->value, nix::noPos);
+ state->state.waitForAllPaths();
}
NIXC_CATCH_ERRS
}
@@ -100,6 +102,7 @@ nix_err nix_value_call_multi(
try {
state->state.callFunction(*fn->value, {internal_args.data(), nargs}, *value->value, nix::noPos);
state->state.forceValue(*value->value, nix::noPos);
+ state->state.waitForAllPaths();
}
NIXC_CATCH_ERRS
}
@@ -110,6 +113,7 @@ nix_err nix_value_force(nix_c_context * context, EvalState * state, nix_value *
context->last_err_code = NIX_OK;
try {
state->state.forceValue(*value->value, nix::noPos);
+ state->state.waitForAllPaths();
}
NIXC_CATCH_ERRS
}
@@ -120,6 +124,7 @@ nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, nix_val
context->last_err_code = NIX_OK;
try {
state->state.forceValueDeep(*value->value);
+ state->state.waitForAllPaths();
}
NIXC_CATCH_ERRS
}
diff --git a/src/libexpr-c/nix_api_value.cc b/src/libexpr-c/nix_api_value.cc
index 7fd8233adec2..b6a838284eff 100644
--- a/src/libexpr-c/nix_api_value.cc
+++ b/src/libexpr-c/nix_api_value.cc
@@ -194,6 +194,8 @@ ValueType nix_get_type(nix_c_context * context, const nix_value * value)
switch (v.type()) {
case nThunk:
return NIX_TYPE_THUNK;
+ case nFailed:
+ return NIX_TYPE_FAILED;
case nInt:
return NIX_TYPE_INT;
case nFloat:
@@ -386,6 +388,7 @@ nix_value * nix_get_attr_byname(nix_c_context * context, const nix_value * value
auto attr = v.attrs()->get(s);
if (attr) {
state->state.forceValue(*attr->value, nix::noPos);
+ state->state.waitForAllPaths();
return new_nix_value(attr->value, state->state.mem);
}
nix_set_err_msg(context, NIX_ERR_KEY, "missing attribute");
diff --git a/src/libexpr-c/nix_api_value.h b/src/libexpr-c/nix_api_value.h
index 5bd45da9059d..a01bfb280599 100644
--- a/src/libexpr-c/nix_api_value.h
+++ b/src/libexpr-c/nix_api_value.h
@@ -100,7 +100,10 @@ typedef enum {
/** @brief External value from C++ plugins or C API
* @see Externals
*/
- NIX_TYPE_EXTERNAL
+ NIX_TYPE_EXTERNAL,
+ /** @brief Failed value. Contains an exception that can be rethrown.
+ */
+ NIX_TYPE_FAILED,
} ValueType;
// forward declarations
diff --git a/src/libexpr-c/package.nix b/src/libexpr-c/package.nix
index 694fbc1fe789..ec92ecce1054 100644
--- a/src/libexpr-c/package.nix
+++ b/src/libexpr-c/package.nix
@@ -15,7 +15,7 @@ let
in
mkMesonLibrary (finalAttrs: {
- pname = "nix-expr-c";
+ pname = "determinate-nix-expr-c";
inherit version;
workDir = ./.;
diff --git a/src/libexpr-test-support/include/nix/expr/tests/value/context.hh b/src/libexpr-test-support/include/nix/expr/tests/value/context.hh
index 68a0b8dea7d7..2311f3941c13 100644
--- a/src/libexpr-test-support/include/nix/expr/tests/value/context.hh
+++ b/src/libexpr-test-support/include/nix/expr/tests/value/context.hh
@@ -26,6 +26,12 @@ struct Arbitrary
static Gen arbitrary();
};
+template<>
+struct Arbitrary
+{
+ static Gen arbitrary();
+};
+
template<>
struct Arbitrary
{
diff --git a/src/libexpr-test-support/meson.build b/src/libexpr-test-support/meson.build
index df28661b7e78..0fae96b47f1e 100644
--- a/src/libexpr-test-support/meson.build
+++ b/src/libexpr-test-support/meson.build
@@ -50,7 +50,7 @@ this_library = library(
# TODO: Remove `-lrapidcheck` when https://github.com/emil-e/rapidcheck/pull/326
# is available. See also ../libutil/build.meson
link_args : linker_export_flags + [ '-lrapidcheck' ],
- prelink : true, # For C++ static initializers
+ prelink : prelink, # For C++ static initializers
install : true,
)
diff --git a/src/libexpr-test-support/package.nix b/src/libexpr-test-support/package.nix
index 5cb4adaa8c46..1879a5716082 100644
--- a/src/libexpr-test-support/package.nix
+++ b/src/libexpr-test-support/package.nix
@@ -18,7 +18,7 @@ let
in
mkMesonLibrary (finalAttrs: {
- pname = "nix-util-test-support";
+ pname = "determinate-nix-util-test-support";
inherit version;
workDir = ./.;
diff --git a/src/libexpr-test-support/tests/value/context.cc b/src/libexpr-test-support/tests/value/context.cc
index d6036601a948..8ce84fb51f54 100644
--- a/src/libexpr-test-support/tests/value/context.cc
+++ b/src/libexpr-test-support/tests/value/context.cc
@@ -16,6 +16,15 @@ Gen Arbitrary::arb
});
}
+Gen Arbitrary::arbitrary()
+{
+ return gen::map(gen::arbitrary(), [](StorePath storePath) {
+ return NixStringContextElem::Path{
+ .storePath = storePath,
+ };
+ });
+}
+
Gen Arbitrary::arbitrary()
{
return gen::mapcat(
@@ -31,6 +40,8 @@ Gen Arbitrary::arbitrary()
case 2:
return gen::map(
gen::arbitrary(), [](NixStringContextElem a) { return a; });
+ case 3:
+ return gen::map(gen::arbitrary(), [](NixStringContextElem a) { return a; });
default:
assert(false);
}
diff --git a/src/libexpr-tests/value/value.cc b/src/libexpr-tests/value/value.cc
index 420db0f31b17..bd8f0da71213 100644
--- a/src/libexpr-tests/value/value.cc
+++ b/src/libexpr-tests/value/value.cc
@@ -13,7 +13,6 @@ TEST_F(ValueTest, unsetValue)
{
Value unsetValue;
ASSERT_EQ(false, unsetValue.isValid());
- ASSERT_EQ(nThunk, unsetValue.type(true));
ASSERT_DEATH(unsetValue.type(), "");
}
diff --git a/src/libexpr/attr-path.cc b/src/libexpr/attr-path.cc
index 575a135422ab..c8b800245881 100644
--- a/src/libexpr/attr-path.cc
+++ b/src/libexpr/attr-path.cc
@@ -39,6 +39,14 @@ AttrPath AttrPath::parse(EvalState & state, std::string_view s)
return res;
}
+AttrPath AttrPath::fromStrings(EvalState & state, const std::vector & attrNames)
+{
+ AttrPath res;
+ for (auto & attrName : attrNames)
+ res.push_back(state.symbols.create(attrName));
+ return res;
+}
+
std::string AttrPath::to_string(EvalState & state) const
{
return dropEmptyInitThenConcatStringsSep(".", state.symbols.resolve({*this}));
diff --git a/src/libexpr/eval-cache.cc b/src/libexpr/eval-cache.cc
index 43f10da6eac9..0d6bbdaf4839 100644
--- a/src/libexpr/eval-cache.cc
+++ b/src/libexpr/eval-cache.cc
@@ -364,23 +364,33 @@ void AttrCursor::fetchCachedValue()
throw CachedEvalError(parent->first, parent->second);
}
-AttrPath AttrCursor::getAttrPath() const
+AttrPath AttrCursor::getAttrPathRaw() const
{
if (parent) {
- auto attrPath = parent->first->getAttrPath();
+ auto attrPath = parent->first->getAttrPathRaw();
attrPath.push_back(parent->second);
return attrPath;
} else
return {};
}
-AttrPath AttrCursor::getAttrPath(Symbol name) const
+AttrPath AttrCursor::getAttrPath() const
+{
+ return root->cleanupAttrPath(getAttrPathRaw());
+}
+
+AttrPath AttrCursor::getAttrPathRaw(Symbol name) const
{
- auto attrPath = getAttrPath();
+ auto attrPath = getAttrPathRaw();
attrPath.push_back(name);
return attrPath;
}
+AttrPath AttrCursor::getAttrPath(Symbol name) const
+{
+ return root->cleanupAttrPath(getAttrPathRaw(name));
+}
+
std::string AttrCursor::getAttrPathStr() const
{
return getAttrPath().to_string(root->state);
@@ -554,16 +564,17 @@ string_t AttrCursor::getStringWithContext()
if (auto s = std::get_if(&cachedValue->second)) {
bool valid = true;
for (auto & c : s->second) {
- const StorePath & path = std::visit(
+ const StorePath * path = std::visit(
overloaded{
- [&](const NixStringContextElem::DrvDeep & d) -> const StorePath & { return d.drvPath; },
- [&](const NixStringContextElem::Built & b) -> const StorePath & {
- return b.drvPath->getBaseStorePath();
+ [&](const NixStringContextElem::DrvDeep & d) -> const StorePath * { return &d.drvPath; },
+ [&](const NixStringContextElem::Built & b) -> const StorePath * {
+ return &b.drvPath->getBaseStorePath();
},
- [&](const NixStringContextElem::Opaque & o) -> const StorePath & { return o.path; },
+ [&](const NixStringContextElem::Opaque & o) -> const StorePath * { return &o.path; },
+ [&](const NixStringContextElem::Path & p) -> const StorePath * { return nullptr; },
},
c.raw);
- if (!root->state.store->isValidPath(path)) {
+ if (!path || !root->state.store->isValidPath(*path)) {
valid = false;
break;
}
@@ -711,6 +722,7 @@ StorePath AttrCursor::forceDerivation()
/* The eval cache contains 'drvPath', but the actual path has
been garbage-collected. So force it to be regenerated. */
aDrvPath->forceValue();
+ root->state.waitForPath(drvPath);
if (!root->state.store->isValidPath(drvPath))
throw Error(
"don't know how to recreate store derivation '%s'!", root->state.store->printStorePath(drvPath));
diff --git a/src/libexpr/eval-gc.cc b/src/libexpr/eval-gc.cc
index 0d25f38f64de..c1e974e053b8 100644
--- a/src/libexpr/eval-gc.cc
+++ b/src/libexpr/eval-gc.cc
@@ -46,6 +46,88 @@ static void * oomHandler(size_t requested)
throw std::bad_alloc();
}
+static size_t getFreeMem()
+{
+ /* On Linux, use the `MemAvailable` or `MemFree` fields from
+ /proc/cpuinfo. */
+# ifdef __linux__
+ {
+ std::unordered_map fields;
+ for (auto & line :
+ tokenizeString>(readFile(std::filesystem::path("/proc/meminfo")), "\n")) {
+ auto colon = line.find(':');
+ if (colon == line.npos)
+ continue;
+ fields.emplace(line.substr(0, colon), trim(line.substr(colon + 1)));
+ }
+
+ auto i = fields.find("MemAvailable");
+ if (i == fields.end())
+ i = fields.find("MemFree");
+ if (i != fields.end()) {
+ auto kb = tokenizeString>(i->second, " ");
+ if (kb.size() == 2 && kb[1] == "kB")
+ return string2Int(kb[0]).value_or(0) * 1024;
+ }
+ }
+# endif
+
+ /* On non-Linux systems, conservatively assume that 25% of memory is free. */
+ long pageSize = sysconf(_SC_PAGESIZE);
+ long pages = sysconf(_SC_PHYS_PAGES);
+ if (pageSize > 0 && pages > 0)
+ return (static_cast(pageSize) * static_cast(pages)) / 4;
+ return 0;
+}
+
+/**
+ * When a thread goes into a coroutine, we lose its original sp until
+ * control flow returns to the thread. This causes Boehm GC to crash
+ * since it will scan memory between the coroutine's sp and the
+ * original stack base of the thread. Therefore, we detect when the
+ * current sp is outside of the original thread stack and push the
+ * entire thread stack instead, as an approximation.
+ *
+ * This is not optimal, because it causes the stack below sp to be
+ * scanned. However, we usually we don't have active coroutines during
+ * evaluation, so this is acceptable.
+ *
+ * Note that we don't scan coroutine stacks. It's currently assumed
+ * that we don't have GC roots in coroutines.
+ */
+void fixupBoehmStackPointer(void ** sp_ptr, void * _pthread_id)
+{
+ void *& sp = *sp_ptr;
+ auto pthread_id = reinterpret_cast(_pthread_id);
+ size_t osStackSize;
+ char * osStackHi;
+ char * osStackLo;
+
+# ifdef __APPLE__
+ osStackSize = pthread_get_stacksize_np(pthread_id);
+ osStackHi = (char *) pthread_get_stackaddr_np(pthread_id);
+ osStackLo = osStackHi - osStackSize;
+# else
+ pthread_attr_t pattr;
+ if (pthread_attr_init(&pattr))
+ throw Error("fixupBoehmStackPointer: pthread_attr_init failed");
+# ifdef HAVE_PTHREAD_GETATTR_NP
+ if (pthread_getattr_np(pthread_id, &pattr))
+ throw Error("fixupBoehmStackPointer: pthread_getattr_np failed");
+# else
+# error "Need `pthread_attr_get_np`"
+# endif
+ if (pthread_attr_getstack(&pattr, (void **) &osStackLo, &osStackSize))
+ throw Error("fixupBoehmStackPointer: pthread_attr_getstack failed");
+ if (pthread_attr_destroy(&pattr))
+ throw Error("fixupBoehmStackPointer: pthread_attr_destroy failed");
+ osStackHi = osStackLo + osStackSize;
+# endif
+
+ if (sp >= osStackHi || sp < osStackLo) // sp is outside the os stack
+ sp = osStackLo;
+}
+
static inline void initGCReal()
{
/* Initialise the Boehm garbage collector. */
@@ -76,8 +158,11 @@ static inline void initGCReal()
GC_set_oom_fn(oomHandler);
- /* Set the initial heap size to something fairly big (25% of
- physical RAM, up to a maximum of 384 MiB) so that in most cases
+ GC_set_sp_corrector(&fixupBoehmStackPointer);
+ assert(GC_get_sp_corrector());
+
+ /* Set the initial heap size to something fairly big (80% of
+ free RAM, up to a maximum of 4 GiB) so that in most cases
we don't need to garbage collect at all. (Collection has a
fairly significant overhead.) The heap size can be overridden
through libgc's GC_INITIAL_HEAP_SIZE environment variable. We
@@ -88,15 +173,10 @@ static inline void initGCReal()
if (!getEnv("GC_INITIAL_HEAP_SIZE")) {
size_t size = 32 * 1024 * 1024;
# if HAVE_SYSCONF && defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES)
- size_t maxSize = 384 * 1024 * 1024;
- long pageSize = sysconf(_SC_PAGESIZE);
- long pages = sysconf(_SC_PHYS_PAGES);
- if (pageSize != -1)
- size = (pageSize * pages) / 4; // 25% of RAM
- if (size > maxSize)
- size = maxSize;
+ size_t maxSize = 4ULL * 1024 * 1024 * 1024;
+ auto free = getFreeMem();
+ size = std::max(size, std::min((size_t) (free * 0.5), maxSize));
# endif
- debug("setting initial heap size to %1% bytes", size);
GC_expand_hp(size);
}
}
diff --git a/src/libexpr/eval-settings.cc b/src/libexpr/eval-settings.cc
index 04c6193885e1..27205864b8ba 100644
--- a/src/libexpr/eval-settings.cc
+++ b/src/libexpr/eval-settings.cc
@@ -91,9 +91,19 @@ bool EvalSettings::isPseudoUrl(std::string_view s)
std::string EvalSettings::resolvePseudoUrl(std::string_view url)
{
- if (hasPrefix(url, "channel:"))
- return "https://channels.nixos.org/" + std::string(url.substr(8)) + "/nixexprs.tar.xz";
- else
+ if (hasPrefix(url, "channel:")) {
+ auto realUrl = "https://channels.nixos.org/" + std::string(url.substr(8)) + "/nixexprs.tar.xz";
+ static bool haveWarned = false;
+ warnOnce(
+ haveWarned,
+ "Channels are deprecated in favor of flakes in Determinate Nix. "
+ "Instead of '%s', use '%s'. "
+ "See https://zero-to-nix.com for a guide to Nix flakes. "
+ "For details and to offer feedback on the deprecation process, see: https://github.com/DeterminateSystems/nix-src/issues/34.",
+ url,
+ realUrl);
+ return realUrl;
+ } else
return std::string(url);
}
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index ab3f7b3ff5da..1392ce38b0a6 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -25,6 +25,8 @@
#include "nix/fetchers/tarball.hh"
#include "nix/fetchers/input-cache.hh"
#include "nix/util/current-process.hh"
+#include "nix/store/async-path-writer.hh"
+#include "nix/expr/parallel-eval.hh"
#include "parser-tab.hh"
@@ -44,6 +46,11 @@
#include
#include
#include
+#include
+
+#ifndef _WIN32 // TODO use portable implementation
+# include
+#endif
#include "nix/util/strings-inline.hh"
@@ -155,6 +162,8 @@ std::string_view showType(ValueType type, bool withArticle)
return WA("a", "float");
case nThunk:
return WA("a", "thunk");
+ case nFailed:
+ return WA("a", "failure");
}
unreachable();
}
@@ -193,20 +202,36 @@ PosIdx Value::determinePos(const PosIdx pos) const
return attrs()->pos;
case tLambda:
return lambda().fun->pos;
+#if 0
+ // FIXME: disabled because reading from an app is racy.
case tApp:
return app().left->determinePos(pos);
+#endif
default:
return pos;
}
#pragma GCC diagnostic pop
}
-bool Value::isTrivial() const
+template<>
+bool ValueStorage::isTrivial() const
{
- return !isa()
- && (!isa()
- || (dynamic_cast(thunk().expr) && ((ExprAttrs *) thunk().expr)->dynamicAttrs->empty())
- || dynamic_cast(thunk().expr) || dynamic_cast(thunk().expr));
+ auto p1_ = p1; // must acquire before reading p0, since thunks can change
+ auto p0_ = p0.load(std::memory_order_acquire);
+
+ auto pd = static_cast(p0_ & discriminatorMask);
+
+ if (pd == pdThunk || pd == pdPending || pd == pdAwaited) {
+ bool isApp = p1_ & discriminatorMask;
+ if (isApp)
+ return false;
+ auto expr = untagPointer(p1_);
+ return (dynamic_cast(expr) && ((ExprAttrs *) expr)->dynamicAttrs->empty())
+ || dynamic_cast(expr) || dynamic_cast(expr);
+ }
+
+ else
+ return true;
}
static Symbol getName(const AttrName & name, EvalState & state, Env & env)
@@ -232,6 +257,8 @@ EvalMemory::EvalMemory()
assertGCInitialized();
}
+thread_local EvalState::EvalContext EvalState::evalContext;
+
EvalState::EvalState(
const LookupPath & lookupPathFromArguments,
ref store,
@@ -300,6 +327,7 @@ EvalState::EvalState(
, debugRepl(nullptr)
, debugStop(false)
, trylevel(0)
+ , asyncPathWriter(AsyncPathWriter::make(store))
, srcToStore(make_ref())
, importResolutionCache(make_ref())
, fileEvalCache(make_ref())
@@ -311,6 +339,7 @@ EvalState::EvalState(
, baseEnv(mem.allocEnv(BASE_ENV_SIZE))
#endif
, staticBaseEnv{std::make_shared(nullptr, nullptr)}
+ , executor{make_ref(settings)}
{
corepkgsFS->setPathDisplay("");
internalFS->setPathDisplay("«nix-internal»", "");
@@ -451,7 +480,8 @@ void EvalState::checkURI(const std::string & uri)
Value * EvalState::addConstant(const std::string & name, Value & v, Constant info)
{
Value * v2 = allocValue();
- *v2 = v;
+ // Do a raw copy since `operator =` barfs on thunks.
+ memcpy((char *) v2, (char *) &v, sizeof(Value));
addConstant(name, v2, info);
return v2;
}
@@ -467,8 +497,10 @@ void EvalState::addConstant(const std::string & name, Value * v, Constant info)
We might know the type of a thunk in advance, so be allowed
to just write it down in that case. */
- if (auto gotType = v->type(true); gotType != nThunk)
- assert(info.type == gotType);
+ if (v->isFinished()) {
+ if (auto gotType = v->type(); gotType != nThunk)
+ assert(info.type == gotType);
+ }
/* Install value the base environment. */
staticBaseEnv->vars.emplace_back(symbols.create(name), baseEnvDispl);
@@ -654,7 +686,7 @@ void printStaticEnvBindings(const SymbolTable & st, const StaticEnv & se)
// just for the current level of Env, not the whole chain.
void printWithBindings(const SymbolTable & st, const Env & env)
{
- if (!env.values[0]->isThunk()) {
+ if (env.values[0]->isFinished()) {
std::cout << "with: ";
std::cout << ANSI_MAGENTA;
auto j = env.values[0]->attrs()->begin();
@@ -709,7 +741,7 @@ void mapStaticEnvBindings(const SymbolTable & st, const StaticEnv & se, const En
if (env.up && se.up) {
mapStaticEnvBindings(st, *se.up, *env.up, vm);
- if (se.isWith && !env.values[0]->isThunk()) {
+ if (se.isWith && env.values[0]->isFinished()) {
// add 'with' bindings.
for (auto & j : *env.values[0]->attrs())
vm.insert_or_assign(std::string(st[j.name]), j.value);
@@ -943,7 +975,14 @@ void EvalState::mkPos(Value & v, PosIdx p)
auto origin = positions.originOf(p);
if (auto path = std::get_if(&origin)) {
auto attrs = buildBindings(3);
- attrs.alloc(s.file).mkString(path->path.abs(), mem);
+ if (path->accessor == rootFS && store->isInStore(path->path.abs()))
+ // FIXME: only do this for virtual store paths?
+ attrs.alloc(s.file).mkString(
+ path->path.abs(),
+ {NixStringContextElem::Path{.storePath = store->toStorePath(path->path.abs()).first}},
+ mem);
+ else
+ attrs.alloc(s.file).mkString(path->path.abs(), mem);
makePositionThunks(*this, p, attrs.alloc(s.line), attrs.alloc(s.column));
v.mkAttrs(attrs);
} else
@@ -991,6 +1030,7 @@ std::string EvalState::mkSingleDerivedPathStringRaw(const SingleDerivedPath & p)
auto optStaticOutputPath = std::visit(
overloaded{
[&](const SingleDerivedPath::Opaque & o) {
+ waitForPath(o.path);
auto drv = store->readDerivation(o.path);
auto i = drv.outputs.find(b.output);
if (i == drv.outputs.end())
@@ -1066,10 +1106,9 @@ Value * ExprPath::maybeThunk(EvalState & state, Env & env)
* from a thunk, ensuring that every file is parsed/evaluated only
* once (via the thunk stored in `EvalState::fileEvalCache`).
*/
-struct ExprParseFile : Expr, gc
+struct ExprParseFile : Expr
{
- // FIXME: make this a reference (see below).
- SourcePath path;
+ SourcePath & path;
bool mustBeTrivial;
ExprParseFile(SourcePath & path, bool mustBeTrivial)
@@ -1120,18 +1159,14 @@ void EvalState::evalFile(const SourcePath & path, Value & v, bool mustBeTrivial)
}
Value * vExpr;
- // FIXME: put ExprParseFile on the stack instead of the heap once
- // https://github.com/NixOS/nix/pull/13930 is merged. That will ensure
- // the post-condition that `expr` is unreachable after
- // `forceValue()` returns.
- auto expr = new ExprParseFile{*resolvedPath, mustBeTrivial};
+ ExprParseFile expr{*resolvedPath, mustBeTrivial};
fileEvalCache->try_emplace_and_cvisit(
*resolvedPath,
nullptr,
[&](auto & i) {
vExpr = allocValue();
- vExpr->mkThunk(&baseEnv, expr);
+ vExpr->mkThunk(&baseEnv, &expr);
i.second = vExpr;
},
[&](auto & i) { vExpr = i.second; });
@@ -1437,7 +1472,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
state.attrSelects[pos2]++;
}
- state.forceValue(*vAttrs, (pos2 ? pos2 : this->pos));
+ state.forceValue(*vAttrs, pos2 ? pos2 : this->pos);
} catch (Error & e) {
if (pos2) {
@@ -1496,6 +1531,8 @@ void ExprLambda::eval(EvalState & state, Env & env, Value & v)
v.mkLambda(&env, this);
}
+thread_local size_t EvalState::callDepth = 0;
+
void EvalState::callFunction(Value & fun, std::span args, Value & vRes, const PosIdx pos)
{
auto _level = addCallDepth(pos);
@@ -1511,15 +1548,16 @@ void EvalState::callFunction(Value & fun, std::span args, Value & vRes,
forceValue(fun, pos);
- Value vCur(fun);
+ Value vCur = fun;
auto makeAppChain = [&]() {
- vRes = vCur;
for (auto arg : args) {
auto fun2 = allocValue();
- *fun2 = vRes;
- vRes.mkPrimOpApp(fun2, arg);
+ *fun2 = vCur;
+ vCur.reset();
+ vCur.mkPrimOpApp(fun2, arg);
}
+ vRes = vCur;
};
const Attr * functor;
@@ -1615,6 +1653,7 @@ void EvalState::callFunction(Value & fun, std::span args, Value & vRes,
lambda.name ? concatStrings("'", symbols[lambda.name], "'") : "anonymous lambda")
: nullptr;
+ vCur.reset();
lambda.body->eval(*this, env2, vCur);
} catch (Error & e) {
if (loggerSettings.showTrace.get()) {
@@ -1649,7 +1688,9 @@ void EvalState::callFunction(Value & fun, std::span args, Value & vRes,
primOpCalls[fn->name]++;
try {
- fn->fun(*this, vCur.determinePos(noPos), args.data(), vCur);
+ auto pos = vCur.determinePos(noPos);
+ vCur.reset();
+ fn->fun(*this, pos, args.data(), vCur);
} catch (Error & e) {
if (fn->addTrace)
addErrorTrace(e, pos, "while calling the '%1%' builtin", fn->name);
@@ -1671,6 +1712,7 @@ void EvalState::callFunction(Value & fun, std::span args, Value & vRes,
assert(primOp->isPrimOp());
auto arity = primOp->primOp()->arity;
auto argsLeft = arity - argsDone;
+ assert(argsLeft);
if (args.size() < argsLeft) {
/* We still don't have enough arguments, so extend the tPrimOpApp chain. */
@@ -1699,7 +1741,9 @@ void EvalState::callFunction(Value & fun, std::span args, Value & vRes,
// 2. Create a fake env (arg1, arg2, etc.) and a fake expr (arg1: arg2: etc: builtins.name arg1 arg2
// etc)
// so the debugger allows to inspect the wrong parameters passed to the builtin.
- fn->fun(*this, vCur.determinePos(noPos), vArgs, vCur);
+ auto pos = vCur.determinePos(noPos);
+ vCur.reset();
+ fn->fun(*this, pos, vArgs, vCur);
} catch (Error & e) {
if (fn->addTrace)
addErrorTrace(e, pos, "while calling the '%1%' builtin", fn->name);
@@ -1716,6 +1760,7 @@ void EvalState::callFunction(Value & fun, std::span args, Value & vRes,
heap-allocate a copy and use that instead. */
Value * args2[] = {allocValue(), args[0]};
*args2[0] = vCur;
+ vCur.reset();
try {
callFunction(*functor->value, args2, vCur, functor->pos);
} catch (Error & e) {
@@ -1903,8 +1948,12 @@ void ExprOpImpl::eval(EvalState & state, Env & env, Value & v)
|| state.evalBool(env, e2, pos, "in the right operand of the IMPL (->) operator"));
}
-void ExprOpUpdate::eval(EvalState & state, Value & v, Value & v1, Value & v2)
+void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v)
{
+ Value v1, v2;
+ state.evalAttrs(env, e1, v1, pos, "in the left operand of the update (//) operator");
+ state.evalAttrs(env, e2, v2, pos, "in the right operand of the update (//) operator");
+
state.nrOpUpdates++;
const Bindings & bindings1 = *v1.attrs();
@@ -1978,38 +2027,6 @@ void ExprOpUpdate::eval(EvalState & state, Value & v, Value & v1, Value & v2)
state.nrOpUpdateValuesCopied += v.attrs()->size();
}
-void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v)
-{
- UpdateQueue q;
- evalForUpdate(state, env, q);
-
- v.mkAttrs(&Bindings::emptyBindings);
- for (auto & rhs : std::views::reverse(q)) {
- /* Remember that queue is sorted rightmost attrset first. */
- eval(state, /*v=*/v, /*v1=*/v, /*v2=*/rhs);
- }
-}
-
-void Expr::evalForUpdate(EvalState & state, Env & env, UpdateQueue & q, std::string_view errorCtx)
-{
- Value v;
- state.evalAttrs(env, this, v, getPos(), errorCtx);
- q.push_back(v);
-}
-
-void ExprOpUpdate::evalForUpdate(EvalState & state, Env & env, UpdateQueue & q)
-{
- /* Output rightmost attrset first to the merge queue as the one
- with the most priority. */
- e2->evalForUpdate(state, env, q, "in the right operand of the update (//) operator");
- e1->evalForUpdate(state, env, q, "in the left operand of the update (//) operator");
-}
-
-void ExprOpUpdate::evalForUpdate(EvalState & state, Env & env, UpdateQueue & q, std::string_view errorCtx)
-{
- evalForUpdate(state, env, q);
-}
-
void ExprOpConcatLists::eval(EvalState & state, Env & env, Value & v)
{
Value v1;
@@ -2129,7 +2146,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
} else if (firstType == nFloat) {
v.mkFloat(nf);
} else if (firstType == nPath) {
- if (!context.empty())
+ if (hasContext(context))
state.error("a string that refers to a store path cannot be appended to a path")
.atPos(pos)
.withFrame(env, *this)
@@ -2157,16 +2174,6 @@ void ExprPos::eval(EvalState & state, Env & env, Value & v)
state.mkPos(v, pos);
}
-void ExprBlackHole::eval(EvalState & state, [[maybe_unused]] Env & env, Value & v)
-{
- throwInfiniteRecursionError(state, v);
-}
-
-[[gnu::noinline]] [[noreturn]] void ExprBlackHole::throwInfiniteRecursionError(EvalState & state, Value & v)
-{
- state.error("infinite recursion encountered").atPos(v.determinePos(noPos)).debugThrow();
-}
-
// always force this to be separate, otherwise forceValue may inline it and take
// a massive perf hit
[[gnu::noinline]]
@@ -2199,6 +2206,7 @@ void EvalState::forceValueDeep(Value & v)
for (auto & i : *v.attrs())
try {
// If the value is a thunk, we're evaling. Otherwise no trace necessary.
+ // FIXME: race, thunk might be updated by another thread
auto dts = state.debugRepl && i.value->isThunk() ? makeDebugTraceStacker(
state,
*i.value->thunk().expr,
@@ -2351,12 +2359,15 @@ std::string_view EvalState::forceStringNoCtx(Value & v, const PosIdx pos, std::s
{
auto s = forceString(v, pos, errorCtx);
if (v.context()) {
- error(
- "the string '%1%' is not allowed to refer to a store path (such as '%2%')",
- v.string_view(),
- (*v.context()->begin())->view())
- .withTrace(pos, errorCtx)
- .debugThrow();
+ NixStringContext context;
+ copyContext(v, context);
+ if (hasContext(context))
+ error(
+ "the string '%1%' is not allowed to refer to a store path (such as '%2%')",
+ v.string_view(),
+ (*v.context()->begin())->view())
+ .withTrace(pos, errorCtx)
+ .debugThrow();
}
return s;
}
@@ -2411,14 +2422,21 @@ BackedStringView EvalState::coerceToString(
}
if (v.type() == nPath) {
+ // FIXME: instead of copying the path to the store, we could
+ // return a virtual store path that lazily copies the path to
+ // the store in devirtualize().
if (!canonicalizePath && !copyToStore) {
// FIXME: hack to preserve path literals that end in a
// slash, as in /foo/${x}.
return v.pathStrView();
} else if (copyToStore) {
- return store->printStorePath(copyPathToStore(context, v.path()));
+ return store->printStorePath(copyPathToStore(context, v.path(), v.determinePos(pos)));
} else {
- return std::string{v.path().path.abs()};
+ auto path = v.path();
+ if (path.accessor == rootFS && store->isInStore(path.path.abs())) {
+ context.insert(NixStringContextElem::Path{.storePath = store->toStorePath(path.path.abs()).first});
+ }
+ return std::string(path.path.abs());
}
}
@@ -2490,7 +2508,7 @@ BackedStringView EvalState::coerceToString(
.debugThrow();
}
-StorePath EvalState::copyPathToStore(NixStringContext & context, const SourcePath & path)
+StorePath EvalState::copyPathToStore(NixStringContext & context, const SourcePath & path, PosIdx pos)
{
if (nix::isDerivation(path.path.abs()))
error("file names are not allowed to end in '%1%'", drvExtension).debugThrow();
@@ -2503,7 +2521,7 @@ StorePath EvalState::copyPathToStore(NixStringContext & context, const SourcePat
*store,
path.resolveSymlinks(SymlinkResolution::Ancestors),
settings.readOnlyMode ? FetchMode::DryRun : FetchMode::Copy,
- path.baseName(),
+ computeBaseName(path, pos),
ContentAddressMethod::Raw::NixArchive,
nullptr,
repair);
@@ -2555,7 +2573,9 @@ EvalState::coerceToStorePath(const PosIdx pos, Value & v, NixStringContext & con
auto path = coerceToString(pos, v, context, errorCtx, false, false, true).toOwned();
if (auto storePath = store->maybeParseStorePath(path))
return *storePath;
- error("path '%1%' is not in the Nix store", path).withTrace(pos, errorCtx).debugThrow();
+ error("cannot coerce '%s' to a store path because it is not a subpath of the Nix store", path)
+ .withTrace(pos, errorCtx)
+ .debugThrow();
}
std::pair EvalState::coerceToSingleDerivedPathUnchecked(
@@ -2579,6 +2599,9 @@ std::pair EvalState::coerceToSingleDerivedP
.debugThrow();
},
[&](NixStringContextElem::Built && b) -> SingleDerivedPath { return std::move(b); },
+ [&](NixStringContextElem::Path && p) -> SingleDerivedPath {
+ error("string '%s' has no context", s).withTrace(pos, errorCtx).debugThrow();
+ },
},
((NixStringContextElem &&) *context.begin()).raw);
return {
@@ -2813,8 +2836,11 @@ void EvalState::assertEqValues(Value & v1, Value & v2, const PosIdx pos, std::st
}
return;
- case nThunk: // Must not be left by forceValue
- assert(false);
+ // Cannot be returned by forceValue().
+ case nThunk:
+ case nFailed:
+ unreachable();
+
default: // Note that we pass compiler flags that should make `default:` unreachable.
// Also note that this probably ran after `eqValues`, which implements
// the same logic more efficiently (without having to unwind stacks),
@@ -2906,8 +2932,11 @@ bool EvalState::eqValues(Value & v1, Value & v2, const PosIdx pos, std::string_v
// !!!
return v1.fpoint() == v2.fpoint();
- case nThunk: // Must not be left by forceValue
- assert(false);
+ // Cannot be returned by forceValue().
+ case nThunk:
+ case nFailed:
+ unreachable();
+
default: // Note that we pass compiler flags that should make `default:` unreachable.
error("eqValues: cannot compare %1% with %2%", showType(v1), showType(v2))
.withTrace(pos, errorCtx)
@@ -3013,6 +3042,11 @@ void EvalState::printStatistics()
topObj["nrOpUpdates"] = nrOpUpdates.load();
topObj["nrOpUpdateValuesCopied"] = nrOpUpdateValuesCopied.load();
topObj["nrThunks"] = nrThunks.load();
+ topObj["nrThunksAwaited"] = nrThunksAwaited.load();
+ topObj["nrThunksAwaitedSlow"] = nrThunksAwaitedSlow.load();
+ topObj["nrSpuriousWakeups"] = nrSpuriousWakeups.load();
+ topObj["maxWaiting"] = maxWaiting.load();
+ topObj["waitingTime"] = microsecondsWaiting / (double) 1000000;
topObj["nrAvoided"] = nrAvoided.load();
topObj["nrLookups"] = nrLookups.load();
topObj["nrPrimOpCalls"] = nrPrimOpCalls.load();
@@ -3064,10 +3098,10 @@ void EvalState::printStatistics()
}
if (getEnv("NIX_SHOW_SYMBOLS").value_or("0") != "0") {
+ auto list = json::array();
+ symbols.dump([&](std::string_view s) { list.emplace_back(std::string(s)); });
// XXX: overrides earlier assignment
- topObj["symbols"] = json::array();
- auto & list = topObj["symbols"];
- symbols.dump([&](std::string_view s) { list.emplace_back(s); });
+ topObj["symbols"] = std::move(list);
}
if (outPath == "-") {
std::cerr << topObj.dump(2) << std::endl;
@@ -3254,11 +3288,11 @@ Expr * EvalState::parse(
const std::shared_ptr & staticEnv)
{
DocCommentMap tmpDocComments; // Only used when not origin is not a SourcePath
- DocCommentMap * docComments = &tmpDocComments;
+ auto * docComments = &tmpDocComments;
if (auto sourcePath = std::get_if