Skip to main content

Managed CI/CD

When RBS spins up a server for your branch, CI workers, schedulers, and job workers are deployed automatically. There’s nothing to configure — your CI pipeline runs the moment you push code.

How it works

Push to branch

RBS Server starts (or already running)

CI workers, scheduler, build workers auto-deployed

Workflows execute automatically

Results stream to your code editor in real-time
Every branch server comes with:
  • CI workers — execute build and test jobs.
  • Scheduler — manages workflow triggers and cron-based jobs.
  • Job workers — handle long-running tasks (deployments, infrastructure changes).
  • Build workers — run the actual compilation and packaging.
You never need to set up runners, configure YAML pipelines, or manage CI infrastructure. It’s all included.

Why RBS CI?

FeatureRBS CIGitHub ActionsJenkins
Setup requiredNone — auto-deployedYAML per workflowGroovy + agents
WorkersAuto-deployed per branchShared runnersManual agents
Affected-onlyBuilt-inManual setupManual setup
Editor integrationNative — see results in editorBrowser onlyBrowser only
Branch isolationFull — one server per branchShared environmentShared environment

Defining workflows

Basic workflow

Create a ci.rbs file in your repository:
load("@rbs//ci/rules.rbs", "workflow", "job", "step")

workflow(
    name = "build_and_test",
    description = "Build and test all targets",
    on = {
        "push": {"branches": ["main", "develop"]},
        "pull_request": {"branches": ["main"]},
    },
    jobs = [
        job(
            name = "build",
            steps = [
                step(name = "Build All", run = "rbs build //..."),
            ],
        ),
        job(
            name = "test",
            needs = ["build"],
            steps = [
                step(name = "Run Tests", run = "rbs test //..."),
                step(name = "Check Coverage", run = "rbs coverage //..."),
            ],
        ),
    ],
)

Multi-stage pipeline

workflow(
    name = "full_pipeline",
    on = {"push": {"branches": ["main"]}},
    jobs = [
        # Stage 1: Build
        job(
            name = "build",
            steps = [
                step(name = "Build", run = "rbs build //..."),
            ],
        ),
        
        # Stage 2: Test (parallel — both depend on build)
        job(
            name = "unit_tests",
            needs = ["build"],
            steps = [
                step(name = "Unit Tests", run = "rbs test //... --test_tag_filters=unit"),
            ],
        ),
        job(
            name = "integration_tests",
            needs = ["build"],
            steps = [
                step(name = "Integration Tests", run = "rbs test //... --test_tag_filters=integration"),
            ],
        ),
        
        # Stage 3: Deploy (depends on all tests)
        job(
            name = "deploy",
            needs = ["unit_tests", "integration_tests"],
            steps = [
                step(name = "Deploy", run = "rbs run //deploy:production"),
            ],
            condition = "branch == 'main'",
        ),
    ],
)

Triggers

Push trigger

on = {
    "push": {
        "branches": ["main", "develop"],
        "paths": ["src/**", "BUILD.rbs"],    # Only trigger on specific paths
    },
}

Pull request trigger

on = {
    "pull_request": {
        "branches": ["main"],
        "types": ["opened", "synchronize"],
    },
}

Schedule trigger (Cron)

on = {
    "schedule": {
        "cron": "0 2 * * *",   # Daily at 2 AM
    },
}

Manual trigger

on = {
    "manual": {
        "inputs": {
            "environment": {"type": "choice", "options": ["dev", "staging", "prod"]},
            "deploy": {"type": "boolean", "default": False},
        },
    },
}

Webhook trigger

on = {
    "webhook": {
        "url": "/hooks/deploy",
        "secret": "env:WEBHOOK_SECRET",
    },
}

Jobs and steps

Job configuration

job(
    name = "build",
    needs = ["setup"],                          # Dependencies on other jobs
    condition = "branch == 'main'",             # Conditional execution
    timeout = 300,                              # Timeout in seconds
    retry = {"max_attempts": 3, "delay": 30},   # Retry configuration
    env = {"NODE_ENV": "production"},           # Environment variables
    steps = [...],
)

Step types

# Shell command
step(name = "Build", run = "rbs build //...")

# RBS target execution
step(name = "Run App", target = "//services/api:server")

# Custom script
step(name = "Setup", run = """
    echo "Setting up environment..."
    rbs workspace
    rbs build //tools:setup
""")

# Conditional step
step(
    name = "Deploy",
    run = "rbs run //deploy:production",
    condition = "branch == 'main' and tests_passed",
)

Affected-only builds

One of the most powerful CI features: instead of building and testing your entire repository, RBS intelligently determines which targets are affected by the current changes.

How it works

  1. RBS computes the dependency graph of all targets.
  2. Changed files are mapped to their owning targets.
  3. Only changed targets and their dependents are rebuilt and retested.

Usage

# Build only targets affected by changes since the last commit
rbs ci --affected

# Build only targets affected by changes in a PR
rbs ci --affected --base=origin/main

Example output

🔍 Computing affected targets...
📊 Changes detected in:
   - services/api/Server.java
   - libs/common/Utils.java

🎯 Affected targets (3 of 47):
   //services/api:server
   //services/api:server_test
   //libs/common:utils_test

⏭️  Skipped 44 unaffected targets
✅ Build completed: 3 targets in 12s (vs ~180s for full build)
Results stream directly to your code editor in real-time.

DAG-based execution

CI jobs form a Directed Acyclic Graph (DAG). The platform automatically:
  • Parallelizes independent jobs across available workers.
  • Orders dependent jobs correctly.
  • Fails fast when critical jobs fail.
  • Skips downstream jobs when dependencies fail.
         ┌─────────┐
         │  build   │
         └────┬────┘
        ┌─────┴─────┐
   ┌────▼────┐ ┌────▼────┐
   │  unit   │ │  integ  │
   │  tests  │ │  tests  │
   └────┬────┘ └────┬────┘
        └─────┬─────┘
         ┌────▼────┐
         │ deploy  │
         └─────────┘

Distributed execution

The RBS platform can automatically scale workers across multiple nodes for faster builds:
# In ci.rbs — enable distributed execution for a workflow
workflow(
    name = "distributed_build",
    on = {"push": {"branches": ["main"]}},
    execution = {
        "distributed": True,
        "strategy": "least_loaded",    # or "round_robin", "tag_match"
    },
    jobs = [...],
)
# Or enable from the command line
rbs ci --distributed

How distribution works

  1. The platform breaks the build graph into parallelizable units.
  2. Units are distributed to available workers on the branch server.
  3. Results are collected and merged.
  4. Artifacts are available in the unified .rbs/ output directory.

Viewing results in your editor

CI results stream to your code editor in real-time:
  • Build status appears in the editor status bar.
  • Test results are annotated inline (pass/fail markers next to test functions).
  • Build logs are available in the RBS output panel.
  • Coverage reports highlight covered and uncovered lines directly in the editor.

CI commands

CommandDescription
rbs ciRun the default CI workflow.
rbs ci --workflow=NAMERun a specific workflow.
rbs ci --affectedRun only on affected targets.
rbs ci --affected --base=REFCompute affected targets relative to a Git ref.
rbs ci --distributedEnable distributed execution.
rbs ci --dry-runShow execution plan without running.
rbs ci --verboseShow detailed execution output.