Continuous Integration setup (CI)
Traditionally, the CI build environment has to be kept in sync with the
project. If the project needs make
to build, the CI has to be configured to
have it available. This can become quite tricky whenever a version requirement
changes.
With devshell, the only dependency is Nix. Once the devshell is built, all the dependencies are loaded into scope and automatically are in sync with the current code checkout.
General approach
The only dependency we need installed in the CI environment is Nix.
Assuming that the shell.nix
file exists, the general approach is to build it
with nix to get back the entrypoint script. And then executed that script with
the commands.
For example, let's say that make
is being used to build the project.
The devshell.toml
would have it as part of its commands:
[[commands]]
package = "gnumake"
All the CI has to do, is this: nix-shell --run "$(nix-build shell.nix)/entrypoint make"
.
$(nix-build shell.nix)/entrypoint
outputs a path to the entrypoint scriptnix-shell --run
sets the required environment variables for the entrypoint script to work.- The entrypoint script is executed with
make
as an argument. It loads the environment. - Finally make is executed in the context of the project environment, with all the same dependencies as the developer's.
Hercules CI
Hercules CI is a Nix-based continuous integration and deployment service.
Build
If you haven't packaged your project with Nix or if a check can't run in the Nix sandbox, you can run it as an effect.
ci.nix
let
shell = import ./shell.nix {};
pkgs = shell.pkgs;
effectsSrc =
builtins.fetchTarball "https://github.com/hercules-ci/hercules-ci-effects/archive/COMMIT_HASH.tar.gz";
inherit (import effectsSrc { inherit pkgs; }) effects;
in
{
inherit shell;
build = effects.mkEffect {
src = ./.;
effectScript = ''
go build
'';
inputs = [
shell.hook
];
};
}
Replace COMMIT_HASH by the latest git sha from hercules-ci-effects
,
or, if you prefer, you can bring effects
into scope using another pinning method.
Run locally
The hci
command is available in nixos-21.05
and nixos-unstable
.
devshell.toml
[[commands]]
package = "hci"
Use hci effect run
. Following the previous example:
hci effect run build --no-token
Shell only
To build the shell itself on x86_64-linux
:
ci.nix
{
shell = import ./shell.nix {};
# ... any extra Nix packages you want to build; perhaps
# pkgs = import ./default.nix {} // { recurseForDerivations = true; };
}
system
If you build for multiple systems, pass system
:
import ./shell.nix { inherit system; };
GitHub Actions
Add the following file to your project. Replace the <your build command>
part with whatever is needed to build the project.
.github/workflows/devshell.yml
name: devshell
on:
push:
branches:
- master
pull_request:
workflow_dispatch:
jobs:
build:
strategy:
matrix:
os: [ ubuntu-20.04, macos-latest ]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- uses: cachix/install-nix-action@v12
- uses: cachix/cachix-action@v8
with:
name: "<your cache here>"
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
- run: |
source "$(nix-build shell.nix)"
<your build command>
TODO
Add more CI-specific examples.