Git

Pipelines

CI/CD for your repositories: workflows that build, test and deploy on push, pull request, schedule or by hand.

A workflow is a YAML file in .cactive/workflows/ in your repository. Its syntax is GitHub Actions': if you know one, you know the other. Each time a workflow runs is a run, made of jobs, made of steps. Runs show in the repository's Pipelines section in the Git portal, with live logs, and each commit shows its status beside it.

A first workflow

.cactive/workflows/ci.yml
name: CI
on:
  push:
    branches: [main]
  pull_request:
jobs:
  test:
    runs-on: linux-arm64
    steps:
      - uses: checkout
      - uses: cache
        with:
          key: npm-${{ hashFiles('package-lock.json') }}
          path: ~/.npm
      - run: npm ci
      - run: npm test

Push it, open Pipelines, and watch the run.

Triggers

EventFilters
pushbranches, branches-ignore, tags, tags-ignore, paths, paths-ignore
pull_requestbranches / branches-ignore (the target branch), paths, paths-ignore, types (opened, reopened, synchronize)
schedulecron (UTC, five fields; at most every 5 minutes)
workflow_dispatchinputs (string, boolean, number, choice, environment)

Patterns: * matches anything but /, ** anything, ? makes the character before it optional, + repeats it, [a-z] is a set, and ! at the start excludes what an earlier pattern matched. Pushes to a branch use the workflow in the pushed commit; pull requests the source branch's; schedules the default branch's. Run workflow (or POST …/pipelines/workflows/:file/dispatches) starts a workflow_dispatch workflow on a branch you choose, with its inputs.

Jobs

Key
runs-onA hosted runner type (below), or [self-hosted, …labels].
needsJobs that must finish first; their outputs and result are in needs.
ifRuns the job only when true. Without it, every needed job must have succeeded.
strategy.matrixOne job per combination (lists, include, exclude, or fromJSON(…)); fail-fast (default true), max-parallel.
env, defaults.runEnvironment variables and the default shell and working-directory.
environmentname (and url): see Environments.
concurrencygroup (and cancel-in-progress): one running and one waiting per group.
outputsValues for later jobs, from step outputs.
timeout-minutes, continue-on-errorAs on GitHub.

Steps

A step is run (a script in shell: bash by default, sh, pwsh, powershell, python, node, or a command with {0}) or uses with one of the built-in actions:

Actionwith
checkoutref, fetch-depth (default 1; 0 for all history), path
cachekey, path, restore-keys. Output cache-hit; saves after the job when the key wasn't an exact hit.
upload-artifactname, path, retention-days, if-no-files-found
download-artifactname, path

actions/checkout@v4, actions/cache@v4, actions/upload-artifact@v4 and actions/download-artifact@v4 mean the same built-ins, so workflows from GitHub mostly carry over. Other actions aren't available.

Steps pass values on as on GitHub: append name=value lines to $SI_OUTPUT (outputs), $SI_ENV (environment for later steps) and $SI_PATH (directories for PATH), and Markdown to $SI_STEP_SUMMARY. Print ::group::Title and ::endgroup:: to fold output, ::add-mask::value to hide a value, and ::error::, ::warning:: or ::notice:: (with file= and line=) for annotations on the run page.

Expressions

${{ … }} works in any value (if may leave it out). Contexts: git (ref, ref_name, sha, event_name, actor, repository, run_number, … ; github works too), inputs, vars, secrets, env, needs, matrix, strategy, steps, job, runner. Functions: contains, startsWith, endsWith, format, join, toJSON, fromJSON, hashFiles, success, failure, always, cancelled. Pass untrusted text (a pull request title) to a script through env, not by writing ${{ }} into the script.

Runners

Hosted runner types (your plan's monthly minutes count their time times their multiplier):

LabelMachine
linux-arm64-lambdaARM, 4 GB; starts in seconds; at most 15 minutes; no Docker
linux-arm64 (also hosted)ARM, 2 vCPU, 4 GB
linux-arm64-largeARM, 8 vCPU, 16 GB
linux-x64x86, 2 vCPU, 3 GB, Ubuntu

Each hosted job runs in a fresh machine of its own that's discarded afterwards. It reaches the internet but nothing of the platform except through its job's own access: its repository (read), its run's artifacts, its branch's caches.

Self-hosted: agents approved for Pipeline jobs (by the machine's owner) with full network access run jobs whose runs-on starts with self-hosted and whose other labels the machine has: its OS (linux, macos, windows), architecture (x64, arm64) and labels you give it in the organization's Pipeline Settings → Runners (from the organization's page). The job's secrets reach that machine, so use self-hosted runners with repositories you trust.

Environments and approvals

An environment (Settings → Environments) is a deployment target such as production. Rules are optional:

  • Required reviewers: up to six people or groups; one approval lets the job go, one rejection fails it. Prevent self-review stops whoever started the run from approving it.
  • Wait timer: minutes to wait before the job starts.
  • Deployment branches: all, the protected branch, or patterns.
  • Environment secrets and variables, which only that environment's jobs get, once its rules pass.

Secrets and variables

Set them for the organization (all repositories or chosen ones), a repository, or an environment; an environment's win over the repository's, which win over the organization's. Secrets are encrypted, never shown again, given only to running jobs and hidden in logs as ***. Anyone who can push a workflow can make it use the repository's and the organization's secrets, so keep secrets that only certain branches or reviewers should reach in an environment. Managing them needs git:admin (owners and admins).

Caches and artifacts

Caches belong to a branch: a job restores from its own branch, a pull request's target and the default branch, and saves only to its own branch, so a branch can't change what the default branch restores. Caches unused for 7 days are removed, and the oldest go first past your plan's storage. Artifacts belong to a run and are kept for retention-days (default 30, at most your plan's).

Statuses, re-runs and cancelling

The commit list, branches and pull requests show each commit's status. On a run, Re-run runs everything again (or only the failed jobs and what needs them) as a new attempt; earlier attempts stay. Cancel stops a run.

From the terminal

In a clone of the repository (or with --repo org/name), si runs lists runs, shows one, prints a job's log (--follow while it runs), re-runs or cancels it, and runs a workflow by hand:

si runs ls --status failure
si runs logs 42 --follow
si runs start deploy.yml --ref main -f target=web

Not available

Third-party, composite and Docker actions; reusable workflows; container and services; an automatic job token (store an API key as a secret); OIDC; events other than the four above; Windows, macOS and GPU hosted runners; if: always() steps after a cancel.