Evaluation

Project configuration for Hercules CI is written in the Nix language. Your agent will evaluate the herculesCI attribute of a flake, or, if a repository does not contain flake.nix, the agent will look for that attribute in nix/ci.nix, ci.nix or default.nix.

Inside this expression, Hercules CI looks for an optional but recommended herculesCI attribute. If this attribute is not present, the evaluator will either:

  • if it is a flake, evaluate a default onPush job with sensible defaults, or

  • if it is a ci.nix or default.nix, fall back to the pre-0.9 evaluation behavior.

A simple example of an herculesCI attribute looks as follows:

  herculesCI = { ... }: {
    onPush.default = {
      outputs = { ... }: {
        # Attributes here will be built for each push.
        hello = pkgs.hello;
      };
    };
  };

herculesCI Value

The herculesCI attribute can be a function producing an attribute set. If no parameters are needed, the attribute set can be provided directly instead.

herculesCI Parameters

When you define the herculesCI attribute as a function, it will receive the following arguments, providing context for your CI/CD configuration attributes

ref, branch, tag, rev, shortRev

These strings represent the version and origin of the source that contains the herculesCI attribute.

branch and tag may be null.

primaryRepo

Information about the repository and revision of the sources that led to the herculesCI attribute.

primaryRepo.outPath

A path containing the files of the checked out revision.

primaryRepo.webUrl

Web link to the repository for use in the browser.

primaryRepo.remoteHttpUrl

Git remote URL for cloning, etc via the HTTP(S) protocol.

May be null for (private) forges that are not configured to offer this protocol.

The HTTP protocol is recommended because it - is more often allowed on firewalled networks - lets Hercules CI distribute short-lived tokens to Effects; a secure and convenient alternative to personal access tokens or permanent SSH deploy keys.

This will be an https URL on most forges, except private forges that don’t have TLS enabled.

primaryRepo.remoteSshUrl

Git remote URL for cloning, etc via the SSH protocol.

May be null for (private) forges that are not configured to offer this protocol.

primaryRepo.forgeType

Type of forge the repo is on, e.g. "github".

primaryRepo.owner

The name of the owner of the repository.

primaryRepo.name

The name of the repository.

herculesCI

Information about the Hercules CI instance the agent is connected to. This is mostly for Hercules CI Enterprise users; who self-manage the entire stack.

herculesCI.apiBaseUrl

The base URL of the Hercules CI API. This can be used to differentiate behavior on Hercules CI Enterprise. On non-enterprise agents, the value is https://hercules-ci.com. This matches the configuration file.

herculesCI Attributes

The herculesCI value primarily defines handlers for what to build and run for various events, such as onPush.

onPush

This declares what to do when a Git ref is updated, such as when you push a commit or after you merge a pull request.

If onPush is omitted and your herculesCI attribute is in a flake, Hercules CI will use the flake to generate a default job.

If onPush is set to { }, no jobs will be created for the push event.

If onPush contains attributes, jobs will created for each.

The name will be used as part of the commit status for each resulting job.

onPush.<name>.extraInputs.<inputName> (beta)

Specifies a location to an unpinned dependency. The name chosen for the <inputName> placeholder will be used as an attribute argument for onPush.<name>.outputs Parameters.

onPush.<name>.extraInputs.<inputName>.project (beta)

The name of a repository in the same organization.

onPush.<name>.extraInputs.<inputName>.ref (beta)

A Git ref indicating the branch or tag to check out. Example: refs/heads/staging for a branch called staging.

onPush.<name>.outputs Parameters

The arguments to the outputs are sourced from onPush.<name>.extraInputs.<inputName> (beta), by resolving the inputs to pinned revisions before creating the job.

You can find the pinned revisions in the dashboard or by clicking a commit status.

Other information besides extraInputs can be retrieved from the herculesCI parameters.

onPush.<name>.outputs Attributes

These "output" attributes can be

  • derivations,

  • effects IF added in onPush.<name>.outputs.effects,

  • attribute sets containing further "outputs", in a nested manner,

  • other types, which will be ignored.

During the execution of the job, first, all derivations will be built. If the build went well, all effects will run, concurrently with effects in the same job, but only after preceding jobs have either completed or failed to build.

Derivations, shells and effects

All three are defined through derivations.

  • A derivation marked by the attribute isEffect = true is categorized as an effect and will be run in the effects sandbox. Effects must be defined below the outputs.effects attribute.

  • A derivation marked by the buildDependenciesOnly = true attribute will not be built, but its dependencies will.

  • A derivation with phases = ["noBuildPhase"] is treated as if it had buildDependenciesOnly = true. This includes Nixpkgs' mkShell.

  • A derivation with ignoreFailure = true will be built, but not included in the job status and commit status. This is only useful when a build is unpredictable and irrelevant to the development process. requireFailure may be a better option, to avoid regressions after repairs.

  • A derivation with requireFailure = true will be built and included in the job status and commit status, but with its build status reversed. This is useful during development to track for example which tests are known to fail. If during development a problem is solved, you are required to remove the attribute, which is necessary to avoid regressions.

Attribute sets

Unlike the legacy format and nix-build, nested attribute sets are traversed by default.

You can mark attribute sets not to be traversed by adding an attribute recurseForDerivations = false inside them, as is done by the function lib.dontRecurseIntoAttrs of type attrs → attrs.

onPush.<name>.outputs.effects Attributes

This is this the only location in outputs where effects are allowed.

onSchedule Attributes

Since hercules-ci-agent 0.9.8

Behaves similar to onPush, but is responsible for jobs that respond to the passing of time rather than to a git push or equivalent.

onSchedule is like cron for your projects.

onSchedule.<name>.outputs Attributes

Since hercules-ci-agent 0.9.8

Behaves the same as onPush.<name>.outputs Attributes, but for jobs that respond to the passing of time rather than to a git push or equivalent.

onSchedule.<name>.when Attributes

Since hercules-ci-agent 0.9.8

This attribute set defines at which times a job will be created. Each subattribute represents an equality, all of which will hold at the next planned time. The time zone is UTC.

The minute or hour attributes can be omitted, in which case Hercules CI will pick an arbitrary time for you.

Examples:

  # an arbitrary time of day, once a each day
  when = { };
  # 1 or 2 in the morning before Central European work days
  when = {
    hour = [ 0 ];
    dayOfWeek = [ "Mon" "Tue" "Wed" "Thu" "Fri" ];
  }
  # First Tuesday of the month, arbitrary time of day
  when = {
    dayOfWeek = [ "Tue" ];
    dayOfMonth = [ 1 2 3 4 5 6 7 ];
  }
  • minute: An optional integer representing the minute mark at which a job should be created. Inclusive range: [0 .. 59]. Default: an arbitrary minute.

  • hour: An optional integer or list of integers representing the hours at which a jobs should be created. Inclusive range: [0 .. 23]. Default: a single arbitrary hour.

  • dayOfWeek: An optional list of strings representing the days during which jobs should be created. Valid items are "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun". Default: all days of the week.

  • dayOfMonth: A list of integers representing the days of the month during which jobs should be created. Inclusive range: [1 .. 31]. Default: all days of the month. Combining with dayOfWeek further reduces the number of jobs.

Default onPush job

When the herculesCI.onPush attribute is omitted, Hercules CI will supply a default definition.

This will build the flake attributes:

  • packages

  • checks

  • devShell

  • devShells

  • apps

  • nixosConfigurations

  • darwinConfigurations

  • effects

If effects is a function, it will receive the same arguments as the herculesCI attribute.

Ignored attributes

The following attributes are silently ignored, because they do not have a well-defined or independently testable structure.

  • overlays

  • submodules

  • nixosModules

  • darwinModules

  • legacyPackages

Unknown attributes are also ignored and produce a trace line in the evaluation log.

Default systems

The herculesCI attribute, if it exists, is read for its ciSystems attribute; an optional list of "system" strings. If specified, it restricts the job to just the listed architecture-platform combinations.