Ephemeral (single-use, just-in-time) self-hosted runners for GitHub Actions

A fresh runner for every job, recycled after.

An ephemeral runner takes one job and then goes away, so no job starts with another job's runner or work folder. Codemany gives every GitHub Actions job a fresh single-use runner on your own Mac or Linux machine. Each one registers with GitHub just in time, takes one job and exits; its folder is wiped and a fresh runner starts.

Why one runner per job

A long-lived self-hosted runner keeps its folder from job to job. Files a build left behind can break or change the next build. With GitHub's runner on its own, that cleanup between jobs is yours, along with updates and scaling (Codemany compared).

A single-use runner starts every job from the same clean folder. Results don't depend on which job ran before.

How Codemany's single-use runners work

  1. Register just in time

    Codemany registers a runner with GitHub just in time, with the labels self-hosted and codemany, plus the operating system and CPU labels GitHub's runner adds.

  2. Take one job

    GitHub still schedules jobs and shows the logs. It hands the runner one job whose runs-on labels it has.

  3. Exit and wipe

    When the job ends, the runner exits, Codemany removes it, and its folder is wiped.

  4. Start a fresh one

    A fresh runner starts. Each repo keeps a warm runner while there are spares; idle runners move to repos with waiting jobs. Busy runners are never touched.

Details: How Codemany runs jobs.

Use them in a workflow

You don't write any just-in-time config yourself. Change one line, runs-on:

name: CI
on: push
jobs:
  build:
    runs-on: [self-hosted, codemany]
    steps:
      - uses: actions/checkout@v4
      - run: make test

To send a job to your Linux machines only, use runs-on: [self-hosted, Linux, codemany]. More in Runner labels.

What is wiped and what carries over

  • Wiped: the runner and its folder, after every job.
  • Kept: downloads from actions/setup-go, setup-node, setup-python and other actions/setup-* steps, in a shared tool cache at ~/.codemany/toolcache, pruned past 20 GB (Tools and caching).
  • Kept: the tools installed on your machine. Nothing is preinstalled; jobs get what you have.
  • Not undone: a job runs as your user, so files it changes outside its folder and programs it leaves running stay. A fresh runner keeps jobs apart from each other, not from your Mac (What a job can do).

Crashes, hangs and updates

  • A crashed runner is replaced, backing off from 5 seconds up to 5 minutes.
  • A runner offline for 2 minutes is stopped, with leftover processes such as simulators, and replaced.
  • Updates wait until running jobs finish. GitHub errors and rate limits never stop a running job.

How many run at once

Each runner budgets 4 GB of memory, 15 GB of disk and 2 performance cores. An 8 GB Mac runs 1 job at a time; a 16 GB Mac runs 3. codemany capacity prints how many fit. To run more, add machines.

Questions

Is an ephemeral runner a sandbox?

No. It keeps jobs apart from each other, not from your machine. Read runner security before you point it at a repo.

Do I have to create JIT configs or remove runners myself?

No. Codemany registers each runner just in time and removes it when the job ends. You only change runs-on.

Does every job start with a cold cache?

Not for actions/setup-* downloads: they stay in the shared tool cache. Pre-warm fills it with the versions your workflows ask for.

Where do I see the logs?

On GitHub, as with any runner. Codemany Console also shows runs and job logs, with secrets masked on your machine.

How do I set it up?

Follow Get started, or the guides for a runner on a Mac and a runner on Linux.