Using devenv in GitHub Actions
GitHub Actions
Section titled “GitHub Actions”Introduction
Section titled “Introduction”GitHub Actions is a continuous integration (CI) platform built into GitHub.
Devenv allows you to reuse your existing development environment in your GitHub Actions workflows to run checks, builds, tests, and more.
This guide will go through the steps required to set up devenv in a GitHub Actions workflow and show you how to run commands in the devenv shell. We’ll use the following sample devenv configuration in our examples.
{ pkgs, ... }:
{ packages = [ pkgs.hello ];
scripts.say-bye.exec = '' echo bye '';}The hello package is a program that prints “Hello, world!” and the custom say-bye script prints “bye”.
A complete workflow example is available at the end of this guide.
Prerequisites
Section titled “Prerequisites”Let’s first prepare the job environment for devenv.
steps:- uses: actions/checkout@v5- uses: cachix/install-nix-action@v31- uses: cachix/cachix-action@v16 with: name: devenv- name: Install devenv.sh run: nix profile add nixpkgs#devenvThe above snippet does the following:
- Installs and sets up Nix.
- Configures Nix to use the devenv cache provided by Cachix to speed up the installation.
- Installs devenv.
If you’re using a self-hosted runner, you can pre-install both Nix and devenv, and skip the associated steps.
devenv test
Section titled “devenv test”Devenv provides a convenient built-in devenv test command.
It builds the shell and runs any defined git hooks against your repository.
This is a quick and easy way to test that your development environment works as expected and lint your code at the same time.
- name: Build the devenv shell and run any git hooks run: devenv testRun a single command
Section titled “Run a single command”Single commands can be passed to devenv shell to be run in the devenv shell.
- name: Run a single command in the devenv shell run: devenv shell helloBuilding shell ...Hello, world!Run multiple commands
Section titled “Run multiple commands”Each run step in a job launches a separate shell.
That’s why we can’t just run devenv shell in one run step and have all subsequent commands run in the same devenv shell.
Instead, we can use the shell option
to override the default shell for the current step and replace it with the devenv shell.
- name: Run a multi-line command in the devenv shell shell: devenv shell bash -- -e {0} run: | hello say-byeBuilding shell ...Hello, world!byeOverriding the shell can become quite tedious when you have a lot of separate run steps.
You can use the defaults.run
option to set devenv as the default shell for all run steps in a job.
defaults: run: shell: devenv shell bash -- -e {0}When setting the default shell, the “Install devenv.sh” step must be amended as follows, so that it does not attempt to use a devenv shell:
- name: Install devenv.sh shell: bash run: nix profile add nixpkgs#devenvComplete Example
Section titled “Complete Example”Let’s put all of the above together in a complete example workflow.
name: "Test"
on: pull_request: push:
jobs: tests: strategy: matrix: os: [ubuntu-latest, macos-latest] runs-on: ${{ matrix.os }}
steps: - uses: actions/checkout@v5 - uses: cachix/install-nix-action@v31 - uses: cachix/cachix-action@v16 with: name: devenv - name: Install devenv.sh run: nix profile add nixpkgs#devenv
- name: Build the devenv shell and run any pre-commit hooks run: devenv test
- name: Run a single command in the devenv shell run: devenv shell hello
- name: Run a multi-line command in the devenv shell shell: devenv shell bash -- -e {0} run: | hello say-byeUsing with Nix Flakes
Section titled “Using with Nix Flakes”If you’re using devenv with Nix Flakes and nix develop to set the shell for a step, you may need to wrap the command in bash.
This sets the necessary environment variables for devenv to work inside the restrictive flake shell.
- name: Run command in flake shell shell: bash -c "nix develop --impure -c bash -- {0}" run: devenv test
