GitLab’s CI/CD pipelines are usually configured using a domain-specific language embedded in YAML (
.gitlab-ci.yml). The DSL is complex, untyped, evolving, and provides limited validation capabilities.
GitLab 12.9 introduced dynamic child pipelines which means the primary pipeline controlled by
gitlab-ci.yml can dynamically create a
generated-config.yml file to spawn a child pipeline.
Here’s a proof of concept demo that leverages the feature to dynamically generate pipeline configurations from Dhall. This solves the problem of trying to keep the Dhall source of truth in sync with the static YAML config. It adds ~15s of overhead to the start of CI, but it may be possible to implement an optimistic caching strategy.
The repo doesn’t do the difficult work of modeling the GitLab DSL using Dhall types. That’s quite involved; as I mentioned the DSL evolves. Error messages from GitLab’s official validation tool are often unclear and I’ve also had issues getting it to resolve remote includes. I’ve tried 3rd party CLI-based validation tools and typically I bump against DSL features they don’t support. For now my intention is to focus more on modeling the “good parts” of the DSL which have been stable for a while and rely Dhall’s composability to make up for the rest.