Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nix devShell and Nix-based GitHub Actions build using nix develop #1648

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

msgilligan
Copy link
Contributor

@msgilligan msgilligan commented Feb 23, 2025

This PR adds a flake.nix (and flake.lock) file that can be used to create a Nix development shell for Sparrow. For interactive use (assuming the user has Nix installed and flakes enabled) the shell can be started with:

nix develop

The GitHub Actions package.yaml file has been extended with a job that does a full build of the Sparrow jpackage using the following build command:

nix develop -c gradle jpackage

The flake.lock file makes a snapshot of all the dependencies and makes the build somewhat reproducible (dependencies are still loaded via Maven.)

The flake.nix file could be extended with a full, reproducible Nix build that would run in a sandbox with no network access and no access to undeclared objects in the file system. But this is a good first step towards that.

@msgilligan msgilligan marked this pull request as draft February 23, 2025 20:41
@msgilligan msgilligan force-pushed the msgilligan/gha-package-nix-test branch 6 times, most recently from 8001f49 to 16c5472 Compare February 25, 2025 01:34
@msgilligan msgilligan changed the title WIP: basic Nix-based build using nix develop -c Nix devShell and Nix-based GitHub Actions build using nix develop -c gradle jpackage Feb 25, 2025
@msgilligan msgilligan marked this pull request as ready for review February 25, 2025 01:48
@msgilligan
Copy link
Contributor Author

Here is the successful run: https://github.com/msgilligan/sparrow/actions/runs/13511693733

@craigraw
Copy link
Collaborator

This is cool, but I am struggling a bit with the "why?" on this, since it appears the major benefit of using Nix is reproducibility, which Sparrow already has. It appears on the surface to be a more complex build setup.

@msgilligan
Copy link
Contributor Author

msgilligan commented Feb 25, 2025

This is cool, but I am struggling a bit with the "why?" on this, since it appears the major benefit of using Nix is reproducibility, which Sparrow already has. It appears on the surface to be a more complex build setup.

It's reproducibility "ab ovo" -- all the way back to the beginning. Similar to how Bitcoin Core uses GUIX. It's often called "bootstrappable" to distinguish from the reproducibility that Sparrow (and bitcoinj) currently have.

See:

It's a goal of mine to be able to verify build from source on secp-jdk and bitcoinj all the way back to the "first" C compiler. And I would like to help move Sparrow in this direction, too. I view this as a long-term project (that will likely take several years.) But each step along the way IMO will increase quality and trustworthiness.

A short term goal for me is to just be able to install Sparrow via Nixpkgs. The current Sparrow in Nixpkgs is x86_64-linux only: https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/applications/blockchains/sparrow/default.nix#L285. A long term goal is to be able to run Sparrow on a Linux Computer running NixOS with every piece of software in the system built with bootstrappable reproducibility.

We've made progress on bitcoinj, but have a way to go. Our base module now only depends on the JDK itself and only two jars (slf4japi and a jar for nullability annotations), the secp-jdk -api module only depends on JSpecify (the new/best solution for nullability annotation.)

I know that Sparrow is a much more complicated beast, but I believe we can work on it one-step-at-a-time without too much impact on the rest of the Sparrow project.

I'm fairly new to Nix, but I am focused on applying it to building the TEE enclave software that I am working on. I've also been applying it to bitcoinj + secp-jdk as a "side-project". It's also easier for me to apply it to Java (than Rust) because I am much more familiar with the build tools.

I find there are many other benefits to using Nix/Nixpkgs/NixOS, though the learning curve is steep. So, if you're at all interested, I'm happy to send PRs that provide and improve a Nix-based build and spend some time helping you get up to speed. This would all be in parallel to the existing build process, although at some point in the future if the Nix-build is looking good and wins your trust you could certainly switch over. This is the same approach I'm using for secp-jdk and bitcoinj. sec-jdk will hopefully be released into production with a Nix-based build, but this is not guaranteed. bitcoinj has yet to merge any Nix code onto its master branch, but I'll likely create a PR very similar to this one that is very limited in scope and I hope Andreas will approve it. (The current WIP PR is to broad in scope and should be reproduced to just the devShell approach for a first step.)

If you're not interested and/or want to postpone until later, I'll understand. I've got plenty of fish to fry. But I do like the idea of a "full stack" build that goes all the way from OS to libraries to desktop app. Let me know what you think!

@msgilligan
Copy link
Contributor Author

BTW, one of the best introductions to Nix is Section 2 of the original GUIX white paper: https://arxiv.org/abs/1305.4584 -- In about 1 page it explains the big picture very well.

@craigraw
Copy link
Collaborator

Thanks for the explanation :) Clearly I have much to learn about Nix.

I know that Sparrow is a much more complicated beast, but I believe we can work on it one-step-at-a-time without too much impact on the rest of the Sparrow project.

In line with this, does it make sense to put the nix_jpackage job into it's own yaml file - say nix-jpackage.yaml? That way it can be triggered independently, and as I don't think there are any artifacts uploaded by the nix_jpackage job, it makes it simpler to manage as an independent unit.

Is it possible to perform a Windows build of Sparrow using this approach?

With respect to merging, I'll need to wait until Sparrow migrates to JDK 23 before merging this to avoid confusion.

@msgilligan
Copy link
Contributor Author

Thanks for the explanation :) Clearly I have much to learn about Nix.

A good way to get started with Nix, and to learn about it on your own time is to install and use Home Manager: https://github.com/nix-community/home-manager

You can use it on Ubuntu/Debian or on macOS and in its simplest form can be used as a config file that lists packages to install via Nixpkgs. It is especially useful if you want to share configuration between systems. On macOS it co-exists well with HomeBrew and SDKMAN! and on Linux with apt and SDKMAN!.

does it make sense to put the nix_jpackage job into it's own yaml file - say nix-jpackage.yaml?

Yes. I will revise this PR to do that.

Is it possible to perform a Windows build of Sparrow using this approach?

I haven't done it, yet. But I am game for trying.

I'm sure it's possible using cross-platform build tools. I'm not sure what the state of jpackage is these days. Can you run jpackage on Linux to make a Windows exe?

With respect to merging, I'll need to wait until Sparrow migrates to JDK 23 before merging this to avoid confusion.

Of course.

@msgilligan msgilligan force-pushed the msgilligan/gha-package-nix-test branch 2 times, most recently from 8042277 to 1feb27a Compare February 25, 2025 19:14
@msgilligan
Copy link
Contributor Author

@craigraw I made the suggested change and made sure it ran correctly: https://github.com/msgilligan/sparrow/actions/runs/13529101842

(forgive my hack to make it run, but the "Nix Package" workflow wasn't showing up for me in the GUI, so I temporarily added a 'on push' trigger and then removed it)

msgilligan added a commit to msgilligan/sparrow that referenced this pull request Feb 25, 2025
* Change job label from `build` to `jpackage`
* Add a `name` attribute setting name with matrix.os

This matches the format of `nix-jpackage.yaml` in PR sparrowwallet#1648
to keep them similar assuming it is merged as is.
@craigraw
Copy link
Collaborator

On reflection can nix-jpackage.yaml be renamed to package-nix.yaml and the job name renamed to

    name: build-nix (${{ matrix.os }})

@msgilligan msgilligan force-pushed the msgilligan/gha-package-nix-test branch from 1feb27a to 274bdb6 Compare February 26, 2025 21:22
msgilligan added a commit to msgilligan/sparrow that referenced this pull request Feb 26, 2025
* Add a `name` attribute setting job name with matrix.os

This matches the format of `nix-jpackage.yaml` in PR sparrowwallet#1648
to keep them similar assuming both PRs are merged as is.
@msgilligan msgilligan changed the title Nix devShell and Nix-based GitHub Actions build using nix develop -c gradle jpackage Nix devShell and Nix-based GitHub Actions build using nix develop Feb 26, 2025
This is not a full (i.e. isolated, reproducible) Nix build, but does
verify that the Nix devShell in `flake.nix` works and that we can successfully
build Sparrow with Gradle and JDK provided by Nix.
@msgilligan msgilligan force-pushed the msgilligan/gha-package-nix-test branch from 274bdb6 to 1209e26 Compare February 26, 2025 21:25
@msgilligan
Copy link
Contributor Author

On reflection can [the file] be renamed ... and the job name renamed...

@craigraw Done. Rebased and force-pushed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants