Core concepts
These are the domain concepts bitrab uses internally. Keeping them straight matters because the same GitLab keyword can affect multiple layers.
Pipeline
Internally, a pipeline is a PipelineConfig dataclass from bitrab/models/pipeline.py.
It contains:
- ordered
stages - global
variables - a
defaultblock - concrete
jobs
By the time a PipelineConfig exists, includes have already been merged and extends: has already been resolved.
Job
A job is a JobConfig dataclass. A top-level YAML mapping becomes a job if:
- its key is not in
PipelineProcessor.RESERVED_KEYWORDS - it is not a hidden template name like
.base - its value is a mapping
The execution-facing job model includes:
- shell command lists:
before_script,script,after_script - scheduling metadata:
stage,when,needs - failure policy:
retry_*,allow_failure*,timeout - filesystem behavior:
artifacts_*,dependencies - expansion metadata for
parallel:and matrix fan-out
Stages
Stages are still first-class even though bitrab also supports DAG execution.
- In pure stage mode, stages are the primary ordering mechanism.
- In DAG mode, stages still matter because
_build_dag()uses them to synthesize dependencies for jobs that do not declareneeds:.
This means stage order is not just display metadata.
needs: and DAG scheduling
If any job has needs:, StagePipelineRunner.execute_pipeline() delegates to DagPipelineRunner.
Important consequence: bitrab does not run two separate execution engines. The stage runner is the front door, and it switches to DAG mode when needed.
Rules
Rules are represented as RuleConfig dataclasses and applied by config.rules.evaluate_rules().
Current supported rule keys:
ifexistswhenallow_failurevariablesneeds
Rules are evaluated in order; the first match wins. If no rule matches, the job is rewritten to when: never.
Variable handling
There are several variable layers:
- host
os.environ - synthesized CI-style built-ins from
VariableManager - local dotenv files (
.env,.bitrab.env) - pipeline/global variables
- default/job variables
- upstream dotenv report variables for dependencies
The exact merge points matter, especially because JobExecutor.build_context() re-applies job variables after loading upstream dotenv report values so job-level YAML remains authoritative.
Executors
Bitrab does not currently have a plugin executor system. In practice, the executor is:
- native bash via
execution.shell.run_bash()
The "executor" abstraction today is mostly embodied by JobExecutor plus the PipelineCallbacks output hooks, not by interchangeable shell/docker backends.
Workspace model
Jobs run from the project directory, not from an isolated copied checkout. JobExecutor._execute_with_context() explicitly uses ctx.project_dir as cwd.
Per-job directories still exist under .bitrab/<job-name>/, but they are exposed to scripts as CI_JOB_DIR, not used as the main working directory.
That is one of the most important behavioral differences from containerized GitLab Runner execution.