All docs

Working on code

CI and checks

Run jobs on your own runners with .fettlecode/ci.yml, report results from other CI with the status API, and require checks before merging.

Fettlecode has CI of its own, and also takes results from any other CI. Either way, each result is a check on a commit, shown on the change, and branch rules can require named checks to pass before merging.

Fettlecode CI

Put the jobs in .fettlecode/ci.yml in the repository:

jobs:
  test:
    runs-on: linux                    # labels a runner must have (optional)
    on: [push, change, queue]         # when to run (optional: all three)
    branches: [main, 'release/*']     # pushes to these branches only (optional)
    timeout-minutes: 20               # optional: 30 by default, at most 360
    steps:
      - npm ci                        # a step is a shell command,
      - name: Test                    # or a name and a command
        run: npm test
  • on: push runs for pushes to branches, change for each change and revision sent for review, and queue for merge queue builds.
  • branches limits pushes to some branches. * matches within one part of a name and ** across parts, so release/* matches release/1.0.
  • Up to 20 jobs, each with 1 to 50 steps. Job names use letters, digits, dots, dashes and underscores.

Each job reports as the check ci/<job name>, such as ci/test, with its log in the app. If the file has a mistake, the check says what's wrong.

What a step has

Steps run in a fresh folder holding the commit's files, on the runner's machine, with these set:

VariableValue
CI, FETTLECODEtrue
FETTLECODE_JOBThe job's name
FETTLECODE_REPOSITORYowner/repo
FETTLECODE_SHAThe commit being tested
FETTLECODE_REFThe branch, change or queue ref

Steps run real commands with the repository's code. Use runners on machines you trust with that code, and don't put runners for public repositories on machines with secrets.

Runners

An instance admin adds runners in Your settings → This Fettlecode → Runners: give the runner a name and the labels this machine offers (such as linux or gpu). The token is shown once. Then on the runner's machine, from the Fettlecode folder:

FETTLECODE_URL=https://code.example.com \
FETTLECODE_RUNNER_TOKEN=fcr_... \
pnpm --filter @fettlecode/runner start

A job with runs-on goes to a runner with all those labels; one without goes to any runner. FETTLECODE_RUNNER_WORK_DIR sets where jobs are unpacked.

Results from other CI

Any CI can report results with the same commit status API as GitHub, using a personal access token that can write to the repository:

curl -X POST https://code.example.com/api/repos/wren/bookings/statuses/$SHA \
  -H "Authorization: Bearer $FETTLECODE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"state": "success", "context": "build", "target_url": "https://ci.example.com/run/42"}'

state is pending, success, failure or error, and context names the check.

Requiring checks

In a repository's Settings → Branch rules, list the checks a branch needs, such as ci/test. A change can't be submitted until they've passed on its latest revision, and the merge queue tests each change merged with the branch first.

A rebase that leaves a change's work the same keeps its results, so a stack doesn't re-run CI for nothing.