Predefined CI/CD variables
Loom injects a set of predefined environment variables into every job at runtime. Use them in scripts to access job identity, workspace paths, Git metadata, and runtime context without hardcoding values.
check:
stage: ci
target: linux
script:
- echo "Job $LOOM_JOB_NAME running in $LOOM_PROJECT_DIR"
- 'echo "Commit: $CI_COMMIT_SHORT_SHA on branch $CI_COMMIT_BRANCH"'
Variable naming
Loom provides two sets of predefined variables:
| Prefix | Purpose |
|---|---|
LOOM_ | Native Loom variables. Use these when writing Loom-first workflows. |
CI_ | Compatibility layer for scripts that also run in GitLab CI, GitHub Actions, or other platforms. |
Many CI_ variables are aliases of their LOOM_ counterparts (for example, CI_JOB_NAME and LOOM_JOB_NAME resolve to the same value). Prefer LOOM_ variables in new workflows — they are Loom's native names.
Using variables in scripts
Variables are injected as shell environment variables. Reference them with $VARIABLE_NAME:
check:
stage: ci
target: linux
script:
- echo "Job $LOOM_JOB_NAME running in $CI_PROJECT_DIR"
- cd "$CI_PROJECT_DIR" && pnpm run build
Provider behavior affects which variables a job sees:
| Provider | Behavior |
|---|---|
Host (no image: set) | Job inherits the local process environment, then Loom applies workflow/job variables as overrides. |
Docker (image: set) | Loom supplies predefined variables, workflow/job variables, and declared secrets. It does not automatically forward the host environment or expand $NAME inside YAML variable values. |
Precedence
A workflow or job variable overrides a predefined variable with the same name.
version: v1
stages: [ci]
default:
variables:
CI_PROJECT_DIR: "/custom/workdir"
show-dir:
stage: ci
target: linux
script:
- echo "$CI_PROJECT_DIR"
Output:
/custom/workdir
If you depend on Loom's default value for a predefined variable, avoid overriding it. Use a different variable name instead — for example, prefix custom variables with your org or team name.
The full merge order is:
- Predefined variables (Loom system) — baseline values.
- Workflow-level
variables/default.variables— override predefined values for matching keys. - Job-level
variables— override both predefined and workflow-level values for matching keys.
See Variables for the full precedence model.
Predefined variables reference
Pipeline-scoped variables are resolved once per loom run and then merged into every job environment. Job-scoped and step-scoped variables are resolved per job right before script execution.
Loom pipeline variables
| Variable | Description | Availability | Example |
|---|---|---|---|
LOOM_CI | Always true when Loom is executing a job. | Pipeline | true |
LOOM_RUN_ID | Executor run id. Unique per loom run invocation. | Pipeline | loom-run-local-1772867400012726000 |
LOOM_PIPELINE_ID | Executor pipeline id. | Pipeline | loom-local-1772867400012726000 |
LOOM_WORKFLOW_PATH | Workflow file path used for this run in the snapshot. | Pipeline | .loom/workflow.yml |
Pipeline compatibility variables
| Variable | Description | Availability | Example |
|---|---|---|---|
CI | Always true when Loom is executing a job. | Pipeline | true |
CI_RUN_ID | Compatibility alias for Loom's run id. | Pipeline | loom-run-local-1772867400012726000 |
CI_PIPELINE_ID | Executor pipeline id. | Pipeline | loom-local-1772867400012726000 |
CI_PIPELINE_IID | Same value as CI_PIPELINE_ID today. | Pipeline | loom-local-1772867400012726000 |
CI_PIPELINE_STARTED_AT | RFC 3339 timestamp captured when the run starts. | Pipeline | 2026-03-06T12:00:00Z |
CI_PIPELINE_STARTED_AT_SLUG | Slug of CI_PIPELINE_STARTED_AT limited to 63 bytes. | Pipeline | 2026-03-06t12-00-00z |
CI_PROJECT_NAME | Project name derived from the workspace root or explicit project metadata. | Pipeline | loom |
CI_PROJECT_NAMESPACE | Currently resolves to the same value as CI_PROJECT_NAME. | Pipeline | loom |
CI_PROJECT_NAMESPACE_SLUG | Slug of CI_PROJECT_NAMESPACE limited to 63 bytes. | Pipeline | loom |
CI_PROJECT_NAMESPACE_ID | Placeholder namespace id. | Pipeline | 0 |
CI_RUNNER_ID | Runner identifier for local Loom execution. | Pipeline | loom-local |
CI_RUNNER_VERSION | Runner version marker for local Loom execution. | Pipeline | local |
Pipeline Git variables
| Variable | Description | Availability | Example |
|---|---|---|---|
CI_COMMIT_SHA | Snapshot HEAD SHA that Loom runs against. | Pipeline when Git metadata is known | abcdef1234567890abcdef12 |
CI_COMMIT_SHORT_SHA | First 8 characters of CI_COMMIT_SHA. | Pipeline when Git metadata is known | abcdef12 |
CI_COMMIT_BRANCH | Current branch name when Loom can resolve it. | Pipeline when branch is resolvable | main |
CI_COMMIT_REF_NAME | Alias of CI_COMMIT_BRANCH for GitLab-compatible scripts. | Pipeline when branch is resolvable | main |
Job variables
| Variable | Description | Availability | Example |
|---|---|---|---|
LOOM_JOB_NAME | Job name (graph node id). | Job | check |
LOOM_JOB_ID | Job id (currently same as job name). | Job | check |
LOOM_JOB_STAGE | Job stage name. | Job | ci |
LOOM_JOB_TARGET | Job target. | Job | linux |
LOOM_JOB_IMAGE | Job image when image: is set. | Job when image: is set | node:20-alpine |
LOOM_PROVIDER | host or docker, depending on whether image: is set. | Job | docker |
LOOM_PROJECT_DIR | Working directory when the job starts. | Job | /workspace |
CI_BUILDS_DIR | Top-level directory where builds or workspaces live. | Job | /tmp |
CI_PROJECT_DIR | Workspace root where the job runs. | Job | /workspace |
CI_JOB_NAME | Job name (graph node id). | Job | check |
CI_JOB_ID | Job id (currently same as job name). | Job | check |
CI_JOB_STAGE | Job stage name. | Job | ci |
CI_JOB_TARGET | Job target. | Job | linux |
CI_JOB_IMAGE | Job image when image: is set. | Job when image: is set | node:20-alpine |
CI_DEBUG_TRACE | Defaults to false; set to true to enable verbose shell tracing. | Job | false |
CI_JOB_STATUS | Always running during script execution. | Job | running |
CI_JOB_TIMEOUT | Placeholder timeout value. | Job | 0 |
CI_JOB_STARTED_AT | RFC 3339 timestamp captured when the job environment is injected. | Job | 2026-03-06T12:01:00Z |
CI_JOB_STARTED_AT_SLUG | Slug of CI_JOB_STARTED_AT limited to 63 bytes. | Job | 2026-03-06t12-01-00z |
CI_STAGE_STARTED_AT | RFC 3339 timestamp for the stage start tracked for the current job. | Job | 2026-03-06T12:01:00Z |
CI_STAGE_STARTED_AT_SLUG | Slug of CI_STAGE_STARTED_AT limited to 63 bytes. | Job | 2026-03-06t12-01-00z |
Step variables
| Variable | Description | Availability | Example |
|---|---|---|---|
CI_STEP_ID | Always 1; Loom currently executes a job as a single shell step. | Step | 1 |
CI_STEP_STARTED_AT | RFC 3339 timestamp captured when the current step starts. | Step | 2026-03-06T12:01:00Z |
CI_STEP_STARTED_AT_SLUG | Slug of CI_STEP_STARTED_AT limited to 63 bytes. | Step | 2026-03-06t12-01-00z |
These variables are defined by Loom and do not depend on any external CI provider.
Variables in workflow rules
Narrow v1 workflow.rules.if expressions reference variables using
$VARIABLE_NAME syntax:
workflow:
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
The rule context contains only Loom-resolved predefined variables whose
availability is Pipeline in the tables above. Job and step variables,
workflow-defined variables, provider overrides, and the ambient process
environment are not included. If a referenced pipeline variable is unavailable
(for example, Git metadata could not be resolved), evaluation fails closed before
provider preflight, secrets, commands, or services. See
Rules for supported operators and decision behavior.
Running inside another CI system
When you invoke loom run --local from within a GitLab CI job, GitHub Actions step, or other CI runner:
- Host-provider jobs (no
image:) inherit the parent CI environment. Loom then applies its predefined variables and workflow/job overrides, so matching names such asCI_COMMIT_REF_NAMEcan be replaced. Other outer-CI values, such asGITHUB_SHA, remain available unless overridden. - Docker-provider jobs (
image:set) receive Loom's predefined variables, workflow/job variables, and declared secrets. They do not inherit the parent CI environment.
Workflow variable values are literal strings. Writing GITHUB_SHA: $GITHUB_SHA passes the literal text $GITHUB_SHA into Docker; it does not expand the outer environment variable. To supply a non-secret value, write its resolved value into the workflow before starting Loom. For example:
check:
stage: ci
target: linux
image: node:20-alpine
variables:
GITHUB_SHA: "abcdef1234567890abcdef1234567890abcdef1234"
script:
- 'echo "Supplied CI SHA: $GITHUB_SHA"'
Migration from other CI platforms
Loom supplies the CI_ variables listed above. Their values describe the Loom run; they do not reproduce all of the outer CI platform's metadata. Compare the available fields before migrating a script:
| Area | What Loom provides | What may be missing |
|---|---|---|
| Job identity | Job name, id, stage, target, image, status | — |
| Workspace | Project directory, builds directory | — |
| Git metadata | Commit SHA, short SHA, branch name | Tag name, MR/PR metadata, author, labels |
| Pipeline | Pipeline id, run id, timestamps | Pipeline source, trigger info, upstream pipeline |
| Runner | Runner id (loom-local), version (local) | Runner description, tags, architecture |
If your scripts need values Loom does not provide (merge request metadata, actor names, tags), write their resolved values into workflow or job variables, or rely on the host environment when running Loom inside another CI system.
When writing portable scripts, prefer LOOM_ variables inside Loom workflows and map to provider-specific names at the boundary:
check:
stage: ci
target: linux
script:
- 'echo "Project dir: $LOOM_PROJECT_DIR"'
- 'echo "Provider: $LOOM_PROVIDER"'
Not yet supported
Loom does not currently derive Git metadata beyond commit SHA and branch name. Tag names, merge request details, author information, and similar context are not automatically populated. If a Docker job needs them, supply their resolved values in variables before starting Loom. Use declared secrets for sensitive values.
Security considerations
Some predefined variables can expose sensitive information even when they do not look like secrets:
- Paths (
CI_PROJECT_DIR,CI_BUILDS_DIR,LOOM_PROJECT_DIR) can reveal usernames, internal mount paths, or repository layout. - Identifiers (
CI_COMMIT_SHA,CI_PIPELINE_ID,LOOM_RUN_ID) can be used to correlate runs and access logs. - Image references (
CI_JOB_IMAGE) may reveal base images or private registries.
The predefined variable names listed here are public. Their values may expose private context; redact path segments and internal hostnames when asking for help. If you need to share debugging context, provide the run_id and structured log pointers instead of raw environment dumps. See What to share.
Troubleshooting
Print all predefined variables available in a job:
script:
- env | grep -E '^CI_|^LOOM_' | sort
Enable verbose shell tracing for detailed execution output:
variables:
CI_DEBUG_TRACE: "true"
Validate your workflow before running:
loom check
Next steps
- Variables — precedence rules, provider behavior, troubleshooting
- Syntax (v1) — full workflow keyword reference
- Rules — conditional workflow execution
- Predefined CI variables (optional reference) — upstream provider variable snapshot