In-repo Configuration

You can configure nix-ci on a per-commit basis by adding a nix-ci.nix file in your repository.

It has to be a single self-contained file. NixCI reads it straight out of your forge, without cloning your repository, so a configuration that imports another file is rejected rather than read. Everything in it is plain data, so there is rarely a reason to split it up: inline what you would have imported.

Validator

You can use this validator to validate your configuration without having to push a commit.

Run this command in your repository to validate your configuration:

nix eval --json --file ./nix-ci.nix | curl --netrc -H "Content-Type: application/json" -d @- https://nix-ci.lector.ai/documentation/configuration

Alternatively, you can run nix eval --json --file ./nix-ci.nix and paste the output below.

Reference schema

# SuiteConfiguration
enable: # optional
  # default: true
  # Enable CI
  <boolean>
systems: # optional
  # Only build for these systems. By default these are computed based on which workers are available for the repository.
  # or null
  - <string>
onlyBuild: # optional
  # Only build these attributes.
  # This does not affect test or deploy jobs.
  # or null
  - <string>
doNotBuild: # optional
  # Exclude these attributes from building.
  # This does not affect test or deploy jobs.
  # or null
  - <string>
timeout: # optional
  # Maximum timeout, in seconds. Note that the actual timeout may depend on the workers' configuration.
  <number>
cache: # optional
  # Ssh Cache configuration
  # In order to push to the cache as well, the repository needs to have a SSH_CACHE_PRIVATE_KEY secret.
  # SshCacheConfiguration
  name: # optional
    # ssh cache name, for logging
    <string>
  # any of
  [ domain: # required
      # cache domain, example: cache.nix-ci.com
      <string>
  , url: # required
      # cache url, example: ssh://cache.nix-ci.com
      <string>
  ]
  user: # optional
    # ssh user, defaults to the worker user
    <string>
  host-key: # optional
    # ssh host key
    <string>
  public-key: # required
    # ssh public key
    <string>
  cache-public-key: # optional
    # cache verification public key
    <string>
cachix: # optional
  # Cachix configuration
  # In order to push to the cache as well, the repository needs to have a CACHIX_AUTH_TOKEN or CACHIX_SIGNING_KEY secret.
  # CachixConfiguration
  name: # required
    # cache name
    <string>
  public-key: # required
    # cache public key (for pulling)
    <string>
allow-import-from-derivation: # optional
  # Allow import-from-derivation during evaluation.
  # default: True
  <boolean>
shallow-clone: # optional
  # Fetch only the commit being built, not its whole history.
  # Set false for a flake that reads self.revCount, which has nothing to count without the history.
  # In-repo test and deploy jobs ignore this and fetch the whole history.
  # default: True
  <boolean>
impure: # optional
  # Build with --impure
  # default: False
  <boolean>
build-logs: # optional
  # Build with --print-build-logs
  # default: True
  <boolean>
fail-fast: # optional
  # Cancel the rest of a suite once one job fails
  # default: True
  <boolean>
auto-retry: # optional
  # Automatically retry every individual failed run in a suite once
  # default: True
  <boolean>
dependency-discovery: # optional
  # Dependency discovery configuration
  # any of
  [ # true: enable dependency discovery (synchronous defaults to False)
    # false: disable dependency discovery
    <boolean>
  , # DependencyDiscovery
    enable: # optional
      # default: true
      # Enable automatic dependency discovery
      # default: True
      <boolean>
    synchronous: # optional
      # default: false
      # Wait for dependency detection to finish before starting builds
      # default: False
      <boolean>
  ]
dependencies: # optional
  # Additional build dependencies on top of what is discovered automatically. A map from attribute to a list of attributes it depends on.
  # or null
  <key>: 
    - <string>
fail-on-dangling-dependencies: # optional
  # Fail the build when a configured build dependency references a job that does not exist.
  # When false, such a dangling dependency is reported as a warning and ignored instead.
  # default: False
  <boolean>
test: # optional
  # default: {}
  # Test Configurations
  <key>: 
    # TestConfiguration
    enable: # optional
      # default: true
      # enable this test
      <boolean>
    package: # required
      # package of which the main program will be run
      <string>
    system: # optional
      # system on which the test will be run
      <string>
    branches: # optional
      # default: :any
      # branches from which may be tested
      # any of
      [ # one of
        [ # the branches to run on, with nothing excluded
          # any of
          [ # every ref
            :any
          , # the repository's default branch
            :default
          , # a branch name, or a glob pattern: * matches within one segment, ** across them, ? a single character
            <string>
          , # every ref; deprecated, write :any instead
            any
          , # every ref; deprecated, write :any instead
            all
          , # the repository's default branch; deprecated, write :default instead
            default
          , - # any of
              [ # every ref
                :any
              , # the repository's default branch
                :default
              , # a branch name, or a glob pattern: * matches within one segment, ** across them, ? a single character
                <string>
              , # every ref; deprecated, write :any instead
                any
              , # every ref; deprecated, write :any instead
                all
              , # the repository's default branch; deprecated, write :default instead
                default
              ]
          ]
        , # BranchFilter
          run-on: # optional
            # default: :any
            # branches to run on
            # any of
            [ # every ref
              :any
            , # the repository's default branch
              :default
            , # a branch name, or a glob pattern: * matches within one segment, ** across them, ? a single character
              <string>
            , # every ref; deprecated, write :any instead
              any
            , # every ref; deprecated, write :any instead
              all
            , # the repository's default branch; deprecated, write :default instead
              default
            , - # any of
                [ # every ref
                  :any
                , # the repository's default branch
                  :default
                , # a branch name, or a glob pattern: * matches within one segment, ** across them, ? a single character
                  <string>
                , # every ref; deprecated, write :any instead
                  any
                , # every ref; deprecated, write :any instead
                  all
                , # the repository's default branch; deprecated, write :default instead
                  default
                ]
            ]
          do-not-run-on: # optional
            # default: []
            # branches not to run on, even when they are in "run-on"
            # any of
            [ # every ref
              :any
            , # the repository's default branch
              :default
            , # a branch name, or a glob pattern: * matches within one segment, ** across them, ? a single character
              <string>
            , # every ref; deprecated, write :any instead
              any
            , # every ref; deprecated, write :any instead
              all
            , # the repository's default branch; deprecated, write :default instead
              default
            , - # any of
                [ # every ref
                  :any
                , # the repository's default branch
                  :default
                , # a branch name, or a glob pattern: * matches within one segment, ** across them, ? a single character
                  <string>
                , # every ref; deprecated, write :any instead
                  any
                , # every ref; deprecated, write :any instead
                  all
                , # the repository's default branch; deprecated, write :default instead
                  default
                ]
            ]
        ]
      , # true means every ref, false means none
        <boolean>
      ]
    in-repo: # optional
      # Run the job in a checkout of the repository at the right revision
      # default: False
      # Setting this to false is more efficient if the job doesn't need to access to git history.
      # You can use ${self} to refer to the flake source if you need access to the repository contents at the current commit only.
      <boolean>
    secrets: # optional
      # default: []
      # secrets provided to the test
      - <string>
    ssh-keys: # optional
      # default: []
      # ssh keys provided to the test
      - # SshKeyConfiguration
        secret: # required
          # name of the secret on NixCI to use as the private key
          <string>
        public-key: # required
          # public key of the ssh key
          <string>
deploy: # optional
  # default: {}
  # Deploy Configurations
  <key>: 
    # DeployConfiguration
    enable: # optional
      # default: true
      # enable this deployment
      <boolean>
    package: # required
      # package of which the main program will be run
      <string>
    system: # optional
      # system on which the deployment will be run
      <string>
    branches: # optional
      # default: :default
      # branches from which may be deployed
      # any of
      [ # one of
        [ # the branches to run on, with nothing excluded
          # any of
          [ # every ref
            :any
          , # the repository's default branch
            :default
          , # a branch name, or a glob pattern: * matches within one segment, ** across them, ? a single character
            <string>
          , # every ref; deprecated, write :any instead
            any
          , # every ref; deprecated, write :any instead
            all
          , # the repository's default branch; deprecated, write :default instead
            default
          , - # any of
              [ # every ref
                :any
              , # the repository's default branch
                :default
              , # a branch name, or a glob pattern: * matches within one segment, ** across them, ? a single character
                <string>
              , # every ref; deprecated, write :any instead
                any
              , # every ref; deprecated, write :any instead
                all
              , # the repository's default branch; deprecated, write :default instead
                default
              ]
          ]
        , # BranchFilter
          run-on: # optional
            # default: :any
            # branches to run on
            # any of
            [ # every ref
              :any
            , # the repository's default branch
              :default
            , # a branch name, or a glob pattern: * matches within one segment, ** across them, ? a single character
              <string>
            , # every ref; deprecated, write :any instead
              any
            , # every ref; deprecated, write :any instead
              all
            , # the repository's default branch; deprecated, write :default instead
              default
            , - # any of
                [ # every ref
                  :any
                , # the repository's default branch
                  :default
                , # a branch name, or a glob pattern: * matches within one segment, ** across them, ? a single character
                  <string>
                , # every ref; deprecated, write :any instead
                  any
                , # every ref; deprecated, write :any instead
                  all
                , # the repository's default branch; deprecated, write :default instead
                  default
                ]
            ]
          do-not-run-on: # optional
            # default: []
            # branches not to run on, even when they are in "run-on"
            # any of
            [ # every ref
              :any
            , # the repository's default branch
              :default
            , # a branch name, or a glob pattern: * matches within one segment, ** across them, ? a single character
              <string>
            , # every ref; deprecated, write :any instead
              any
            , # every ref; deprecated, write :any instead
              all
            , # the repository's default branch; deprecated, write :default instead
              default
            , - # any of
                [ # every ref
                  :any
                , # the repository's default branch
                  :default
                , # a branch name, or a glob pattern: * matches within one segment, ** across them, ? a single character
                  <string>
                , # every ref; deprecated, write :any instead
                  any
                , # every ref; deprecated, write :any instead
                  all
                , # the repository's default branch; deprecated, write :default instead
                  default
                ]
            ]
        ]
      , # true means every ref, false means none
        <boolean>
      ]
    in-repo: # optional
      # Run the job in a checkout of the repository at the right revision
      # default: False
      # Setting this to false is more efficient if the job doesn't need to access to git history.
      # You can use ${self} to refer to the flake source if you need access to the repository contents at the current commit only.
      <boolean>
    secrets: # optional
      # default: []
      # secrets provided to the deployment
      - <string>
    ssh-keys: # optional
      # default: []
      # ssh keys provided to the deployment
      - # SshKeyConfiguration
        secret: # required
          # name of the secret on NixCI to use as the private key
          <string>
        public-key: # required
          # public key of the ssh key
          <string>