For developers
Maintainers
Add a Run on Setup button, a Runs on Setup badge and a setup.json to your repository, and how Setup verifies your recipe.
On this page
If you maintain an open-source project, you can let people try it without installing anything. A "Run on Setup" link opens Setup with your repository already pasted. Setup works out how to run it, and the visitor gets a running copy in a sandbox for about an hour.
The "Runs on Setup" badge shows whether that actually works. It turns green after a real runner started your project and all its checks passed, and goes grey again when the last successful run is more than 30 days old. If you commit a setup.json to your repository, Setup uses your recipe instead of guessing.
You don't need an account to add the link or the badge. The generator on the maintainers page writes both for you.
The Run on Setup link
The link is /run?source=<url>:
https://setup.run/run?source=github.com/louislam/uptime-kumasource takes anything the box on Home takes, usually a repository URL. A visitor who is signed in goes straight to the analysis. Everyone else signs in or creates an account first and lands on the same analysis afterwards. From there they read the recipe and start a trial.
Badge and button snippets
The generator on the maintainers page takes owner/repo or a GitHub URL and produces these two snippets. Both link the badge to the Run on Setup link.
Markdown:
[](https://setup.run/run?source=github.com/louislam/uptime-kuma)HTML:
<a href="https://setup.run/run?source=github.com/louislam/uptime-kuma"
><img src="https://setup.run/api/badge/uptime-kuma" alt="Runs on Setup"
/></a>Your project's catalog page at /catalog/<slug> has a For maintainers section with the same badge and a Run button, a dark "Run on Setup" button image served from /api/badge/<slug>/button:
[](https://setup.run/run?source=https%3A%2F%2Fgithub.com%2Flouislam%2Fuptime-kuma)The snippets on your Setup show its own address. setup.run is used here as the example.
Check the slug
The badge URL ends in the project's slug. The generator guesses it from the repository name, so louislam/uptime-kuma becomes uptime-kuma. That matches projects in the curated catalog. A project that Setup created from an analysis usually has the owner in its slug, such as louislam-uptime-kuma, and gets a short random suffix if that name was taken.
The snippets in the For maintainers section of the catalog page always use the right slug. When in doubt, copy them from there.
What the badge shows
The badge reads setup on the left and the state on the right.
| Badge | Color | When | HTTP status |
|---|---|---|---|
setup verified v1.4.2 | green | A run on one of Setup's runners passed all its checks in the last 30 days. | 200 |
setup runs | green | The same, when Setup doesn't know which release the recipe is for. | 200 |
setup ci passed v1.4.2 | blue | Only your own CI reported a pass in the last 30 days (see Check setup.json in CI). | 200 |
setup unverified | grey | No run has passed yet, or the last pass is older than 30 days. | 200 |
setup unknown | grey | No project has this slug, or the project is private. | 404 |
A run on Setup wins over a CI report. The response also carries the state (runs, ci, unverified or unknown) in an X-Setup-Badge header, which is handy for scripts. Badge images are cached for about five minutes, so a change can take a moment to show up.
Public, unlisted and private projects
Badges only answer for public and unlisted projects. Projects in the curated catalog are public. A project that Setup created from an analysis starts out private to the workspace that analyzed it first, and its badge reads unknown until it is public or unlisted. Unlisted projects can be opened by anyone with the link but don't appear in the catalog.
The dashboard has no switch for this yet. Members of the owning workspace can change it with an API key. GET /api/projects/<slug> returns the project with its id:
curl -X PATCH https://setup.run/api/projects/<project-id> \
-H "Authorization: Bearer $SETUP_API_KEY" \
-H "Content-Type: application/json" \
-d '{"visibility":"unlisted"}'visibility is private, unlisted or public. If someone else's workspace analyzed your repository first and owns the project, write to us.
Add a setup.json to your repository
Put a setup.json in the root of your repository. If your link points to a subdirectory (/tree/<ref>/<dir>), put it in the root of that directory. The easiest way to get one is Download setup.json in the For maintainers section of your project's catalog page: it is the recipe Setup runs, with defaults left out. The format is described in Recipes. A small one looks like this:
{
"version": 1,
"slug": "uptime-kuma",
"name": "Uptime Kuma",
"category": "homelab",
"source": {
"kind": "github",
"url": "https://github.com/louislam/uptime-kuma"
},
"services": {
"app": {
"image": "louislam/uptime-kuma:1.23.16",
"ports": [{ "container": 3001 }],
"volumes": [{ "name": "data", "path": "/app/data" }]
}
},
"expose": { "service": "app", "port": 3001 },
"checks": { "http": { "path": "/" } }
}What Setup does with it:
- It comes first. A valid
setup.jsonwins over Setup's own detection. The analysis says "Recipe maintained in the repository (setup.json)". - The source is always yours. Setup builds the repository that was pasted, at the commit it analyzed. It replaces
sourcein your file. Ifsource.git.urlpoints to another repository, Setup ignores it and shows a warning. A service that builds from another repository also gets a warning. - A broken file is skipped. Invalid JSON or a recipe that fails its checks is ignored with a warning, and Setup falls back to detecting how the project runs.
- Changes become revisions. Each analysis reads the file at the analyzed commit. When the content changed, Setup stores it as a new recipe revision.
If your project is also in Setup's curated catalog, the catalog page keeps showing the curated recipe.
To try a recipe before you commit it, paste the file's contents into the box on Home and start a trial. You see the same checks a visitor would. With the runner installed, setup-runner validate setup.json checks the file offline with the same rules Setup uses and points at the line of each problem.
Check setup.json in CI
The Setup GitHub Action checks your setup.json on every pull request and reports release runs to Setup. The GitHub Action tab in the For maintainers section writes a workflow for your project. It looks like this:
on:
pull_request:
paths: [setup.json]
push:
tags: ["v*"]
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: setup-run/verify-action@v1
with:
api-key: ${{ startsWith(github.ref, 'refs/tags/') && secrets.SETUP_API_KEY || '' }}On each run the action validates the file and annotates problems in the pull request. It then starts your recipe in a throwaway sandbox on the GitHub runner's own Docker, runs its checks and removes the sandbox again. The report is uploaded as an artifact and summarized on the run.
To report runs, create a maintainer token under Maintainer tokens on your project's catalog page (only the project's owners see it) and store it in your repository as the SETUP_API_KEY secret. A maintainer token belongs to one project and can only report runs for it. It is shown once, you can give it an expiry, and you can revoke it at any time.
Runs your CI reports are labelled CI-reported. Setup didn't see them happen, so they never count as verified by Setup: they give the blue ci passed badge, while runs on Setup's own runners give the green one. Both kinds, passed and failed, appear in the Verification history on the catalog page with the tag or branch, the commit and a link to the CI run.
How verification works
A run verifies a recipe when the runner reports its checks and every one passes, for example images pulled, services started, health checks healthy and the HTTP check answered through the app's public address. Your recipe decides what the health and HTTP checks look at (see Recipes).
Two kinds of runs count:
- Runs by people. Every trial or kept app that someone starts or updates from your project and that passes its checks adds a verification. A failed run by a visitor is not recorded against your recipe.
- Verification runs. Setup also runs dedicated verification jobs, for example for every catalog entry. These record passes and failures.
For each verification Setup stores the recipe revision, the source commit, the runner's isolation and architecture, the individual checks and how long the run took. The catalog page shows the latest one under Verification and every run, including the ones your CI reported, under Verification history.
How verification is repeated
There is no fixed schedule per project. The badge follows the last passing run:
- It stays green for 30 days after a passing run, then reads
unverifieduntil the next one. - When someone keeps an app from a Git repository, Setup checks your repository at most once a day for a new release, or a new commit if there are no releases. If it moved, Setup analyzes it again and adds a revision when the recipe changed. Kept apps with automatic updates move to that revision, and a passing update counts as a verification.
- Every Run on Setup click analyzes your repository again, so new trials use your latest
setup.json.
Note. A GitHub App that opens a pull request with a verified
setup.jsonand checks it again on Setup's own runners on every release is planned. It does not exist yet; the GitHub Action above checks releases on your CI.