{ lib, cilib, jobSubmodule, ... }: let inherit (lib) mkOption types filterAttrs mergeAttrsList mapAttrs mkRenamedOptionModule literalExpression; inherit (cilib.helpers) filterUnset unset mkUnsetOption toYaml toYamlPretty eitherWithSubOptions; pipelineConfigSubmodule = {rootConfig, ...}: { options = { nixJobsByDefault = mkOption { description = '' Whether to transform all jobs to nix-configured jobs by default. If false, you need to set `nix.enable` for each job you want to be transformed. ''; type = types.bool; default = rootConfig.nixJobsByDefault; }; }; }; pipelineSubmodule = { name, config, rootConfig, ... }: let # # GITLAB OPTIONS # gitlabOptions = { default = mkOption { type = types.submodule { # allow other keys aswell, maybe define them in the future? https://docs.gitlab.com/ci/yaml/#default freeformType = types.anything; options = { image = mkUnsetOption { type = types.str; description = '' Default image to use for this entire pipeline. !!! note Moved from top level to `default`: [GitLab Docs](https://docs.gitlab.com/ci/yaml/deprecated_keywords/). ''; }; services = mkUnsetOption { type = types.listOf types.anything; description = '' !!! note Moved from top level to `default`: [GitLab Docs](https://docs.gitlab.com/ci/yaml/deprecated_keywords/). ''; }; cache = mkUnsetOption { # could be more granular type = types.either (types.listOf types.attrs) types.attrs; description = '' !!! note Moved from top level to `default`: [GitLab Docs](https://docs.gitlab.com/ci/yaml/deprecated_keywords/). ''; }; before_script = mkUnsetOption { type = types.listOf types.str; description = '' !!! note Moved from top level to `default`: [GitLab Docs](https://docs.gitlab.com/ci/yaml/deprecated_keywords/). ''; }; after_script = mkUnsetOption { type = types.listOf types.str; description = '' !!! note Moved from top level to `default`: [GitLab Docs](https://docs.gitlab.com/ci/yaml/deprecated_keywords/). ''; }; }; }; # required for it to show up in the docs, but not in the config default = unset; defaultText = literalExpression "unset"; description = '' Custom default values for job keywords. ''; }; include = mkUnsetOption { type = types.attrs; description = '' Import configuration from other YAML files. [Docs](https://docs.gitlab.com/ci/yaml/#include) ''; }; stages = mkOption { type = types.listOf types.str; default = []; # .pre and .post always exist apply = val: [".pre"] ++ val ++ [".post"]; description = '' The names and order of the pipeline stages. [Docs](https://docs.gitlab.com/ci/yaml/#stages) !!! note `.pre` and `.post` are added automatically. ''; }; variables = mkUnsetOption { # default/global variables can have descriptions etc. type = types.attrsOf (eitherWithSubOptions types.str (types.submodule { options = { description = mkUnsetOption { type = types.str; description = '' Use the `description` keyword to define a description for a default variable. ''; }; value = mkUnsetOption { type = types.str; description = '' Use the `value` keyword to define a pipeline-level (default) variable’s value. ''; }; options = mkUnsetOption { type = types.listOf types.str; description = '' Use `options` to define an array of values that are [selectable in the UI when running a pipeline manually](https://docs.gitlab.com/ci/pipelines/#configure-a-list-of-selectable-prefilled-variable-values). ''; }; expand = mkUnsetOption { type = types.bool; description = '' Use the `expand` keyword to configure a variable to be expandable or not. ''; }; }; })); description = '' Define default CI/CD variables for all jobs in the pipeline. Supports strings or attrs as values, for more info see [here](https://docs.gitlab.com/ci/yaml/#variablesdescription). [Docs](https://docs.gitlab.com/ci/yaml/#default-variables) ''; }; workflow = mkUnsetOption { type = types.attrs; description = '' Control what types of pipeline run. [Docs](https://docs.gitlab.com/ci/yaml/#workflow) ''; }; }; in { _file = ./pipeline.nix; # from https://docs.gitlab.com/ci/yaml/#default imports = builtins.map (val: mkRenamedOptionModule [val] ["default" val]) [ "after_script" "artifacts" "before_script" "cache" "hooks" "id_tokens" "image" "interruptible" "retry" "services" "tags" "timeout" ]; options = { nix = mkOption { description = '' Nix-GitLab-CI config options for this pipeline. ''; type = types.submoduleWith { modules = [pipelineConfigSubmodule]; specialArgs.rootConfig = rootConfig; }; default = {}; }; finalConfig = mkOption { description = '' Final config of the pipeline. (readonly) ''; readOnly = true; type = types.attrs; }; packages = mkOption { description = '' Final packages for use in CI. (readonly) ''; readOnly = true; type = types.attrsOf types.package; }; # jobs are nested to make distinguishing them from other keys in the ci config easier jobs = mkOption { description = '' Jobs for this pipeline. ''; type = types.attrsOf (types.submoduleWith { modules = [jobSubmodule]; specialArgs = { pipelineName = name; pipelineConfig = config.nix; }; }); default = {}; }; } // gitlabOptions; config = let attrsToKeep = builtins.attrNames gitlabOptions; in { finalConfig = (filterUnset (filterAttrs (n: _v: builtins.elem n attrsToKeep) config)) // mapAttrs (_name: value: value.finalConfig) config.jobs; packages = { "gitlab-ci:pipeline:${name}" = toYaml "gitlab-ci-config.json" config.finalConfig; "gitlab-ci:pipeline:${name}:pretty" = toYamlPretty "gitlab-ci-config.yml" config.finalConfig; } // mergeAttrsList (map (job: job.packages) (builtins.attrValues config.jobs)); }; }; in { inherit pipelineSubmodule pipelineConfigSubmodule; }