---
title: "Generate in CI"
description: "Drive typeship from a pipeline with the typeship CLI or API: regenerate a project on your schedule, or generate a package ad hoc and commit it yourself."
url: https://typeship.dev/docs/guides/ci
markdown: https://typeship.dev/docs/guides/ci.md
section: "Get started"
---
> ## Documentation index
> Fetch the complete documentation index at https://typeship.dev/llms.txt (every page, one line each) or the full text at https://typeship.dev/llms-full.txt.
> Append .md to any docs URL, or send Accept: text/markdown, for the markdown twin of that page.

# Generate in CI

Drive typeship from a pipeline with the typeship CLI or API: regenerate a project on your schedule, or generate a package ad hoc and commit it yourself.

Projects with a destination regenerate on their own and open pull requests, so most teams never need CI for generation. Reach for it when you want the packages in your own pipeline: to commit them alongside your app, to build them into a container, or to gate a release on a fresh generation.

Both paths use typeship's own tooling. This page is about calling **typeship**, not about running your generated CLI. For that, see [In CI](https://typeship.dev/docs/platforms/cli#in-ci) on the CLI page.

## Regenerate a project and pull the files

The [typeship CLI](https://typeship.dev/docs/cli) reads its key from `TYPESHIP_TOKEN` and prints JSON, so it drops into any job. Create a key under **api keys** in the console and store it as a secret.

```yaml title=".github/workflows/sdk.yml"
name: Regenerate SDK
on:
  workflow_dispatch:
  schedule:
    - cron: "0 6 * * 1"

jobs:
  regenerate:
    runs-on: ubuntu-latest
    env:
      TYPESHIP_TOKEN: ${{ secrets.TYPESHIP_TOKEN }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm install -g typeship-ax
      - name: Regenerate and unpack
        run: |
          typeship projects generate prj_your_project_id > generations.json
          node -e '
            const fs = require("fs"), path = require("path");
            for (const g of JSON.parse(fs.readFileSync("generations.json")).data) {
              if (g.status !== "succeeded") { console.error(g.language, g.error); process.exit(1); }
              for (const f of g.files) {
                const p = path.join("packages", g.language, f.path);
                fs.mkdirSync(path.dirname(p), { recursive: true });
                fs.writeFileSync(p, f.content);
              }
            }'
      - run: git status --short
```

`projects generate` regenerates a URL-sourced project, records the generation and its spec version, and returns every language's files. It does not open pull requests. Commit the result however your pipeline commits.

Large packages return `files_omitted: true` with a `files_index` instead of inline files. Fetch each with `typeship generations get-file <generation_id> --path src/index.ts`.

## Generate ad hoc, no project

`generate run` runs the generator on any spec without a project or an account. It is the same call the homepage makes:

```bash
typeship generate run \
  --spec '{"url":"https://api.acme.example.com/openapi.json"}' \
  --platforms '["sdk","cli"]' \
  --language typescript > result.json
```

Or with `curl`:

```bash
curl -s https://typeship.dev/api/v1/generate \
  -H "Content-Type: application/json" \
  -d '{"spec":{"url":"https://api.acme.example.com/openapi.json"},"platforms":["sdk"],"language":"python"}'
```

Ad hoc generation is capped at the first 25 operations of a spec and stores nothing. It is for evaluation and small APIs. Anything you want kept current belongs in a project.

## Fail the build on spec drift

Your generated CLI's `--validate` flag checks a live API against the spec it was generated from. A smoke job that runs a few read-only commands with `--validate` catches an API that drifted from its published spec before your users do:

```yaml
- name: Spec drift check
  env:
    ACME_TOKEN: ${{ secrets.ACME_TOKEN }}
  run: node packages/typescript/dist/cli.js accounts list --validate --limit 5
```

## Sitemap

[Every page of these docs](https://typeship.dev/llms.txt)
