---
title: "Deploys from pull requests"
description: "What starts a deploy of a pull request, what each step does, how the pull request shows the result, and when Stagely deletes the stagelet."
url: https://stagely.dev/docs/app/deploys
---

## What starts a deploy

| Trigger                                                                  | Who                                                                            | Notes                                                                                                                                                   |
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Open, reopen or push to a pull request                                   | Anyone who can push                                                            | Only when the project deploys on push, the default. Never for a pull request from a fork.                                                               |
| A comment whose first word is the comment command, `/stagely` by default | People with write, maintain or admin permission on the repository              | Stagely replies with a comment that links to the stagelet's page in the console. Others get a reply that says only people with write access can deploy. |
| The project's deploy label                                               | Anyone who can label; for a pull request from a fork, people with write access | Off until an admin sets a label name. Case does not matter.                                                                                             |
| **Deploy** in the console                                                | Members of the account                                                         | Enter the pull request's number on the project's page.                                                                                                  |
| `deploy_pull_request` over MCP                                           | A coding agent, acting as you                                                  | See [Connect a coding agent](https://stagely.dev/docs/agents.md).                                                                                                             |

Every deploy builds the pull request's head commit. Stagely resolves the commit itself. A caller can't ask for a different commit.

### Pull requests from forks

A pull request from a fork can hold code from anyone who can fork your repository. Its stagelet gets the project's config and secrets. So it deploys only when someone with write access asks: with the comment command, the deploy label, the console or MCP. New commits on the fork never deploy it on their own.

## On the pull request

Stagely posts each deploy as a commit status on the deployed commit, with the context `stagely/<your account>`:

| Status    | Meaning                                                                                            |
| --------- | -------------------------------------------------------------------------------------------------- |
| `pending` | The deploy is queued or running                                                                    |
| `success` | The stagelet runs this commit                                                                      |
| `failure` | The deploy failed                                                                                  |
| `error`   | A newer deploy, a reset or a delete replaced this one before it ran, or Stagely refused the deploy |

The status's **Details** link opens the stagelet's page in the console. The exception is the `error` status of a refused deploy: its link opens the project's page.

Stagely can refuse a deploy, for example for an invalid `.stagely.yml`, a missing subscription, or an account that runs as many stagelets as [its plan](https://stagely.dev/docs/setup/billing.md) allows. When a GitHub event asked for the deploy, such as a push, a label or a comment command, the pull request shows the reason: in the `error` commit status, or in the reply to the comment command. When the console or MCP asked for the deploy, Stagely returns the reason to the person or agent that asked. Nothing goes on the pull request.

## The steps

The console and MCP show each step live, with its log.

| Step              | Where            | What happens                                                                                                                                                                                                                                                                                                           |
| ----------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Lease             | Agent            | The agent in your cloud takes the job.                                                                                                                                                                                                                                                                                 |
| Secrets           | Agent host       | The agent finds the value of each named secret. A missing secret fails the deploy here, before any machine starts.                                                                                                                                                                                                     |
| Build images      | Build worker     | A build worker gets the commit's source and checks the resolved Compose project against the [Compose rules](https://stagely.dev/docs/app/compose.md). It builds each service that has a `build` section, and pushes each image to your registry as `<registry>/<owner>/<repo>/<service>:<commit>`. The agent records the digest of each one. |
| Provision machine | Your cloud       | The agent creates the stagelet's own machine if it does not exist yet. This step runs at the same time as the build.                                                                                                                                                                                                   |
| Start services    | Stagelet machine | The agent writes the compiled bundle and the secret file, and runs `docker compose up --wait` with each built image pinned by digest.                                                                                                                                                                                  |
| Migrate           | Stagelet machine | The migration command runs in the public service. The agent skips this step when `.stagely.yml` has no `migration.command`.                                                                                                                                                                                            |
| Health check      | Stagelet machine | The agent requests the health path from inside the machine until the app answers with a 2xx status, for up to two minutes.                                                                                                                                                                                             |
| Route             | Gateway          | The gateway serves the stagelet's private URL. It keeps checking that it reaches the app and that the app answers its health path.                                                                                                                                                                                     |

## When a deploy fails

The console shows the failed step, its error and its log. A coding agent reads the same with `get_operation`.

Stagely tracks the stagelet's states separately: its lifecycle, its revision, its machine, its app's health and its route. A deploy that fails before **Start services**, such as in **Secrets** or **Build images**, leaves the machine running the app it ran before. The stagelet then shows **Failed**, while its revision, machine and app health show that the last good build still serves.

To go back, click **Reset**. A reset reapplies the images, by digest, and the config of the last successful deploy on the same machine. It fetches no new source, runs no migration, and does not undo data migrations.

## Newest wins

Deploys, resets and deletes of one stagelet run one at a time. A newer deploy or reset replaces an older one that is still queued. The stagelet's state and commit always follow its newest operation.

## The end of a stagelet

- **Closing the pull request** deletes its stagelet. Stagely removes access first, then the agent deletes the machine.
- **The TTL** deletes a stagelet that nobody deploys again. The default is 72 hours. Each deploy starts the TTL again.
- **Delete** in the console does the same at any time. A delete that fails shows its error. Click **Delete** again, or let Stagely retry it in the background.

## Project settings

Admins and owners change these on the project's page.

| Setting         | Default     | Meaning                                                               |
| --------------- | ----------- | --------------------------------------------------------------------- |
| Deploy on push  | On          | Opening, reopening and pushing to a pull request deploys it           |
| Comment command | `/stagely`  | The first word of a pull request comment that deploys it              |
| Deploy label    | Empty (off) | A label that deploys the pull request when someone adds it            |
| TTL             | 72 hours    | How long a stagelet lives after its last deploy, from 1 to 2160 hours |
