ci: move to Nix
Description
This would make all the tests possible to run locally. It enhances developer experience and facilitates onboarding of new contributors.
(Updated MSRV to 1.63)
Additions:
- Crate auditing capabilities using
rustsec/advisory-db. - Local and CI caching of all artifacts from running
cargo {check,build,test}in the whole workspace. Superseds.github/workflows/audit.yml. - Pre-commit checks for everything that we enforce (gpg-signed/conventional commits, and some goodies like typos, so docs: fix spelling errors #1086 kind of things are not necessary anymore)
- Instructions and rationale in
NIX.md
Closes #1162. Superseds #1122, #1156, #1165.
Pinneds Dependencies:
-
bitcoind: pinned to 0.25.0 in nixpkgs. -
electrs: pinned toBlockstream's esplorausing the Fedimint deployment, check jkitman/nixpkgs@61ccef8 and https://github.com/fedimint/fedimint/blob/master/flake.nix#L5
TODO:
-
[x] Fix
llvmdeps. -
[x] Fix
opensslerrors. -
[x] Fix dependencies on MacOS.
-
[x] Fix
WASM. -
[x] Fix
MSRV. Add a customCargoMSRV.lock? (Or maybe aCargoMSRV.tomlwith the pinned MSRV dependencies and thencargo generate-lockfilewith Rust MSRV?) Depends on solving fix: buildcrane-utilsusing a different toolchain ipetkov/crane#422 -
[x] move all the logic from
cont_integration.ymltoflake.nix(all thecargo update -p) From the Fedimint suggestion we'll usecrane. This would allow caching of a lot of things Then the user would callnix buid -L .#MSRV --keep-failedand so on. This would also eliminate all the multipleruns-onincont_integration.ymlto a single one where each step would be anameandrunthenix buildcommand. -
[x] Add
DeterminateSystems/magic-nix-cache-actionto cache stuff in CI. -
[x] Update
CONTRIBUTINGwith instructions. Use fedimint instructions for inspiration. -
[x]
nix develop:- [x]
default: Rust latest - [x]
MSRV - [x]
WASM
- [x]
-
[x]
nix flake check:-
[x] clippy
-
[x] audit
-
[x]
rustfmt -
[x] Rust latest
test- [x]
--all-features - [x]
--no-default-features
- [x]
-
[x] MSRV
test- [x]
--all-features - [x]
--no-default-features
- [x]
-
[x] WASM (
--target wasm32-unknown-unknown)test- [x]
-p bdk --no-default-features --features bitcoin/no-std,miniscript/no-std,bdk_chain/hashbrown,dev-getrandom-wasm - [x]
-p esplora --target wasm32-unknown-unknown --no-default-features --features bitcoin/no-std,miniscript/no-std,bdk_chain/hashbrown,async
- [x]
-
[x]
cachix/pre-commit-hooks.nix- [x] signed commits
- [x] conventional commits with
commitizen - [x] typos
- [x]
rustfmt
-
-
[ ] ~Add a CI to update
Cargo.lock~ (is this possible?) -
[x] Add a CI to update
flake.lock -
[x] Delete
.github/workflows/audit.yml -
[x] Port Code Coverage to Nix
-
[x] Nixify the Nightly Docs CI
-
[ ] Add
numtide/devshell -
[x] Clean up commit messages (this is a mess of squash fixup and ammends 😂)
Nix Commands
-
nix flake show: show all possible commands from the flake. -
nix develop: creates adevShellwith all the things you need to develop installed. Also handles ENV vars. Currently isbash,git,ripgrep,bitcoind(pinned),electrs(pinned),openssl,pkg-config,libiconv, and latest stable Rust with all goodies. It also handles specific MacOS deps: Apple XCode SDKs (forbitcoindandelectrsdcrates). Open to suggestions on what to include.-
nix develop .#MSRV: same but with Rust MSRV.
-
-
nix flake check:- checks for typos, gpg-signed commits, conventional commits,
rustfmt,nixpkgs-fmt(.nixfiles). - runs
clippyin all workspace with--all-features --all-targets -- -D warnings. - runs
cargo checkin all workspace (latest stable Rust). - checks dependencies for security advisory using
rustsec/advisory-db. - test everything!!! (see below the individual checks in
.#checks.${system}.{CHECK}
- checks for typos, gpg-signed commits, conventional commits,
-
nix build -L .: runscargo buildin all workspace with latest stable Rust.-
nix build -L .#stable: runscargo buildin all workspace with latest stable Rust. -
nix build -L .#MSRV: runscargo buildin all workspace with MSRV stable Rust. -
PLACEHOLDER: ...
-
-
nix build -L .#checks.${system}.{CHECK}: runs a specificCHECK. In my casesystem = aarch64-darwinthen it isnix build .#checks.aarch64-darwin.CHECK.-
pre-commit-check: checks for typos, conventional commits,nixpkgs-fmt(.nixfiles). -
clippy: runsclippyin all workspace with--all-features --all-targets -- -D warnings. -
fmt: runscargo fmtwith--all -- --check --config format_code_in_doc_comments=truein all workspace with latest Rust. -
audit: checks dependencies for security advisory usingrustsec/advisory-db. -
latest:cargo buildin whole workspace using latest Rust. -
latestAll:cargo test --all-featuresin whole workspace using latest Rust. -
latestNoDefault:cargo test --no-default-featuresin whole workspace using latest Rust. -
latestNoStdBdk:cargo test -p bdk --no-default-features --features bitcoin/no-std,miniscript/no-std,bdk_chain/hashbrownusing latest Rust. -
latestNoStdChain:cargo test -p bdk_chain --no-default-features --features bitcoin/no-std,miniscript/no-std,hashbrownusing latest Rust. -
latestNoStdEsplora:cargo test -p bdk_esplora --no-default-features --features bitcoin/no-std,miniscript/no-std,bdk_chain/hashbrownusing latest Rust. -
MSRV:cargo buildin whole workspace using MSRV Rust. -
MRSVAll:cargo test --all-featuresin whole workspace using MSRV Rust. -
MSRVNoDefault:cargo test --no-default-featuresin whole workspace using MSRV Rust. -
MSRVNoStdBdk:cargo test -p bdk --no-default-features --features bitcoin/no-std,miniscript/no-std,bdk_chain/hashbrownusing MSRV Rust. -
MRSVNoStdChain:cargo test -p bdk_chain --no-default-features --features bitcoin/no-std,miniscript/no-std,hashbrownusing MSRV Rust. -
MSRVNoStdEsplora:cargo test -p bdk_esplora --no-default-features --features bitcoin/no-std,miniscript/no-std,bdk_chain/hashbrownusing MSRV Rust.
-
Notes to the reviewers
-
We are adding automatic pre-commit checks with checks for typos, gpg-signed commits, conventional commits,
nixpkgs-fmt(.nixfiles). This is done automatically if the user has Nix anddevshellinstalled. If not, it will be checked on CI, or with anix flake check. I fixed a bunch of typos and added the.typos.tomlto whitelist somethings like hashes, addresses, etc that were being flagged as false positives. -
I am bumping hashbrown to
0.11.2since it is compatible with MSRV of 1.63 -
I am adding in the building cache/tests a crate name and version. This does not interact with the name or versioning in any of bdk's crates
Cargo.tomlTo avoid this nasty warning in Nix:trace: warning: crane will use a placeholder value since `name` cannot be found in /nix/store/ja4yr1m9ba72gy3pbr2vg540zjdbzp33-source/Cargo.toml to silence this warning consider one of the following: - setting `pname = "...";` in the derivation arguments explicitly - setting `package.name = "..."` or `workspace.package.name = "..."` in the root Cargo.toml - explicitly looking up the values from a different Cargo.toml via `craneLib.crateNameFromCargoToml { cargoToml = ./path/to/Cargo.toml; }` -
We are using
legacyPackagesinstead ofpackagesin thecibuild calls becauselegacyPackagesallows nested sets, e.g.:legacyPackages = ci = { latest = { all = ...; noDefault = ...; ... }; MSRV = { ... }; WASM = { ... }; codeCoverage = ...; };It makes a nice grouping of all CI stuff under the same call:
nix build -L .#ci.latest.{CHECK} -
We are moving from
mozilla/grcovtotaiki-e/cargo-llvm-cov. Why? 3 reasons:- Mozilla's
grcovis a big thing, it does coverage for a lot of things C/C++, JS, Java, and Rust.cargo-llvm-covuses Rust's native coverage tools via LLVM. -
crane(craneLib.cargoLlvmCov) supports nativelycargo-llvm-covwhich will be much easier to make it work and maintain - Our friends at
fedimintalso usecargo-llvm-covwithcraneso it makes easier to collaborate in improvements and issues.
- Mozilla's
Potential issues:
-
We had to remove
Cargo.lockfrom the.gitignore. Nix (crane) needs it for deterministic stuff. From thecraneFAQ:First consider if there is a release of this project available with a lock file as it may be simpler and more consistent to use the exact dependencies published by the project itself. Projects published on crates.io always come with a lock file and nixpkgs has a
fetchCratefetcher which pulls straight from crates.io.Also Rust changed their
Cargo.lockcommit policy a couple months ago:For years, the Cargo team has encouraged Rust developers to commit their Cargo.lock file for packages with binaries but not libraries. We now recommend people do what is best for their project. To help people make a decision, we do include some considerations and suggest committing Cargo.lock as a starting point in their decision making. To align with that starting point, cargo new will no longer ignore Cargo.lock for libraries as of nightly-2023-08-24. Regardless of what decision projects make, we encourage regular testing against their latest dependencies.
-
Mismatch versions between the executables under the
*_EXECenv vars forbitcoind/electrsdcrates and the version the crate thinks to have. -
Centralizes CI maintainability to people that have Nix experience.
-
We are removing the auto-download feature of
bitcoindandelectrsdin thebitcoind_rpcandesploracrates. I added an explanation in the repo and crates'README.mds. This also simplifies a little bit the MSRV pinning of deps.
Changelog notice
Checklists
All Submissions:
- [x] I've signed all my commits
- [x] I followed the contribution guidelines
- [x] I ran
cargo fmtandcargo clippybefore committing
New Features:
- [x] I've added tests for the new feature
- [x] I've added docs for the new feature
Bugfixes:
- [ ] This pull request breaks the existing API
- [x] I've added tests to reproduce the issue which are now passing
- [x] I'm linking the issue being fixed by this PR
How does one update the CargoMSRV.lock file?
After the version of bip39 in the root Cargo.toml file changed to 2.0, I encounter an error when running
nix flake -L check --keep-failed
It appears to involve the 1.2.0 version that's in CargoMSRV.lock.
I tried changing the version to 2.0.0 in the root Cargo.toml
I ran the command
nix flake update
but that didn't update the CargoMSRV.lock file.
I tried removing this lock file, and that didn't work either.
I'm relatively new to nix. Perhaps instructions on handling such version updates in Cargo.toml that involve CargoMSRV.lock would be helpful in the NIX.md file.
Here is the code I started with, rebased to include recent commits to master
It is not that trivial.
-
flake.nix: in theMSRVdevshellchangecargoArtifacts = null;(so that it won't trigger a broken compile when you enter this shell) - enter the
MSRVdevshellwithnix develop .#MSRV -
rm Cargo.lock -
cargo update(then you might need to also pin some deps) - once the thing builds you can
mv Cargo.lock CargoMSRV.lock - reset the change in
cargoArtifactsinflake.nix - reset the removed
Cargo.lock - try
nix flake -L check --keep-failed - commit the new
CargoMSRV.lock
I am planning to fix this and rebase today. This is the workflow that'll be doing.
Thanks, @storopoli !
Last night I ran
nix flake -L check --keep-failed
on commit 2105f99
It ran successfully, except for one set of errors in the middle. I am attaching those errors, from somewhere in the middle of the console output, and a warning at the end of the console output showing which systems were not tested.
The check omitted these incompatible systems: aarch64-darwin, aarch64-linux, x86_64-darwin
The errors were all of the form
crates-audit> error: couldn't check if the package is yanked: not found: No such crate in crates.io index: addr2line
Here are the details of my x86-64 system -
Operating System - NixOS 24.05 (Uakari) Hardware Model - Purism Librem 13 v2 Processor - Intel Core i5-6200U x 4 Memory - 31.3 GB
It's amazing what ground that flake covers!
these are http errors in the cargo-audit check. I am running these fine in my local machine and also in GitHub CI. Maybe your machine is offline or you are blocking crates.io?
these are http errors in the cargo-audit check. I am running these fine in my local machine and also in GitHub CI. Maybe your machine is offline or you are blocking crates.io?
nix build etc. runs in a sandbox and network calls are forbidden there.
These errors might be normal/to be ignored. The advisory-db is passed as a locked input, and not being able to check for yanked crates is just a limitation of running it in Nix, I guess.
BTW. In Fedimint we run the audit by updating the input to the latest version and then doing the update, to always get the audit against current advisories. https://github.com/fedimint/fedimint/blob/59a88ce18c1721acec0db89c6bb97d9ea18af0d9/.github/workflows/ci-nix.yml#L169
BTW. In Fedimint we run the audit by updating the input to the latest version and then doing the update, to always get the audit against current advisories.
Thanks for the tip I added this as well to our CI yml file
Closing in favor of #1320. Cc @yanganto.