CI

Run your GitHub Actions workflows on GitCafe

GitCafe runs the workflows in your repository's .github/workflows/ directory with the same YAML you use on GitHub. Jobs run on the official GitHub Actions runner: on ubuntu-latest they get a fresh GitCafe-hosted Linux VM, and on your own Linux, macOS or Windows machines, including hardware-in-the-loop rigs, they run on self-hosted runners. Results show on the repository's CI tab and as checks on pull requests.

GitCafe reads workflows with GitHub's own parser and expression engine. Most workflows run unchanged; what's supported lists the exceptions, and the table below the actions that need GitHub itself.

Turn on Actions

Coming from GitHub? Follow Move CI from GitHub, including how to avoid duplicate runs while syncing.

Jobs run on your self-hosted runners. GitCafe-hosted runners are in beta for organizations GitCafe admits; their setting appears in Settings → CI once they're available to yours.

Actions is off for every repository until a repository admin turns it on:

  1. Open the repository's Settings → CI.
  2. Check Enable Actions.
  3. If Use GitCafe-hosted runners is shown, keep it checked for ubuntu-latest jobs, or uncheck it to run only on your own runners.
  4. Choose Save Actions settings.
sh
1cafe ci enable # --no-hosted to use only your own runners
2cafe ci settings

Turning Actions off stops runs that started before: running jobs are cancelled and jobs that had not started don't start, even if you turn Actions on again. Rerun them afterwards. Turning Actions on does not run anything by itself: the next push, pull request update or dispatch does.

Your first workflow

Add .github/workflows/ci.yml, or keep the one you already have:

yaml
1name: CI
2
3on:
4 push:
5 branches: [main]
6 pull_request:
7
8jobs:
9 test:
10 runs-on: ubuntu-latest
11 steps:
12 - uses: actions/checkout@v4
13 - uses: actions/setup-node@v4
14 with:
15 node-version: 22
16 - run: npm ci
17 - run: npm test

Push it: the run appears on the CI tab within a minute. If the workflow has a mistake, you get a failed run whose page lists each problem and where it is, instead of silence.

Where jobs run

runs-on picks a runner by its labels: a job runs on a runner that has every label it lists (letter case doesn't matter).

  • GitCafe-hosted runners serve ubuntu-latest, ubuntu-24.04 and ubuntu-22.04. Each job gets a new Linux x64 VM with Docker and the official runner, which is deleted after the job. The image has Node, Python, Git and the usual build tools, but not everything GitHub's images have; setup-* actions download what's missing. A repository uses them while Use GitCafe-hosted runners is on, if the server offers them: Settings → CI lists the labels it serves.
  • Self-hosted runners are your machines. Each has the labels self-hosted, its operating system (Linux, macOS or Windows), its architecture (X64 or ARM64) and any you add when you configure it, so runs-on: [self-hosted, macOS, ARM64] or runs-on: [self-hosted, hil] work as on GitHub. A repository can use the runners registered on it and those of its organization's runner groups that it has access to. Labels choose a runner; they never grant access.

Settings → CI shows every runner the repository can use, with its labels and status. A job that no runner matches waits, marked as waiting for a runner, until one with the right labels comes online. A run waits at most 24 hours for runners, on top of its jobs' time limits, then ends as Timed out.

Triggers

GitCafe reads the workflow files at the commit being tested, so a change to a workflow applies to the commit that makes it. Three events run workflows:

  • push runs for each branch a push creates or updates, whether you push with Git or GitCafe updates the branch, such as when you merge a pull request. Deleting a branch and pushing tags run nothing. branches, branches-ignore, paths and paths-ignore filters work as on GitHub.

  • pull_request runs when a pull request is opened or reopened, and each time its head branch gets a new commit. It tests the head commit of the pull request, not a merge with the base branch: GITHUB_SHA is the head commit and GITHUB_REF is refs/pull/<number>/head. branches filters match the base branch and paths filters the changed files. GitCafe reports every pull request event as the synchronize activity type, so a types list must include synchronize (the default list does).

  • workflow_dispatch runs a workflow on demand, at the commit a branch or tag points to now. You need write access to the repository. Dispatch it with the Cafe CLI; the web UI has no Run workflow button yet:

    sh
    1cafe ci dispatch .github/workflows/ci.yml --ref main

    Inputs take their default values; you can't type input values yet.

A workflow may list other events, such as schedule or release: GitCafe accepts the file and runs it only for the three events above.

Checks on pull requests

Every run reports checks on its commit, next to Buildkite checks and commit statuses (read CI results):

  • one check per job, named <workflow name> / <job name>, such as CI / test or, for a matrix, CI / test (22);
  • one check per run, named <workflow name>, which also reports when the workflow could not be read.

Each check links to its run. To require a check before merging, add its exact name to a ruleset's required status checks. When you rerun a workflow, the new run's checks replace that run's earlier ones.

Secrets and variables

${{ secrets.NAME }} and ${{ vars.NAME }} work as on GitHub: add them in Settings → Secrets and variables of a repository or an organization (secrets and variables). Every job also gets a GITHUB_TOKEN that can read its own repository, valid while the job runs; actions/checkout uses it to clone from GitCafe.

Follow runs and read logs

The repository's CI tab lists workflow runs and Buildkite builds together, newest first, with filters for source, status and branch (and event for workflow runs). A run's page shows its jobs by stage, with a matrix's combinations together under their job, each job's steps with their results, and its log, which updates while the job runs.

sh
1cafe ci list --branch main # workflow runs and Buildkite builds
2cafe ci list --source actions --pr 42 # workflow runs at a pull request's head
3cafe ci view <run-id>
4cafe ci logs <run-id> # the first failed job
5cafe ci logs <run-id> --job test --tail 50

Anyone who can read the repository can see its runs and logs, including anonymous visitors to a public repository. GitCafe keeps up to 4 MiB of each job attempt's log; past that, the oldest output is dropped.

Cancel or rerun a run

You need write access to the repository.

  • Cancel stops a run that hasn't finished. Jobs that haven't started are cancelled at once; running jobs are told to stop.
  • Rerun starts a new run of a finished run at the same commit, with the same workflow, and runs every job again. To run a changed workflow, push a new commit instead.
sh
1cafe ci cancel <run-id>
2cafe ci rerun <run-id>

GitCafe never reruns a job by itself. If a runner disappears mid-job, the job fails once its runner has been silent for a few minutes; rerun it when you're ready.

Coming from the GitHub CLI

cafe ci covers the repository's CI: GitCafe Actions workflow runs and Buildkite builds, like the CI tab (cafe actions is an alias). Runs are addressed by id (actwfrun_… for a workflow run, from cafe ci list), not by run number.

ghcafe
gh run listcafe ci list --source actions (--branch, --event, --status, --pr, --limit)
gh run view <run>cafe ci view <run-id>
gh run view <run> --logcafe ci logs <run-id> --job <job> --full (one job at a time)
gh run view <run> --log-failedcafe ci logs <run-id> (the first failed job, last 200 lines)
gh run watch <run>cafe ci watch <run-id> (exits 8 unless the run succeeded)
gh run cancel <run>cafe ci cancel <run-id>
gh run rerun <run>cafe ci rerun <run-id> (every job)
gh workflow run <workflow> --ref <ref>cafe ci dispatch <workflow>.yml --ref <ref>
gh secret set NAME [--org ORG]cafe ci secret set NAME [--org ORG] (value from --body, --env or stdin)
gh variable set NAME [--org ORG]cafe ci variable set NAME [--org ORG] (value from --body, --env or stdin)
gh pr checks <pr>cafe pr status <pr> (every check: workflow jobs, Buildkite and commit statuses)

What's missing:

  • No rerun of only the failed jobs (gh run rerun --failed, --job): rerun runs every job again.
  • No dispatch inputs (gh workflow run -f/--json): inputs take their defaults.
  • cafe ci list has no --workflow or --user filter. --branch matches runs on that branch's ref; pull request runs are on refs/pull/<number>/head, so find them with cafe ci list --pr <pr> (the runs at the pull request's current head) or cafe ci status --pr <pr>.
  • For organization secrets and variables, --visibility and --repos take repository names of that organization (name or org/name); without them, set keeps an existing one's access and creates a new one as private.

Pull requests from forks

Workflows do not run for pull requests from forks, and pull_request_target is not one of the events GitCafe runs. A fork's run is recorded with the result Action required and its check says that workflows do not run for pull requests from forks; it cannot be rerun. This applies whatever the repository's fork setting is.

What works differently

Some actions and features depend on github.com or on services GitCafe doesn't offer yet:

WhatOn GitCafe
actions/upload-artifact@v4, actions/download-artifact@v4Fail: their own code refuses servers other than github.com. Artifacts are not supported yet; publish files elsewhere, such as a release or object storage.
actions/cacheNo cache service yet: the cache step finds nothing to restore.
OIDC (permissions: id-token: write)Not supported yet: jobs get no OIDC token, so cloud login actions that use one fail. Use a secret instead.
Pull requests from forks, pull_request_targetDon't run (above).
Actions that call the GitHub REST API (actions/github-script, release and comment actions)GITHUB_TOKEN and github.api_url point at GitCafe, which implements only a few endpoints (reading a repository), and the token can only read. Calls to anything else fail.
Third-party runners (Depot, Namespace, Blacksmith, ...)Their runs-on labels never match: those services serve github.com only. See runner providers.
Deployment environments (environment:)The environment's name is shown on the job, but there are no protection rules, environment secrets or variables: the job runs at once.
Actions from repositoriesuses: owner/repo@ref downloads the action from public github.com. An action whose owner/repo is also a GitCafe repository is refused for now. Private github.com actions can't be used.

Limits

  • A job runs for at most its timeout-minutes (default and maximum 360), then ends as Timed out.
  • A run waits at most 24 hours for runners, on top of its jobs' time limits.
  • More in what's supported.
Read as MarkdownGitCafe documentation
Documentation