Skip to main content

CI/CD Integration

Use Workloom in your CI/CD pipeline to detect and prevent AI configuration drift. The wl sync --check command is designed for CI—it exits with status codes that integrate cleanly with build systems.

Quick Start: Drift Detection in CI​

Add this one command to your CI pipeline to check for drift:

wl sync --check
  • Exit code 0 — All files in sync, build passes
  • Exit code 4 — Drift detected, build fails
  • Exit code 2 — Auth error (workspace binding not found)
  • Exit code 3 — Network error
  • Exit code 5 — Policy violation (trust gate failure)

Exit Code Reference​

CodeMeaningAction
0Clean — workspace matches desired stateBuild passes
1Validation failed — manifest errorCheck workspace manifest
2Auth error — binding or credentials missingConfigure auth for CI
3Network error — registry unreachableCheck network connectivity
4Drift detected — files differ from desired stateRun wl status locally
5Policy violation — trust gate not passedReview and approve assets

The wl sync --check Command​

wl sync --check

Does not write anything to disk. Instead:

  1. Computes the desired state from your workspace manifest
  2. Compares it to what's currently on disk
  3. Reports drift if found
  4. Exits with appropriate code

Locked Versions Only​

For deterministic CI, check against locked versions only:

wl sync --check --locked

This uses the lock file (generated by wl pull) and rejects any manifest changes. Useful in CI where you want to enforce reproducibility.

Dry-Run Mode​

Preview what would be applied without checking:

wl sync --dry-run
# Shows the render plan (desired state)
# Does not compare to current state
# Does not write anything

GitHub Actions Example​

name: Check AI Configuration Drift

on:
push:
branches: [main, develop]
pull_request:
branches: [main]

jobs:
workloom:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 9

- name: Install dependencies
run: pnpm install

- name: Build Workloom
run: pnpm build

- name: Check AI configuration drift
run: pnpm wl sync --check --locked
env:
WORKLOOM_REGISTRY_URL: ${{ secrets.WORKLOOM_REGISTRY_URL }}
WORKLOOM_SERVICE_ACCOUNT_TOKEN: ${{ secrets.WORKLOOM_SERVICE_ACCOUNT_TOKEN }}

The env variables are only needed in Phase 2 when Workloom has a hosted registry. In Phase 1, wl sync --check works locally without auth.

Azure DevOps Pipeline Example​

trigger:
- main
- develop

pr:
- main

pool:
vmImage: 'ubuntu-latest'

steps:
- task: NodeTool@0
inputs:
versionSpec: '20'

- task: Bash@3
inputs:
targetType: 'inline'
script: |
npm install -g pnpm@9
pnpm install

- task: Bash@3
inputs:
targetType: 'inline'
script: |
pnpm build
pnpm wl sync --check --locked
env:
WORKLOOM_REGISTRY_URL: $(WORKLOOM_REGISTRY_URL)
WORKLOOM_SERVICE_ACCOUNT_TOKEN: $(WORKLOOM_SERVICE_ACCOUNT_TOKEN)
displayName: 'Check AI configuration drift'

Workspace Policies​

Control CI behavior with workspace manifest policies:

{
"ciPolicy": {
"requireCleanSync": true,
"failOnDrift": true
}
}
PolicyMeaning
requireCleanSync: trueCI must pass wl sync --check
failOnDrift: trueAny drift causes build failure

These policies inform Workloom's behavior but don't automatically enforce CI checks—you still need to add the wl sync --check command to your CI configuration.

Handling Failures​

When wl sync --check Fails​

$ wl sync --check --locked
# Workloom Sync (Check Mode)
# Workspace: My App
# Drift detected in 2 files:
# .claude/settings.json (state: owned_locally_modified)
# .claude/CLAUDE.md (state: owned_clean)
# Run: wl status
exit code: 4

Diagnose locally:

wl status
# Workloom Status Report
# Workspace: My App
# Drift detected in 1 file:
# .claude/settings.json (state: owned_locally_modified)
# Run: wl diff to see changes

See what changed:

wl diff
# .claude/settings.json
# --- desired
# +++ current
# (diff output)

Restore and Commit​

If the drift is unintended, restore:

wl restore
# Restored .claude/settings.json to desired state

Commit the restored files:

git add .claude/
git commit -m "Restore AI configuration to desired state"
git push

The next CI run passes.

Review and Approve​

If the drift is intentional (e.g., you've updated a trust gate asset), review and approve:

wl status
# Output lists which assets need approval

wl approve <asset-id>
# Approve the asset

wl pull
# Re-render with approval

git add .claude/
git commit -m "Update and approve AI configuration changes"
git push

Multi-Target Monorepos​

For monorepos with multiple targets, check specific targets:

# Check all targets (default)
wl sync --check

# Check frontend app only
wl sync --check --target frontend

# Check multiple specific targets
wl sync --check --target frontend --target api

In CI, you might check only production-critical targets:

# GitHub Actions example
- name: Check production targets
run: pnpm wl sync --check --target api --target admin

Service Account Tokens (Phase 2)​

In Phase 2, when Workloom has a hosted registry, use service account tokens for authenticated CI:

export WORKLOOM_SERVICE_ACCOUNT_TOKEN="wl_sat_..."
wl sync --check --locked

Service accounts have fine-grained permissions:

  • Read-only access to specific packages
  • No approval rights
  • Audit-logged access

Set up in GitHub Actions secrets:

env:
WORKLOOM_SERVICE_ACCOUNT_TOKEN: ${{ secrets.WORKLOOM_SERVICE_ACCOUNT_TOKEN }}

Preventing Accidental Changes​

Lock File in Git​

Always commit your lock file to version control:

# After updating your workspace, commit the lock
git add .workloom/lock.toml
git commit -m "Update Workloom lock file"

In CI, use --locked to enforce the locked state:

wl sync --check --locked
# Only checks against the lock file
# Rejects any manifest changes

Branch Protection​

Configure your repo's branch protection to require the CI check:

GitHub: Settings → Branches → Require status checks to pass before merging → Select "Check AI configuration drift"

Azure DevOps: Repos → Branches → Branch policies → Add build policy → Select your pipeline

Pre-Commit Hook​

Locally, catch drift before pushing:

#!/bin/bash
# .git/hooks/pre-commit

pnpm wl sync --check --locked
if [ $? -ne 0 ]; then
echo "Workloom drift detected. Run 'wl status' to review."
exit 1
fi

Troubleshooting​

"Workspace binding not found"​

The CI environment can't find the workspace binding (.loom/binding.toml). Ensure:

  1. The file exists in the repository
  2. Git-tracked (committed, not in .gitignore)
  3. Readable by the CI environment
git ls-files | grep binding.toml
# Should show: .loom/binding.toml

"Registry unreachable" (Phase 2)​

In Phase 2, when fetching packages from the registry:

export WORKLOOM_REGISTRY_URL="https://registry.workloom.dev"
export WORKLOOM_SERVICE_ACCOUNT_TOKEN="wl_sat_..."
wl sync --check --locked

Verify network connectivity and credentials.

"Policy violation in CI"​

A trust gate asset requires approval. In CI, this causes a policy violation:

# Output
# Workloom Sync (Check Mode)
# Policy violation: executable_hook asset requires approval
# Run: wl approve hook <id> locally, then push
exit code: 5

You must approve locally and commit the approval:

wl approve hook my-hook
git add .workloom/approvals.toml
git commit -m "Approve hook asset"
git push

Then rerun CI.

Performance​

For large workspaces:

# With locked versions (fastest)
wl sync --check --locked
# Reads lock file, no network, deterministic

# Without locked versions (slower, fetches registry)
wl sync --check
# Fetches latest package versions (Phase 2+)

In Phase 1, both are equally fast since no remote registry exists.

Reporting Drift in Notifications​

Custom notification on drift (GitHub Actions):

- name: Check drift
id: drift
run: |
pnpm wl sync --check --locked
echo "status=$?" >> $GITHUB_OUTPUT
continue-on-error: true

- name: Notify on drift
if: steps.drift.outputs.status != '0'
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: ':warning: AI configuration drift detected. Run `wl status` and `wl diff` locally.'
})

Next Steps​