Deployment previews
A YoFix preview is a fully-functioning, publicly-reachable deployment of the application at a specific commit. Every push to a branch under an open PR produces one.
The lifecycle
- Webhook: GitHub fires a
pull_requestorpushevent. - Enqueue: the API atomically claims the event, creates a
Deploymentrow in the database, and enqueues a build job on thedeployBullMQ queue. - Build: a deploy worker (any one of the pool) claims the job, clones the repo at the exact commit, installs dependencies, runs the detected build command, and uploads the resulting artifacts to your configured storage provider (R2 by default).
- Manifest: once the artifacts are uploaded, the worker writes a manifest mapping the preview hostname to the artifact prefix.
- Serve: the preview server reads the manifest, fetches
artifacts from storage (with NVMe disk cache for hot files), and
serves them under
your-branch.yofix.dev(or your custom domain). - Comment: the API posts (or updates in place) the PR comment with the preview URL and build status.
Every step publishes progress over Redis pub/sub, which the dashboard streams to your browser over WebSocket. You see the build in real time.
Idempotency
Pushing the same commit twice produces the same artifact. Re-running the
same job (e.g. on retry) does not double-build, double-upload, or
double-post the PR comment. PR comments are keyed by an HTML marker
<!-- yofix-deploy:projectId={id} --> so we always find and update the
existing comment instead of creating a new one.
Atomic claiming
The deploy queue uses BullMQ’s atomic job-claiming primitive on Redis. Even when multiple worker nodes run in parallel, a job is claimed by exactly one worker. There is no double-write risk and no need for distributed locks at the application layer.
Caching
Build dependencies are cached on the worker’s NVMe disk per-project and per-lockfile-hash. A re-run of the same commit on the same project with no lockfile change typically completes in seconds. Preview artifacts themselves are deduplicated by content hash before upload.
Cleanup
By default, previews from closed PRs are garbage-collected after 30 days. You can change the retention window per project (30 / 60 / 90 days) in Project settings → Retention. The cleanup job runs daily and is idempotent.