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

# Sync flags in CI

> Push shipd.config.ts from GitHub Actions with a management API key.

## Overview

Fieldkit's `web-app` repo owns `shipd.config.ts`. On every PR they fail CI if the file drifted from production. On merge to `main` they push.

Management keys (`shipd_mgmt_…`) carry **org + project + environment**. The server rejects a push to a different environment than the key's binding.

## Create the key

In [app.useshipd.com](https://app.useshipd.com) create a management API key for `fieldkit` / `web-app` / `production`. Store it as `SHIPD_API_KEY`.

`--org` (or `SHIPD_ORG`) must match the key's organization when set. It cannot switch orgs.

## Check drift on PRs

```yaml .github/workflows/flags-diff.yml theme={null}
name: flags-diff
on: pull_request
jobs:
  diff:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: pnpm
      - run: pnpm add -g @shipdit/cli
      - run: shipd diff --exit-code --project web-app --env production
        env:
          SHIPD_API_KEY: ${{ secrets.SHIPD_API_KEY }}
```

| Exit | Meaning                               |
| ---- | ------------------------------------- |
| `0`  | No drift                              |
| `2`  | Creates, updates, or archives pending |
| `3`  | CAS conflict (stale version)          |
| `4`  | Unlinked / ownership edge             |

## Push on main

```yaml .github/workflows/flags-push.yml theme={null}
name: flags-push
on:
  push:
    branches: [main]
    paths: ["shipd.config.ts"]
jobs:
  push:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: pnpm add -g @shipdit/cli
      - run: shipd push --yes --project web-app --env production
        env:
          SHIPD_API_KEY: ${{ secrets.SHIPD_API_KEY }}
```

`--ci` is the same as `--yes`. `CI=1` or `SHIPD_CI=1` also skip confirmation.

```bash theme={null}
SHIPD_API_KEY=shipd_mgmt_… shipd push --yes
# or
shipd push --ci --project web-app --org fieldkit --env production
```

## After a conflict

```text theme={null}
Error: conflict
exit 3
```

Someone else applied a newer version. On a developer machine:

```bash theme={null}
shipd pull --project web-app --env production
# re-apply your edits
shipd push --yes
```

`--force` overrides CAS and is audited. Prefer pull.

## Next

* How-to: [Push from CI](/how-to/push-from-ci) · [Resolve a conflict](/how-to/resolve-a-conflict)
* [CLI reference](/reference/cli)
