Skip to content

Continuous Integration with Nix

Théo Zimmermann edited this page Nov 23, 2018 · 17 revisions

Generic setup

Creating a .travis.yml file with the following content:

language: nix

script:
- nix-build --argstr coq-version-or-url "$COQ" --extra-substituters https://coq.cachix.org --trusted-public-keys "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= coq.cachix.org-1:Jgt0DwGAUo+wpxCM52k2V+E0hLoOzFPzvg94F65agtI="

env:
- COQ=https://github.com/coq/coq/tarball/master
- COQ=8.9
- COQ=8.8

and a default.nix file with the following content:

{ pkgs ? (import <nixpkgs> {}), coq-version-or-url, shell ? false }:

let
  coq-version-parts = builtins.match "([0-9]+).([0-9]+)" coq-version-or-url;
  coqPackages =
    if coq-version-parts == null then
      pkgs.mkCoqPackages (import (fetchTarball coq-version-or-url) {})
    else
      pkgs."coqPackages_${builtins.concatStringsSep "_" coq-version-parts}";
in

with coqPackages;

pkgs.stdenv.mkDerivation {

  name = "my-project-name";

  propagatedBuildInputs = [
    coq
    # list other dependencies, for instance:
    ssreflect
  ];

  src = if shell then null else ./.;

  installFlags = "COQLIB=$(out)/lib/coq/${coq.coq-version}/";
}

allows to setup Continuous Integration on Travis using Nix.

This is the essential part of the setup that is proposed in templates/ for coq-community projects. Note that the actual .travis.yml is actually more complex because it also contains logic to test the opam file.

Simpler setup

The very long line nix-build --argstr coq-version-or-url "$COQ" --extra-substituters https://coq.cachix.org --trusted-public-keys "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= coq.cachix.org-1:Jgt0DwGAUo+wpxCM52k2V+E0hLoOzFPzvg94F65agtI=" includes logic for fetching binaries for the development version of Coq from https://coq.cachix.org. Without it, the line would just be nix-build --argstr coq-version-or-url "$COQ" but the development version of Coq would be built every time CI is run. If you don't need to test the development version, the logic can thus be reduced to the following:

language: nix

script:
- nix-build --argstr coq-version-or-url "$COQ"

env:
- COQ=8.9
- COQ=8.8

And if your project depends on a very specific version of Coq, you may even hard-code it, which would give a trivial .travis.yml file:

language: nix

and a reduced default.nix:

{ pkgs ? (import <nixpkgs> {}), shell ? false }:

with pkgs.coqPackages_8_9;

pkgs.stdenv.mkDerivation {

  name = "my-project-name";

  propagatedBuildInputs = [
    coq
    # list other dependencies, for instance:
    ssreflect
  ];

  src = if shell then null else ./.;

  installFlags = "COQLIB=$(out)/lib/coq/${coq.coq-version}/";
}

Learning more

Alternative setup

An alternative method for setting up Continuous Integration for Coq projects is to use the opam + Docker setup described at: https://github.com/coq-community/docker-coq/wiki/CI-setup

Both setups are equally encouraged and may be used by projects from both inside and outside coq-community.