GitHub Actions
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.
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
Let's first prepare the job environment for devenv.
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v26
- uses: cachix/cachix-action@v14
with:
name: devenv
- name: Install devenv.sh
run: nix profile install nixpkgs#devenv
The above snippet does the following:
- Checks out the repository.
- 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
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.
Run a single command
Single commands can be passed to devenv shell
to be run in the devenv shell.
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-bye
Overriding 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.
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@v4
- uses: cachix/install-nix-action@v26
- uses: cachix/cachix-action@v14
with:
name: devenv
- name: Install devenv.sh
run: nix profile install 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-bye