# Deploy Pipeline & gipity.yaml

`gipity deploy` pushes your project live. It runs a multi-phase pipeline server-side and is the step most likely to surface mistakes - so deploy early and often, and **read the phase results every time**.

## The build loop

```
gipity add → edit files → gipity deploy dev → gipity page-inspect <url> → fix errors → repeat
```

Deploy to `dev` while building; deploy to `prod` only when it works. See [app-debugging](app-debugging.md) for the inspect step.

## Commands

```bash
gipity deploy dev      # → https://dev.gipity.ai/<account>/<project>/
gipity deploy prod     # → https://app.gipity.ai/<account>/<project>/
```

| Flag | Effect |
|---|---|
| `--only <phases>` | Run only these phases, comma-separated (e.g. `--only database`) |
| `--force` | Re-run every phase, ignore checksums |
| `--optimize` | Run build optimization on static files |
| `--source-dir <dir>` | Deploy from a directory other than the project root |
| `--no-sync` | Skip the sync-up that normally runs before deploy |
| `--json` | Machine-readable output (the `phases` array) |

## gipity.yaml - the deploy manifest

A project **without** `gipity.yaml` gets a plain static-file deploy (the `src/` folder → CDN). A project **with** `gipity.yaml` gets the full multi-phase pipeline. The `web-fullstack` and `api` starters ship one; `web-simple` does not.

```yaml
version: 1

deploy:
  phases:
    # Static frontend → CDN
    - name: files
      type: static
      source: src

    # SQL migrations → user database (idempotent, each runs once)
    - name: database
      type: sql
      source: migrations
      database: {{DATABASE}}

    # Serverless functions → HTTP endpoints
    - name: functions
      type: functions
      source: functions
      function_definitions:
        - name: get-weather
          auth: public
          fetch_domains: [api.open-meteo.com]
          tables: [weather_lookups]
```

### Phases

| Phase `type` | Source | What it does |
|---|---|---|
| `static` | `src/` | Uploads frontend files to the CDN |
| `sql` | `migrations/` | Auto-creates the database, runs each migration once, loads seeds - idempotent |
| `functions` | `functions/` | Deploys each `.js` file as an HTTP endpoint with its declared permissions |

Workflow automations are also tracked as a phase when present.

### function_definitions

Functions auto-deploy as **public** endpoints, and the deploy pipeline **auto-adds an entry** to `gipity.yaml` for any function it finds undeclared. You only edit entries to grant more than the default:

| Field | Purpose |
|---|---|
| `name` | Function file name (without `.js`) |
| `auth` | `public` (no auth), `user` (logged-in), `member` (project member) |
| `tables` | Database tables the function may read/write |
| `fetch_domains` | External hosts the function may `fetch` - **required** to call app services like `a.gipity.ai` |
| `services` | Declared app services (`llm`, `location`, ...) - documentation only; services are still called via `fetch` |

## Checksums - phases skip when unchanged

On re-deploy, a phase whose inputs haven't changed is skipped (you'll see it reported as unchanged). Use `--force` to re-run everything, or `--only <phase>` to target one phase.

## Read the phase results - every deploy

Each phase reports a status. Do not move on until they're all clean:

| Status | Meaning | Action |
|---|---|---|
| `ok` ✓ | Phase succeeded | None |
| `warning` ⚠ | Deprecated or mis-shaped input (usually `gipity.yaml`); summary starts with "FIX" | Treat as a TODO - fix the file and redeploy |
| `failed` ✗ | Phase did not complete | Fix before doing anything else - the deploy did not fully land |

A `warning` is not informational. Leaving it unresolved means something is already broken or about to be.

## Related skills

- [app-debugging](app-debugging.md) - inspect the deployed page and read function logs
- [app-development](app-development.md) - writing the functions, database, and tests that the pipeline deploys

