Skip to main content
The moon ci command is a special command that should be ran in a continuous integration (CI) environment, as it does all the heavy lifting necessary for effectively running tasks in CI. By default this will run all tasks that are affected by changed files and have the runInCI task option enabled.
$ moon ci
However, you can also provide a list of targets to explicitly run, which will still be filtered down by runInCI.
$ moon ci :build :lint

How it works

The moon ci command is optimized for CI environments and automatically:
  1. Enables CI mode - Automatically detects CI environment and adjusts behavior
  2. Always checks affected - Compares against base branch to find changed files
  3. Filters by runInCI - Only runs tasks explicitly marked for CI
  4. Syncs workspace - Ensures workspace is synced before running tasks
  5. Includes dependents - Runs direct dependents for regression checking
  6. Continues on failure - Continues running tasks even when some fail
  7. Shows detailed summary - Provides comprehensive output for debugging

Arguments

  • ...[target] - Task targets to run. If not provided, runs all tasks matching criteria.

Options

Inherits most options from moon exec and pre-fills with:
  • --affected - Always enabled
  • --ci - Always enabled
  • --on-failure=continue - Continues execution on failure
  • --summary=detailed - Shows detailed summary
  • --upstream=deep - Includes all dependencies
  • --downstream=direct - Includes direct dependents

Common options

  • -f, --force - Force run and bypass cache, ignore changed files.
  • -i, --interactive - Run the pipeline and tasks interactively.

Affected options

  • --base <BASE> - Base branch, commit, or revision to compare against. Auto-detected from CI environment.
  • --head <HEAD> - Current branch, commit, or revision to compare with. Auto-detected from CI environment.
  • -g, --include-relations - Include graph relations for affected checks.
  • --status <STATUS> - Filter changed files based on a changed status.
  • --stdin - Accept changed files from stdin for affected checks.

Graph options

  • --downstream <DEPTH> - Control the depth of downstream dependents. Default is direct in CI.
  • --upstream <DEPTH> - Control the depth of upstream dependencies. Default is deep.

Parallelism options

  • --job <INDEX> - Index of the current job (0 based).
  • --job-total <TOTAL> - Total amount of jobs to run.

Examples

Basic CI run

Run all CI-enabled tasks affected by changes:
$ moon ci
Output:
▮▮▮▮ Loading changed files
  Base revision: main
  Head revision: HEAD
  Changed files:
    src/app.ts
    src/utils.ts

▮▮▮▮ Building action graph
  Action count: 5
  Resolved targets: 3
    app:build
    app:test
    app:lint

▮▮▮▮ Tracking affected tasks
  app:build affected by file src/app.ts
  app:test affected by dependency task app:build
  app:lint affected by file src/app.ts

▮▮▮▮ Executing action pipeline
  ✓ app:lint (1.2s)
  ✓ app:build (2.5s)
  ✓ app:test (4.1s)

✓ Tasks completed in 7.8s

Summary:
  3 tasks completed
  0 tasks cached
  3 tasks executed

Run specific targets in CI

$ moon ci :build :test

CI with custom base branch

$ moon ci --base develop

Split CI jobs

Distribute work across multiple CI jobs:
# GitHub Actions example
jobs:
  test:
    strategy:
      matrix:
        job: [0, 1, 2, 3]
    steps:
      - run: moon ci --job ${{ matrix.job }} --job-total 4

Force run without cache

$ moon ci --force

CI with status filter

Only check specific types of changed files:
$ moon ci --status added --status modified

CI environment detection

The command automatically detects when running in CI and extracts information from environment variables:
CI ProviderBase BranchHead Revision
GitHub ActionsGITHUB_BASE_REFGITHUB_SHA
GitLab CICI_MERGE_REQUEST_TARGET_BRANCH_NAMECI_COMMIT_SHA
CircleCICIRCLE_BRANCHCIRCLE_SHA1
Travis CITRAVIS_BRANCHTRAVIS_COMMIT
JenkinsCHANGE_TARGETGIT_COMMIT
BitbucketBITBUCKET_PR_DESTINATION_BRANCHBITBUCKET_COMMIT

Task configuration

Tasks must be explicitly marked to run in CI using the runInCI option:
# In moon.yml or .moon/tasks/*.yml
tasks:
  build:
    command: 'npm run build'
    options:
      runInCI: true

  test:
    command: 'npm test'
    options:
      runInCI: true

  dev:
    command: 'npm run dev'
    # Not run in CI by default

Comparison with moon run

Featuremoon cimoon run
AffectedAlways enabledOptional
CI modeAlways enabledOptional
Task filterOnly runInCI tasksAll tasks
On failureContinueBail (stop)
SummaryDetailedNone
DependentsDirectNone
Workspace syncAlwaysOnly in CI

Best practices

Configure runInCI appropriately

Only mark tasks that should run in CI:
tasks:
  # CI tasks
  build:
    options:
      runInCI: true

  test:
    options:
      runInCI: true

  # Development only
  dev:
    # Don't set runInCI

Use with pull request workflows

# GitHub Actions
name: CI

on:
  pull_request:
    branches: [main]

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0  # Important for affected checks

      - name: Run CI
        run: moon ci

Handle all changed files

Ensure you fetch enough git history:
# Fetch full history for accurate affected checks
- uses: actions/checkout@v3
  with:
    fetch-depth: 0

Monitor task failures

Since moon ci continues on failure, check exit code:
if ! moon ci; then
  echo "Some tasks failed"
  exit 1
fi

Environment variables

The following environment variables can be used:
  • MOON_FORCE - Same as --force
  • MOON_BASE - Same as --base
  • MOON_HEAD - Same as --head
  • MOON_INCLUDE_RELATIONS - Same as --include-relations
  • MOON_JOB - Same as --job
  • MOON_JOB_TOTAL - Same as --job-total

Configuration

Build docs developers (and LLMs) love