Skip to content

chore(nix): add development shell and CI#2128

Open
lloeki wants to merge 7 commits into
mainfrom
lloeki/nix
Open

chore(nix): add development shell and CI#2128
lloeki wants to merge 7 commits into
mainfrom
lloeki/nix

Conversation

@lloeki

@lloeki lloeki commented Jun 16, 2026

Copy link
Copy Markdown
Member

What does this PR do?

Adds a Nix flake development shell to the repository, with a CI workflow that exercises it.

  • flake.nix / flake.lock: a devshell providing the Rust toolchain (rustc, cargo, rustfmt, clippy), cbindgen, cmake and autotools. The Rust toolchain is pinned via the oxalica/rust-overlay input reading the existing rust-toolchain.toml, so the devshell tracks the same channel as CI and rustup.
  • .github/workflows/nix.yml: enters the devshell and builds the workspace on Linux (x86_64, aarch64) and macOS (arm64), mirroring the Nix CI already present in dd-trace-rb and libdatadog-rb.
  • CODEOWNERS: co-owns the Nix files and workflow with the Nix guild.

Motivation

Contributors using Nix previously kept these files locally and unshared, with the Rust version floating with the nixpkgs channel (currently 1.91.1) rather than matching the toolchain libdatadog is built with. Committing a pinned devshell gives a reproducible, low-setup environment, and the CI guard keeps it from bit-rotting.

Additional Notes

The pin derives from rust-toolchain.toml (single source of truth), so a future MSRV bump updates the devshell automatically.

AI was used to accelerate implementation; all code was reviewed and understood.

How to test the change?

nix develop --command cargo build --workspace --exclude builder, and confirm nix develop --command rustc --version reports the channel from rust-toolchain.toml. CI runs the same build across the three platforms.

lloeki added 3 commits June 16, 2026 15:27
Provide a Nix flake devshell so contributors can get a reproducible
environment (rustc, cargo, rustfmt, clippy, cbindgen, cmake, autotools)
without manual setup. The Rust toolchain is read from the existing
rust-toolchain.toml via the rust-overlay input, so the devshell tracks
the same channel as CI and rustup.
Mirror the CODEOWNERS convention already used in dd-trace-rb and
libdatadog-rb so the Nix guild reviews changes to the development shell
alongside the existing tooling owners.
Add a GitHub Actions workflow that enters the Nix development shell and
builds the workspace on Linux (x86_64, aarch64) and macOS (arm64),
mirroring the Nix CI in dd-trace-rb and libdatadog-rb. This guards the
devshell against bit-rot so contributors relying on it keep a working,
toolchain-pinned environment. Co-own the workflow with the Nix guild.
@datadog-datadog-prod-us1-2

datadog-datadog-prod-us1-2 Bot commented Jun 16, 2026

Copy link
Copy Markdown

Tests

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

🎯 Code Coverage (details)
Patch Coverage: 100.00%
Overall Coverage: 73.35% (+0.29%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: c2a77fe | Docs | Datadog PR Page | Give us feedback!

The stdenv cc-wrapper injects -D_FORTIFY_SOURCE, which glibc rejects when
compiling without optimization. spawn_worker's build script compiles its
trampoline.c at -O0 with -Werror, turning the fortify #warning into a
hard error and breaking a workspace build inside the devshell. Disable
fortify hardening so these C build steps succeed.
@lloeki

lloeki commented Jun 16, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: efca305b12

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/nix.yml
Comment on lines +27 to +30
base: ubuntu-24.04 # always x86_64-linux-gnu
- os: linux
cpu: aarch64
base: ubuntu-24.04-arm # always aarch64-linux-gnu

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use larger Linux runners for the Nix workspace build

In the Linux matrix entries this runs the full cargo build --workspace --exclude builder on standard ubuntu-24.04/ubuntu-24.04-arm runners. The existing test workflow explicitly routes Ubuntu full-workspace builds to the APM larger runner pool because the default GitHub-hosted Ubuntu disk fills during that same workspace build (.github/workflows/test.yml:74-76), and nix develop will also populate /nix/store, so this new check is likely to fail before exercising the flake.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like it's working ok?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're probably ok, since you're compiling a single build. The test workflow is doing multiple, and also doing extra stuff like compiling test fixtures for crashtracker tests, generating code coverage reports, etc.

You could temporarily output df here to see how much headroom you have and potentially use the free-disk-space action like we do here (You probably don't have to be as aggressive as the test workflow is).

@lloeki lloeki marked this pull request as ready for review June 16, 2026 14:19
@lloeki lloeki requested a review from a team as a code owner June 16, 2026 14:19
Comment thread flake.nix

buildInputs = [
rust # rustc + cargo + rustfmt + clippy, pinned via toolchain file
pkgs.rust-cbindgen

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should cbindgen be pinned as well?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, but it's probably not critical for a first PR, since the headers aren't checked in libdatadog manually but are generated automatically when building the FFI (thus using a pinned version). Having cbindgen is nice for local development if you are curious about the generated C interface but it's indicative I believe (plus the fact that I expect cbindgen output to be stable?).

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: efca305b12

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread flake.nix
@@ -0,0 +1,53 @@
{

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add the required license header

AGENTS.md states that all source files must carry the Apache 2.0 license header, but this new Nix source file starts directly with the expression body. Since .nix files can include comments, add the standard Datadog copyright and SPDX header here so the newly added development-shell source follows the repository's licensing convention.

Useful? React with 👍 / 👎.

@dd-octo-sts

dd-octo-sts Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Artifact Size Benchmark Report

aarch64-alpine-linux-musl
Artifact Baseline Commit Change
/aarch64-alpine-linux-musl/lib/libdatadog_profiling.so 7.70 MB 7.70 MB 0% (0 B) 👌
/aarch64-alpine-linux-musl/lib/libdatadog_profiling.a 83.68 MB 83.68 MB 0% (0 B) 👌
aarch64-unknown-linux-gnu
Artifact Baseline Commit Change
/aarch64-unknown-linux-gnu/lib/libdatadog_profiling.a 94.78 MB 94.78 MB 0% (0 B) 👌
/aarch64-unknown-linux-gnu/lib/libdatadog_profiling.so 10.34 MB 10.34 MB 0% (0 B) 👌
libdatadog-x64-windows
Artifact Baseline Commit Change
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.dll 24.83 MB 24.83 MB 0% (0 B) 👌
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.lib 87.33 KB 87.33 KB 0% (0 B) 👌
/libdatadog-x64-windows/debug/dynamic/datadog_profiling_ffi.pdb 180.88 MB 180.89 MB +0% (+8.00 KB) 👌
/libdatadog-x64-windows/debug/static/datadog_profiling_ffi.lib 925.05 MB 925.05 MB 0% (0 B) 👌
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.dll 8.09 MB 8.09 MB 0% (0 B) 👌
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.lib 87.33 KB 87.33 KB 0% (0 B) 👌
/libdatadog-x64-windows/release/dynamic/datadog_profiling_ffi.pdb 23.94 MB 23.94 MB 0% (0 B) 👌
/libdatadog-x64-windows/release/static/datadog_profiling_ffi.lib 47.78 MB 47.78 MB 0% (0 B) 👌
libdatadog-x86-windows
Artifact Baseline Commit Change
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.dll 21.52 MB 21.52 MB 0% (0 B) 👌
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.lib 88.71 KB 88.71 KB 0% (0 B) 👌
/libdatadog-x86-windows/debug/dynamic/datadog_profiling_ffi.pdb 184.88 MB 184.88 MB 0% (0 B) 👌
/libdatadog-x86-windows/debug/static/datadog_profiling_ffi.lib 918.00 MB 918.00 MB 0% (0 B) 👌
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.dll 6.24 MB 6.24 MB 0% (0 B) 👌
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.lib 88.71 KB 88.71 KB 0% (0 B) 👌
/libdatadog-x86-windows/release/dynamic/datadog_profiling_ffi.pdb 25.66 MB 25.66 MB 0% (0 B) 👌
/libdatadog-x86-windows/release/static/datadog_profiling_ffi.lib 45.41 MB 45.41 MB 0% (0 B) 👌
x86_64-alpine-linux-musl
Artifact Baseline Commit Change
/x86_64-alpine-linux-musl/lib/libdatadog_profiling.a 74.60 MB 74.60 MB 0% (0 B) 👌
/x86_64-alpine-linux-musl/lib/libdatadog_profiling.so 8.58 MB 8.58 MB 0% (0 B) 👌
x86_64-unknown-linux-gnu
Artifact Baseline Commit Change
/x86_64-unknown-linux-gnu/lib/libdatadog_profiling.a 90.02 MB 90.02 MB 0% (0 B) 👌
/x86_64-unknown-linux-gnu/lib/libdatadog_profiling.so 10.44 MB 10.44 MB 0% (0 B) 👌

Comment thread .github/workflows/nix.yml Outdated
Comment thread .github/workflows/nix.yml
platform:
- os: darwin
cpu: arm64
base: macos-15 # always arm64-darwin

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is macos strictly needed? I ask because macos runners are scarce and ocuppying one for this might hurt us a bit in terms of merge times

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it guarantees that it consistently works across OSes for any dev that uses Nix on a macOS machine

Should be mostly mitigated by conditional running mentioned above.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also use a concurrency group (example from our test workflow)and cancel in progress if you don't need commit level granularity.

Not necessarily a hill I want to die on, but I think using a concurrency group is a good compromise between getting signal that something broke and not potentially backing up the MergeQueue waiting for a macOS runner for a workflow that doesn't indicate an actual code issue.

lloeki added 3 commits June 17, 2026 15:04
The devshell is a rarely-changing safeguard, so gating every pull request
on it is unnecessary. Drop the blanket pull_request trigger and keep the
workflow on main and mq-working-branch-* pushes; devshell breakage will
still surface in the main pipeline.
Keep the devshell guard responsive to changes that actually affect it:
run on pull requests that modify the Nix files (paths mirror the Nix
CODEOWNERS entries), rust-toolchain.toml (read by the flake), or this
workflow.
Add a non-default `.#nightly` devshell built from ./nightly-toolchain.toml
(via rust-overlay's fromRustupToolchainFile), for the workflows that need
a nightly compiler. Factor the shared shell definition into mkDevShell so
default and nightly only differ by toolchain.
@lloeki lloeki requested a review from hoolioh June 17, 2026 13:11
Comment thread .github/CODEOWNERS
fuzz/ @DataDog/chaos-platform

# Nix
*.nix @DataDog/nix-guild @DataDog/apm-common-components-core

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL there's a Nix guild 😄

Comment thread flake.nix
hardeningDisable = [ "fortify" "fortify3" ];

buildInputs = [
rust # rustc + cargo + rustfmt + clippy, pinned via toolchain file

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One slightly annoying thing here is that we need to cargo fmt with nightly. I wonder if we should provide a nightly toolchain pinned as well, or even maybe propose a "libdd-fmt" alias that uses the right nightly toolchain under the hood. It's a detail though, and could be worked out in a follow up PR.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coincidentally I just added a nightly toolchain as .#nightly.

Maybe we can even work out something that would have a closure over the nightly toolchain as an internal dependency for a nightly-based cargo fmt - and only that - to be exposed. That's exactly the kind of thing Nix can solve.

Indeed probably for a later PR.

Comment thread flake.nix

buildInputs = [
rust # rustc + cargo + rustfmt + clippy, pinned via toolchain file
pkgs.rust-cbindgen

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, but it's probably not critical for a first PR, since the headers aren't checked in libdatadog manually but are generated automatically when building the FFI (thus using a pinned version). Having cbindgen is nice for local development if you are curious about the generated C interface but it's indicative I believe (plus the fact that I expect cbindgen output to be stable?).

@yannham

yannham commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Do you know what are those Test Nix / test report jobs, or where they are coming from? They have no logs and a Windows one doesn't make sense

image

@lloeki

lloeki commented Jun 17, 2026

Copy link
Copy Markdown
Member Author

Do you know what are those Test Nix / test report jobs, or where they are coming from? They have no logs and a Windows one doesn't make sense

image

Interesting. I'm not sure, let me look that up.

@ekump ekump left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few nit comments, but I'm not a nix guy so not sure how relevant they are.

LGTM after we add a little bit of documentation and add a concurrency group for the workflow.

Comment thread flake.nix
# hardening in the shell so those builds succeed.
hardeningDisable = [ "fortify" "fortify3" ];

buildInputs = [

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Should this be nativeBuildInputs since they are build-time host tools?

Comment thread flake.nix
flake-utils.url = "github:numtide/flake-utils";

# backwards compatibility with nix-build and nix-shell
flake-compat.url = "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz";

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Is this necessary? shell.nix or default.nix aren't included in this repo (maybe they will be in the future?).

Comment thread .github/workflows/nix.yml
platform:
- os: darwin
cpu: arm64
base: macos-15 # always arm64-darwin

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also use a concurrency group (example from our test workflow)and cancel in progress if you don't need commit level granularity.

Not necessarily a hill I want to die on, but I think using a concurrency group is a good compromise between getting signal that something broke and not potentially backing up the MergeQueue waiting for a macOS runner for a workflow that doesn't indicate an actual code issue.

Comment thread .github/workflows/nix.yml

permissions:
contents: read
id-token: write

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary? could you get away with contents: read?

Comment thread .github/workflows/nix.yml
@@ -0,0 +1,69 @@
name: Test Nix

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add documentation (maybe here and / or inline in this file) with instructions on what to do if there is a failure? I suspect it'll only come up on MSRV bumps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants