Semaphore Provider
Read when:
- choosing
provider: semaphore(aliassem); - configuring Semaphore CI testboxes, API auth, machine types, or OS images;
- changing
internal/providers/semaphore.
Semaphore is an SSH lease provider that turns a standalone Semaphore CI job into a warm testbox. Crabbox talks to the Semaphore REST API directly (no agent binary) to create a job, wait for it to start, and pull the job's debug SSH key. Semaphore owns the job, project secret context, caches, machine type, and OS image; Crabbox owns the local repo claim, friendly slug, per-lease SSH key, sync, command execution, timing summary, and normalized list/status rendering.
#When To Use
Use Semaphore when a repo already runs on Semaphore CI and you want a lease that inherits that project's machine types, OS images, and secret context. Reach for AWS, Azure, Hetzner, or the static SSH provider instead when the box should be independent managed cloud capacity, or when you need VNC/desktop/code, brokered fleet accounting, or provider firewall control.
#Commands
crabbox warmup --provider semaphore --semaphore-host example-org.semaphoreci.com --semaphore-project my-app
crabbox run --provider semaphore --semaphore-machine f1-standard-4 -- pnpm test
crabbox ssh --provider semaphore --id swift-crab
crabbox status --provider semaphore --id swift-crab
crabbox stop --provider semaphore swift-crab
#Live Smoke
Run a live smoke when changing Semaphore provisioning, API polling, SSH key retrieval, or release behavior. Keep the token in the environment or user config; do not pass it as a command-line argument.
export CRABBOX_SEMAPHORE_HOST=example-org.semaphoreci.com
export CRABBOX_SEMAPHORE_PROJECT=my-app
export CRABBOX_SEMAPHORE_TOKEN=...
go build -trimpath -o bin/crabbox ./cmd/crabbox
CRABBOX_LIVE=1 CRABBOX_LIVE_PROVIDERS=semaphore CRABBOX_LIVE_REPO=/path/to/my-app scripts/live-smoke.sh
The shared harness exits before any Semaphore warmup, run, list, or stop command when host, project, or token configuration is missing. With those values configured, it creates one short-lived Semaphore testbox, waits for SSH, verifies one no-sync command, lists normalized Semaphore inventory, and stops the lease.
For manual debugging, run the same lifecycle directly:
go build -trimpath -o bin/crabbox ./cmd/crabbox
bin/crabbox warmup --provider semaphore --semaphore-idle-timeout 10m
lease=<slug-or-sem_id-from-warmup-output>
bin/crabbox status --provider semaphore --id "$lease" --wait
bin/crabbox run --provider semaphore --id "$lease" --no-sync -- echo crabbox-semaphore-ok
bin/crabbox list --provider semaphore
bin/crabbox stop --provider semaphore "$lease"
Expected results:
warmupcreates a standalone Semaphore job namedcrabbox testbox, prints asem_<job-id>lease ID and a slug, and retrieves the debug SSH key.status --waitreports a running Linux lease with SSH host details.- The no-sync run prints
crabbox-semaphore-ok. listshows the running Crabbox-managed Semaphore job while it is active.stopposts the job stop request and removes the local lease claim and key.
#Backend Kind
SSH lease. The provider creates a standalone Semaphore job, polls until the job is RUNNING with an agent IP and an ssh port, then fetches the debug SSH key and returns a standard SSH LeaseTarget (user semaphore). Crabbox handles all sync and command execution over that SSH connection.
#Configuration
provider: semaphore
semaphore:
host: example-org.semaphoreci.com # required; host name, not an API URL
# Prefer CRABBOX_SEMAPHORE_TOKEN / SEMAPHORE_API_TOKEN over committing a token.
token: ... # required (config or environment)
project: my-app # required
machine: f1-standard-2 # optional, default f1-standard-2
osImage: ubuntu2204 # optional, default ubuntu2204
idleTimeout: 30m # optional, default 30m (Go duration)
Flags: --semaphore-host, --semaphore-project, --semaphore-machine, --semaphore-os-image, --semaphore-idle-timeout.
Environment variables:
CRABBOX_SEMAPHORE_HOST (or SEMAPHORE_HOST)
CRABBOX_SEMAPHORE_TOKEN (or SEMAPHORE_API_TOKEN)
CRABBOX_SEMAPHORE_PROJECT (or SEMAPHORE_PROJECT)
CRABBOX_SEMAPHORE_MACHINE
CRABBOX_SEMAPHORE_OS_IMAGE
CRABBOX_SEMAPHORE_IDLE_TIMEOUT
CRABBOX_* values win over their SEMAPHORE_* equivalents, which win over config-file values. Generate a token at https://<host>/me/api-tokens. For machine types see the Semaphore machine types reference.
Empty environment values fall through to the next alias or earlier setting; nonempty values are not trimmed during loading. All six YAML strings also preserve earlier values when omitted, null, or empty. A token can be loaded from user or repository configuration, but keeping it in the environment or user configuration avoids committing it. There is no token flag.
All six bindings share one typed declaration. The raw machine, OS-image, and idle-timeout settings remain empty when omitted: their effective defaults are f1-standard-2, ubuntu2204, and 30m, applied by flag registration and the existing runtime helpers. Registering an unvisited flag does not populate the raw setting, and an explicitly empty flag still writes an empty value. These loaded settings remain empty even though execution uses a fallback. config show does not expose a Semaphore section.
Host/token source tracking and the later explicit-host flag phase are unchanged. Host, token, project, and duration validation still happens at the existing provider stages. Job creation, SSH setup, claims, and release behavior do not move into configuration generation.
#Lifecycle
- Resolve the project name to an ID (
GET /api/v1alpha/projects/<name>, with a paginated list fallback). POST /api/v1alpha/jobs: create acrabbox testboxjob whose single command prepares/work/crabbox, printscrabbox-testbox-ready, then sleeps for the idle timeout (keepalive).- Poll
GET /api/v1alpha/jobs/:id(up to ~4 minutes) until the job isRUNNINGand exposes an agent IP plus ansshport. GET /api/v1alpha/jobs/:id/debug_ssh_key: fetch the SSH key and store it under the lease's per-box key path.- Persist an exact ownership claim binding the Semaphore organization host, project, immutable job ID, Crabbox lease, and local slug.
- Crabbox syncs and runs commands over SSH.
- Before release, recheck the exact local claim and fresh running Crabbox job identity while holding the claim fence, then
POST /api/v1alpha/jobs/:id/stop. Remove the claim and stored key only after the provider stop succeeds.
#Capabilities
- SSH: yes.
- Crabbox sync: yes, standard SSH/rsync path.
- Desktop / browser / code: no.
- Actions hydration: no.
- Coordinator (broker): no — always direct from the CLI.
#Limitations
- Linux only.
- No coordinator/broker integration.
- No VNC, desktop, or code-server.
--typeis ignored; choose capacity withsemaphore.machineor--semaphore-machine.- Idle timeout is enforced by the in-job keepalive sleep, not a heartbeat;
crabboxtouch is a no-op for this provider. - Cleanup depends on the Semaphore job stop endpoint.
#Gotchas
hostmust be the Semaphore organization host (for exampleexample-org.semaphoreci.com), not an API URL; URLs with a path, query, or fragment are rejected.- The token must belong to that host and have access to the configured project. A
401 Unauthorizedusually means the token and host do not match. idleTimeoutuses Go duration syntax (30m,1h); it must be positive.- Only jobs named
crabbox testboxare treated as Crabbox-managed bylist,status, andresolve. - Local claims are provider-scoped: a slug claimed by another provider does not resolve as a Semaphore job. Resolve a lease by its full
sem_<job-id>ID or by a slug from a recent warmup. - Stop refuses missing claims, a different organization host or project, the wrong job ID, and jobs whose current provider identity is no longer a running Crabbox testbox. Failed stops preserve both the claim and SSH key for retry; an already-finished verified job clears its remaining local claim safely.
- Claims from older Crabbox versions are upgraded only after their encoded job identity, original project, and fresh provider-side ownership have been verified. Legacy claims without project provenance and claimless jobs are never adopted implicitly.
- If a newly created job cannot be claimed and the rollback stop also fails, Crabbox reports the exact job ID and retains its SSH key for manual recovery.