Expand (some) CI variables lazily and selectively
Problem
In GitLab the only time we need to build the full set of CI variables is when sending them to the runner as we assign a job to execute. In all other scenarios we use variables to expand strings potentially containing other variables.
To expand even a single variable in a string we build a lot of variables.
job:
script: echo
rules:
- if: $CI_COMMIT_BRANCH To expand $CI_COMMIT_BRANCH we first build all variables that can potentially be used in that given context.
Can we lazily build only CI_COMMIT_BRANCH and memoize its value?
Updated Proposal (March 2026)
The original proposal assumed that predefined variables could not be overridden by user-defined variables (dependency on #388961 (closed)). However, #388961 (closed) was closed in 2023 after user feedback that overriding predefined variables is necessary for debugging and testing.
Hybrid lazy evaluation approach:
Instead of making ALL variables lazy, we use a hybrid approach:
- Load user-defined variables eagerly (project/group/instance variables) - Required to maintain correct variable precedence - Includes database query and decryption
- Make expensive predefined variables lazy - Only evaluate when actually accessed - Focus on variables with expensive operations
- Keep cheap predefined variables eager - Variables that are just property access don't benefit from lazy evaluation - Lambda overhead isn't worth the complexity
Good candidates for lazy evaluation:
Gitaly calls:
CI_COMMIT_MESSAGE,CI_COMMIT_TITLE,CI_COMMIT_DESCRIPTION- loads commit data from GitalyCI_COMMIT_TAG_MESSAGE- callsrepository.find_tagCI_COMMIT_AUTHOR,CI_COMMIT_TIMESTAMP,CI_COMMIT_USER_LOGIN- Git commit metadata
Database queries:
CI_MERGE_REQUEST_APPROVED- queriesapproval_rulesand approvers tablesCI_KUBERNETES_ACTIVE- queriesdeployment_platforms+ may make API callCI_DEPLOY_FREEZE- queries freeze_periods tableCI_EXTERNAL_PULL_REQUEST_*- loadsexternal_pull_requestsfrom databaseCI_OPEN_MERGE_REQUESTS- queriesmerge_requeststable with permissions check
Not good candidates:
CI_COMMIT_BRANCH,CI_PIPELINE_SOURCE,CI_PROJECT_PATH- just property access- These should remain eager as the lambda overhead outweighs any benefit