---
url: https://docs.tailor.tech/erp-kit/operate/setup-ci.md
description: >-
  Generate GitHub Actions workflows that deploy an ERP Kit project on merge and
  test every pull request in its own preview workspace.
---

# Set Up CI

`erp-kit setup ci` generates two GitHub Actions workflows for an ERP Kit project. It runs the SDK's [`tailor setup ci`](/sdk/github-actions) and adds the steps an ERP Kit project needs on top: registry authentication, seeding, integration tests, and E2E tests.

| Workflow                                      | Runs on                    | What it does                                                                                                                                                                      |
| --------------------------------------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `.github/workflows/tailor-<name>.yml`         | Push to the default branch | Deploys every `apps/<app>/backend`, with its frontend, into one workspace. Pull requests get a plan.                                                                              |
| `.github/workflows/tailor-<name>-preview.yml` | Every pull request         | Deploys every app into a workspace created for that pull request, seeds it, and runs each app's integration and E2E tests. The workspace is deleted when the pull request closes. |
| `.github/tailor.lock`                         |                            | The SDK's record of the generated files and app IDs. Commit it.                                                                                                                   |

Both workflows run only when a change touches an app backend or frontend, `modules/`, `pnpm-lock.yaml`, or the root `package.json`.

`<name>` is the `name` in the project's `package.json` unless you pass `--name`.

::: tip
The `erp-kit-setup-ci` skill runs this whole page for you, including choosing the region and walking through the secrets. Run `/erp-kit-setup-ci` in your coding agent from the project root.
:::

## Prerequisites

* The root `package.json` has `@tailor-platform/sdk` and `@tailor-platform/sdk-plugin-setup` in `devDependencies`. Projects created by `erp-kit init` already do. Otherwise:

  ```bash
  pnpm add -D -w @tailor-platform/sdk @tailor-platform/sdk-plugin-setup
  pnpm install
  ```

* `pnpm-lock.yaml` is at the repository root. Without it, the command stops, because the SDK would choose npm while the ERP Kit jobs run pnpm.

* A machine user with permission to create and deploy workspaces. See [Account management](/administration/account-management).

## Generate the workflows

Run from anywhere inside the repository, in your own terminal:

```bash
pnpm exec erp-kit setup ci --region us-west
```

::: warning
Run this command in an interactive terminal, not from a coding agent or a script. It may ask a question that only an interactive terminal shows.
:::

| Option                        | Use it when                                                                                                                       |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `--region <region>`           | Always. The region for the preview workspaces.                                                                                    |
| `--name <name>`               | The `package.json` name is not a valid workspace name (3 to 53 lowercase letters, digits, and hyphens).                           |
| `--branch <branch>`           | The repository has no remote default branch recorded.                                                                             |
| `--dir <dir>`                 | The ERP Kit project (the directory holding `apps/`) is a subdirectory of the repository. See [Nested projects](#nested-projects). |
| `--preview-environment <env>` | You want a GitHub Environment name other than `<name>-preview` for the preview jobs.                                              |
| `--force`                     | You want to reset hand edits to the SDK-managed parts of the workflows.                                                           |

If the command finds `erp-kit-test-workspace*.yml` workflows from an earlier ERP Kit release, it offers to remove them. Answer **Remove**: otherwise every pull request deploys a second workspace.

Then check that the generated files match what the SDK expects:

```bash
node_modules/.bin/tailor setup check
```

It must end with `No drift detected`.

## Secrets and variables

List the secrets and variables each GitHub Environment needs:

```bash
node_modules/.bin/tailor setup ci env
```

The output prints a `gh` command for each value, with what the value is and where to get it, and the command that creates the environment if it does not exist. Run the commands one at a time and enter each secret at the prompt. Do not pass secret values on the command line.

### App CI environment

ERP Kit's App CI workflow (`erp-kit-app-ci.yml`: lint, typecheck, and frontend build) reads the same machine user secrets from the GitHub Environment named by the `ERP_KIT_CI_ENVIRONMENT` repository variable. `tailor setup ci env` does not list this variable, so `erp-kit setup ci` prints the command at the end of its run:

```bash
gh variable set ERP_KIT_CI_ENVIRONMENT --body <name>-preview
```

Without it, App CI fails at `Fetch Tailor token` with `No credentials provided`, even though the secrets are set.

## Branch protection

To require the preview checks before merging, require the `erp-kit-preview-result` job. It succeeds when the preview was skipped (a draft, a fork, or a change that touches no app) and fails when any preview job failed. Do not require the individual matrix jobs: their names change with the list of apps.

## Customize the workflows

The generated files mix parts owned by the SDK, parts owned by ERP Kit, and parts owned by you:

| Owner   | What it owns                                                                                               | On the next run                                       |
| ------- | ---------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
| SDK     | Jobs and steps whose ID starts with `tailor-`, and the top-level keys listed in each file's header comment | Editing them makes `tailor setup check` report drift. |
| ERP Kit | Jobs and steps whose ID starts with `erp-kit-`, and the preview workflow's top-level `concurrency`         | Removed and re-inserted. Your edits are lost.         |
| You     | Everything else, including job-level `env` and `runs-on` on `tailor-` jobs                                 | Kept.                                                 |

Keep your own changes in steps and jobs with other IDs.

### E2E sharding

Apps whose frontend has a `test:e2e` script and whose backend registers `frontendPlugin` run Playwright in a container against their deployed `default-web` site. The preview workflow sets `ERP_KIT_E2E_SHARDS: "1"` in its top-level `env`. Change it to a larger number to split each app's E2E suite across that many jobs. This value is kept when you run `erp-kit setup ci` again.

### Runners

The `erp-kit-seed`, `erp-kit-integration`, and `erp-kit-e2e` jobs run on the runner named by these repository variables:

| Variable                     | Used by                                                | Falls back to          |
| ---------------------------- | ------------------------------------------------------ | ---------------------- |
| `ERP_KIT_BUILD_RUNNER`       | All three jobs, and App CI's backend and frontend jobs | `ubuntu-latest`        |
| `ERP_KIT_SEED_RUNNER`        | `erp-kit-seed`                                         | `ERP_KIT_BUILD_RUNNER` |
| `ERP_KIT_INTEGRATION_RUNNER` | `erp-kit-integration`                                  | `ERP_KIT_BUILD_RUNNER` |
| `ERP_KIT_E2E_RUNNER`         | `erp-kit-e2e`                                          | `ERP_KIT_BUILD_RUNNER` |

If you [restrict the preview's frontend or GraphQL endpoint by IP](/administration/ip-restriction), set `ERP_KIT_BUILD_RUNNER` to a runner with a fixed IP address. `erp-kit-e2e` runs in a Docker container, so its runner must be able to run containers. The variables are read at run time, so re-running `erp-kit setup ci` does not reset them.

## Nested projects

When the ERP Kit project is a subdirectory of a larger repository, pass `--dir <dir>`. The SDK still runs at the repository root, so the root must be the pnpm workspace root:

* `@tailor-platform/sdk` and `@tailor-platform/sdk-plugin-setup` in the root `package.json`
* `pnpm-lock.yaml` at the root
* `pnpm-workspace.yaml` listing `<dir>/apps/**`

## Re-run after changes

Run `erp-kit setup ci` again with the same options after you upgrade ERP Kit or the SDK, or add an app. `tailor setup check`, which the generated workflows also run, reports when a newer SDK has a newer workflow template. Commit the changes to `.github/workflows/tailor-*.yml`, `.github/tailor.lock`, and any `tailor.config.ts` the SDK changed (it moves app IDs into the lock file).
