{ lib, cilib, ... }: let inherit (lib) mkOption types filterAttrs; inherit (cilib.helpers) filterUnset mkUnsetOption; in rec { jobConfigSubmodule = {pipelineConfig, ...}: { options = { enable = mkOption { description = '' Transform this job to a nix-configured one. ''; type = types.bool; default = pipelineConfig.nixJobsByDefault; }; deps = mkOption { description = '' Dependencies to inject into the job before running it. ''; type = types.listOf types.package; default = []; }; enableRunnerCache = mkOption { type = types.bool; default = false; description = '' Cache this job using the GitLab Runner cache. !!! warning useful for tiny jobs, but most of the time it just takes an eternity. ''; }; runnerCacheKey = mkOption { type = types.str; default = "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"; description = '' Cache key to use for the runner nix cache. Requires [`enableRunnerCache = true`](#pipelinesnamejobsnamenixenablerunnercache). ''; }; }; }; jobSubmodule = { name, config, pipelineName, pipelineConfig, ... }: let # # GITLAB OPTIONS # gitlabOptions = { stage = mkOption { description = '' Pipeline stage to run this job in. ''; type = types.str; }; image = mkOption { description = '' Container/OCI image to use for this job. !!! warning Setting this will mess with Nix-GitLab-CI, so be careful and only use for non-nix jobs. ''; type = types.str; default = "$NIX_CI_IMAGE"; }; variables = mkUnsetOption { type = types.attrsOf types.str; }; before_script = mkUnsetOption { type = types.listOf types.str; }; script = mkOption { type = types.listOf types.str; }; after_script = mkUnsetOption { type = types.listOf types.str; }; artifacts = mkUnsetOption { type = types.attrs; # TODO: more granular description = ''''; }; rules = mkUnsetOption { type = types.listOf types.attrs; }; allow_failure = mkUnsetOption { type = types.bool; }; }; in { options = { nix = mkOption { description = '' Nix-GitLab-CI config options for this job. ''; type = types.submoduleWith { modules = [jobConfigSubmodule]; specialArgs.pipelineConfig = pipelineConfig; }; default = {}; }; finalConfig = mkOption { description = '' Final configuration of this job. (readonly) ''; readOnly = true; internal = true; type = types.attrs; }; depsDrv = mkOption { description = '' Derivation containing all the dependencies of this job. (readonly) ''; readOnly = true; internal = true; type = types.package; }; runnerDrv = mkOption { description = '' Derivation containing the script for running the job locally. (readonly) ''; readOnly = true; internal = true; type = types.package; }; packages = mkOption { description = '' Final packages for this job, eg. for running the job or getting it's deps. (readonly) ''; readOnly = true; internal = true; type = types.attrsOf types.package; }; } // gitlabOptions; config = let attrsToKeep = builtins.attrNames gitlabOptions; in { finalConfig = cilib.mkJobPatched { key = name; job = filterUnset (filterAttrs (n: _v: builtins.elem n attrsToKeep) config); nixConfig = config.nix; inherit pipelineName; }; depsDrv = cilib.mkJobDeps { key = name; job = config.finalConfig; nixConfig = config.nix; }; runnerDrv = cilib.mkJobRun { key = name; job = config.finalConfig; jobDeps = config.depsDrv; }; packages = { "gitlab-ci:pipeline:${pipelineName}:job-deps:${name}" = config.depsDrv; "gitlab-ci:pipeline:${pipelineName}:job:${name}" = config.runnerDrv; }; }; }; }