Nix Develop for Github Actions

Here’s something small that I hope will be useful for people who:

  • run tasks for a project in GitHub Actions
  • specify dependencies for those tasks in flake devShells (or at least see the benefits of doing that, maybe as a migration step towards having builds fully specified as derivations)

It probably won’t be useful to people who:

  • already have all their builds and tests specified as derivations, and in CI only need to run nix flake check
  • don’t use GitHub Actions

If you’re in that first set of people, you might write your GitHub jobs like this (credit to DeterminateSystems/nix-github-actions, which was an inspiration):

      - run: |
          nix develop --command \
            cargo fmt --check
      - run: |
          nix develop --command \
            cargo-deny check
      - run: |
          nix develop --command \
            eclint \
              -exclude "Cargo.lock"
      - run: |
          nix develop --command \
            codespell \
              --skip target,.git \
              --ignore-words-list crate

But now, you could do this instead:

      - uses: nicknovitski/nix-develop@1
      - run: cargo fmt --check
      - run: cargo-deny check
      - run: eclint \
               -exclude "Cargo.lock"
      - run: codespell \
              --skip target,.git \
              --ignore-words-list crate

It’s nix develop for GitHub Actions, and that’s it! It’s only a few dozens lines of bash but it works like a typical setup-*-style GitHub action:

  • in the step which uses: it, everything it needs is downloaded or built
  • in all subsequent steps, any variables in the shell environment will be set, and any binary dependencies of the shell environment will be added the PATH

I wanted to make something like this so that people who were used to those kinds of setup-* actions had something which behaved like them. I hoped that this would make taking the first steps towards a fully nix-specified build process a bit easier for them.

Also, it even works with other third-party actions! For example, I wanted to do this in a javascript project which used yarn:

      - uses: nicknovitski/nix-develop@1 # installs nodejs and yarn
      - uses: actions/setup-node@4
        with:
          cache: yarn # requires `yarn` to already be installed, but ensures the language packages are cached correctly!

(I can’t use that as an example without saying that ideally in that situation I would use the great yarn-plugin-nixify instead.)

Of course it can take arbitrary nix develop arguments:

      - uses: nicknovitski/nix-develop@1
        with:
          arguments: ./#ci # maybe your default devShell is only for local development
      - uses: nicknovitski/nix-develop@1
        with:
          arguments: --impure --keep PATH # maybe you use [devenv](https://devenv.sh/guides/using-with-flakes/)

I hope this helps someone somewhere. And if I’ve made any errors, I hope someone can help me instead! :sweat_smile:

8 Likes