From 2e59767da80a8eda535187331a5b09abb49744d8 Mon Sep 17 00:00:00 2001 From: Youwen Wu Date: Wed, 1 Jan 2025 03:50:02 -0800 Subject: [PATCH] feat: add continuous integration notes --- content/Hacks/nixos-cheat-sheet.md | 35 ++++++++++++++++++++ content/Hacks/nixos-ci.md | 51 ++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 content/Hacks/nixos-ci.md diff --git a/content/Hacks/nixos-cheat-sheet.md b/content/Hacks/nixos-cheat-sheet.md index 68ba015..c1e0ea2 100644 --- a/content/Hacks/nixos-cheat-sheet.md +++ b/content/Hacks/nixos-cheat-sheet.md @@ -125,6 +125,41 @@ stdenv.mkDerivation { } ``` +### Automatic updating derivations + +Nix is powerful but also annoying at times. One of the most common issues is +how to automatically keep a derivation up to date. + +When you fetch remote files in Nix, you need to provide Nix with a hash so that +it can guarantee the output is reproducible. This is a consequence of network +only being available in the "fixed output derivation". + +When we automatically update a Nix derivation's sources, we need to take care +to both update the URL or revision and also the corresponding output hash. + +The hash can be obtained using the `nix store prefetch-file` command, which +replaces the old and inferior `nix-prefetch-url`. + +However this command doesn't return a clean hash that we can just pipe around +in our shell. We can add the `--json` flag and get a JSON object with the hash +in the `hash` property. Such as the following: + +```nu +# this is a nushell script because i hate jq +nix store prefetch-file https://my-file.com/file --json | from json | get hash +``` + +We can then take our new URL and hash and then update our derivation. One way +to do this is with `sed` to modify the derivation in place, but this is kind of +janky. Another way is to create a JSON file that contains the URL and hash and +read it from Nix using `builtins.readFile` and `builtins.fromJSON`. This is +much easier since you can trivially generate JSON files using shell commands +(especially in Nushell). + +The above process can be ran in CI to have fully automatic updating +derivations. See [[continuous-integration-in-nix-projects]] for writing on Nix +in CI. + ## nixpkgs and the nixpkgs lib General stuff related to quirks in nixpkgs and `lib`. diff --git a/content/Hacks/nixos-ci.md b/content/Hacks/nixos-ci.md new file mode 100644 index 0000000..f185c12 --- /dev/null +++ b/content/Hacks/nixos-ci.md @@ -0,0 +1,51 @@ +--- +id: nixos-ci +aliases: [] +tags: [] +--- + +# Continuous integration in Nix projects + +This is where I'm keeping all of my research and notes on continuous +integration in the Nix ecosystem. + +One of the very powerful parts of using Nix to manage your project builds and +dependencies is being able to have one single source of truth, for development, +deployment, and CI. You write your Nix expressions once and get the same +environment everywhere. No need to specify dependencies again and again for +every single environment. Mitchell Hashimoto has written about this extensively +[on his +blog](https://mitchellh.com/writing/nix-with-dockerfiles). + +## Basic GitHub action + +A guilty habit I've gotten into is setting up CI for every single project I +work on and really putting those GitHub actions free minutes to use. It's so +trivial when using Nix, since you literally don't have to do anything extra the +majority of the time. Just copy paste in a GitHub action that installs Nix and +runs `nix build`. That's it. + +```yaml +name: "Check and build flake" +on: + pull_request: + push: + branches: [main] + +jobs: + lints: + name: Build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Check flake inputs + uses: DeterminateSystems/flake-checker-action@v4 + - name: Install Nix + uses: DeterminateSystems/nix-installer-action@main + - uses: DeterminateSystems/magic-nix-cache-action@main + - run: nix flake check --all-systems + - run: nix build . +``` + +This action can basically be dropped in as-is to a Nix project and start +providing basic CI.