> ## Documentation Index
> Fetch the complete documentation index at: https://docs.paradime.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Run several jobs when a pull request merges

> Start several on-merge Bolt schedules on every merge, side by side or after your deploy, and follow all of them in one summary comment on the pull request.

Run more than one Bolt schedule when a pull request merges: your dbt™ deploy, and the jobs that go with it. A job can start with the merge, at the same time as the deploy, or wait for the deploy to finish. One **Paradime Merge Run Summary** comment on the pull request shows all the jobs.

<Note>
  **Prerequisites**

  * The [Paradime GitHub app](/integrations/github/github-app) installed on your dbt™ repository. The **On merge** trigger works only with the app.
  * A [production environment](/products/settings/connections/scheduler-environment/index).
  * A deploy job: an on-merge schedule that deploys your changes. To create one, see [Set up continuous deployment](/guides/orchestrate-data-pipelines/set-up-continuous-deployment). This guide calls it `Deploy - changed models`.
  * The Admin or Developer [role](/products/settings/users/roles-and-permissions) in Paradime, to create Bolt schedules.

  Estimated time: 15 minutes.
</Note>

## Steps

<Steps>
  <Step title="Plan the jobs">
    Decide which jobs run on each merge, and when each one starts. In this guide, two jobs run after the deploy:

    | Job | Starts | Commands |
    | - | - | - |
    | `Deploy - changed models` | When the pull request merges | `dbt build --select state:modified+` |
    | `Refresh - catalog` | After the deploy passes | `paradime catalog refresh` (see [Refresh Paradime Catalog](/products/bolt/creating-schedules/command-settings/paradime-refresh-catalog)) |
    | `Monitor - Elementary` | After the deploy passes or fails | `edr monitor` (see [Run Elementary](/products/bolt/creating-schedules/command-settings/elementary-commands)) |

    The jobs that run after the deploy form a chain with it: they wait for the deploy on the same merge, and they start at the same time when it finishes.
  </Step>

  <Step title="Check your deploy job">
    In Bolt, open `Deploy - changed models`. Make sure that:

    * **Trigger type** is **On merge**, and **Run after another schedule** is off.
    * **Git branch** is the branch that your pull requests merge into, for example `main`. An on-merge schedule runs only when a pull request merges into exactly its Git branch.

    Leave **When merges overlap** on **Run in parallel** for now. See [When two merges overlap](#when-two-merges-overlap).
  </Step>

  <Step title="Add the jobs that run after the deploy">
    For each job, create a schedule in Bolt with these settings:

    * **Name**: for example, `Refresh - catalog`.
    * **Environment**: your production environment.
    * **Git branch**: the same branch as the deploy job.
    * **Commands**: the commands for this job.
    * **Trigger type**: **On merge**. Turn on **Run after another schedule**, and in **Bolt schedule name**, select `Deploy - changed models`.
    * Under **Bolt schedule complete with status:**, select **Passed** for `Refresh - catalog`. For `Monitor - Elementary`, select **Passed** and **Failed**, so that Elementary sends its alerts when the deploy fails too.

    Select **Deploy**.

    <Warning>
      The jobs after the deploy belong to one chain. If one of them fails, Paradime cancels the other jobs of the chain that are still running. For example, if `Refresh - catalog` fails while `Monitor - Elementary` runs, Paradime cancels `Monitor - Elementary`.
    </Warning>
  </Step>

  <Step title="Add a job that starts with the merge (optional)">
    Some jobs do not need the tables that the deploy builds. Create the schedule with the **On merge** trigger and the same **Git branch**, and leave **Run after another schedule** off. On every merge, this job starts at the same time as the deploy. The two jobs are independent: if one fails, the other continues.

    <Warning>
      Jobs that start together run at the same time. If two of them build dbt™ models, give them different model selections, so that they do not build the same table at the same time.
    </Warning>
  </Step>

  <Step title="Merge a pull request">
    Merge a pull request that changes a model in your dbt™ project folder into the branch of your jobs. A merge that changes no file in the dbt™ project folder starts no job.
  </Step>
</Steps>

<Check>
  The merged pull request gets a **Paradime Merge Run Summary** comment. Paradime updates the comment as the jobs run, and it shows every job of the merge:

  ```text theme={"system"}
  ✅ 3 of 3 passed · a1b2c3d merged into main

  Step                      Status      Duration   Run
  Deploy - changed models   ✅ Passed    4m 12s     #1234
  Monitor - Elementary      ✅ Passed    1m 48s     #1236
  Refresh - catalog         ✅ Passed    2m 40s     #1235
  ```

  While the deploy runs, the jobs after it show `Waiting for Deploy - changed models`. If a job is missing from the comment, check its trigger. A job that runs after the deploy needs **Run after another schedule** set to `Deploy - changed models`. A job that starts with the merge needs the **Git branch** that the pull request merged into.
</Check>

## When two merges overlap

By default, each merge starts its jobs at once (**Run in parallel**). If a second pull request merges while the jobs of the first merge still run, the jobs of both merges run at the same time. The second deploy can then start before the first deploy finishes.

If your deploy expects the previous merge to be in production first, make the merges take turns. See [Make merges take turns with a merge queue](/guides/orchestrate-data-pipelines/set-up-a-merge-queue).

## How merge jobs behave

* **Each merge runs its own jobs.** The jobs on the merged branch build the merge commit, even if more commits land on the branch while they run.
* **A later merge does not cancel an earlier one.** The jobs of each merge run to the end, so a deploy never stops halfway because another pull request merged.
* **A failure stops the jobs after it.** In that merge, the jobs that wait for the failed job to pass are skipped. The next merge still runs, because it can contain the fix.
* **The jobs of a merge can run for 6 hours.** After that, Paradime cancels the jobs that are still running.
* **Retry builds the latest commit.** On the run page of a job, **Retry** > **Retry this step** runs the job and the jobs after it again. **Retry the whole chain** runs the chain of the job again from its first job. Both build the latest commit of the branch, not the merge commit. You can retry only after all the jobs of the merge finish.

## Set it up in YAML

If you manage your schedules as code, the deploy has `trigger_on_merge: true`, and each job after it has `run_after`:

```yaml paradime_schedules.yml theme={"system"}
schedules:
  - name: "Deploy - changed models"
    slug: deploy-changed-models-c4d5e6               # your deploy job's slug
    description: "Deploy the models that changed since the last successful deploy"
    owner_email: data-platform@acme.io
    environment: production
    git_branch: main
    schedule: "OFF"
    trigger_on_merge: true
    commands:
      - dbt build --select state:modified+
    deferred_schedule:
      enabled: true
      deferred_schedule_slug: deploy-changed-models-c4d5e6   # defers to its own last successful run
      successful_run_only: true

  - name: "Refresh - catalog"
    description: "Refresh the Paradime Catalog after the deploy"
    owner_email: data-platform@acme.io
    environment: production
    git_branch: main
    schedule: "OFF"
    commands:
      - paradime catalog refresh
    run_after:
      schedule: deploy-changed-models-c4d5e6         # the deploy job
      "on": [passed]

  - name: "Monitor - Elementary"
    description: "Send Elementary alerts after every deploy"
    owner_email: data-platform@acme.io
    environment: production
    git_branch: main
    schedule: "OFF"
    commands:
      - edr monitor
    run_after:
      schedule: deploy-changed-models-c4d5e6
      "on": [passed, failed]
```

Keep the quotes around `on`. YAML reads a bare `on` as the boolean `true`, and then the schedule file fails to parse.

Keep `schedule: "OFF"` on every job of a merge chain. A cron schedule starts runs on its own clock, so those runs cannot wait for a merge. Run `paradime schedule verify` (Paradime CLI 6.8.0 or later) before you commit. It checks the file and adds a `slug` to each new schedule.

## Next steps

<CardGroup cols={2}>
  <Card title="Make merges take turns with a merge queue" href="/guides/orchestrate-data-pipelines/set-up-a-merge-queue" icon="list-ordered">
    Run the jobs of one merge at a time, in merge order.
  </Card>

  <Card title="Chains reference" href="/products/bolt/ci-cd/chains#on-merge" icon="link">
    Every rule for merge chains.
  </Card>

  <Card title="Continuous deployment reference" href="/products/bolt/ci-cd/continuous-deployment/index" icon="rocket">
    Deploy options for GitHub and other git providers.
  </Card>

  <Card title="Retry a run" href="/products/bolt/managing-schedules/retrying-a-run" icon="rotate-ccw">
    How Retry works for merge jobs and for other runs.
  </Card>
</CardGroup>

## Troubleshooting

* **A job does not run on merge.** Its **Git branch** is not exactly the branch that the pull request merged into, or the pull request changed no file in your dbt™ project folder. A suspended job is skipped.
* **A job after the deploy never starts.** The deploy did not finish with the status that the job waits for. For example, a job that waits for **Passed** is skipped when the deploy fails.
* **Retry shows that the merge chain is still running.** A job of the merge still runs. Wait until all the jobs finish, then retry.


## Related topics

- [Run Bolt schedules in order on pull requests and merges](/products/bolt/ci-cd/chains.md)
- [Make merges take turns with a merge queue](/guides/orchestrate-data-pipelines/set-up-a-merge-queue.md)
- [Chain Turbo CI checks to run in order](/guides/orchestrate-data-pipelines/chain-turbo-ci-checks.md)
- [Run several Turbo CI checks on a pull request](/guides/orchestrate-data-pipelines/run-several-turbo-ci-checks.md)
- [Continuous Deployment with GitHub for dbt™](/products/bolt/ci-cd/continuous-deployment/github.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.