# The publishing workflow

The SDK panel on the project's page shows a whole workflow for `.github/workflows/sdk.yml`. On every push to `main` that changes `openapi.yaml` or `latitude10.sdk.json`, it pushes the document to the registry, generates the TypeScript package, builds it and publishes it to npm, then does the same for Python when the config has a `python` section.

### 1. Add the key

Save your project key as the repository secret `LATITUDE10_KEY`.

### 2. Set up trusted publishing

On npm and on PyPI, add this repository and workflow as a trusted publisher for your package. The workflow then publishes with your own accounts' trust: npm with provenance, PyPI through its trusted publishing.

### 3. Add the workflow

```yaml
name: SDK
on:
  push:
    branches: [main]
    paths: [openapi.yaml, latitude10.sdk.json]
permissions:
  contents: read
  id-token: write # npm trusted publishing
jobs:
  sdk:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - uses: actions/setup-node@v5
        with:
          node-version: 24
          registry-url: https://registry.npmjs.org
      - name: Push the spec to Latitude 10
        run: >
          curl --fail-with-body -X POST
          "https://latitude10.tech/api/registry/v1/versions?git_sha=$GITHUB_SHA&git_ref=$GITHUB_REF"
          -H "Authorization: Bearer $LATITUDE10_KEY"
          --data-binary @openapi.yaml
        env:
          LATITUDE10_KEY: ${{ secrets.LATITUDE10_KEY }}
      - name: Generate the SDK
        run: >
          curl --fail-with-body -X POST
          "https://latitude10.tech/api/registry/v1/sdks/typescript?version=latest"
          -H "Authorization: Bearer $LATITUDE10_KEY"
          -H "Content-Type: application/json"
          --data-binary @latitude10.sdk.json -o sdk.tgz
          && tar -xzf sdk.tgz
        env:
          LATITUDE10_KEY: ${{ secrets.LATITUDE10_KEY }}
      - name: Build the SDK
        working-directory: package
        run: npm install --no-audit --no-fund && npm run build
      - name: Publish it unless this version is already on npm
        working-directory: package
        run: |
          NAME=$(node -p 'require("./package.json").name')
          VERSION=$(node -p 'require("./package.json").version')
          if npm view "$NAME@$VERSION" version > /dev/null 2>&1; then
            echo "$NAME@$VERSION is already on npm"
          else
            npm publish --provenance --access public
          fi
        # Without trusted publishing, save an npm token as NPM_TOKEN and uncomment:
        # env:
        #   NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
  python-sdk:
    runs-on: ubuntu-latest
    needs: sdk
    permissions:
      contents: read
      id-token: write # PyPI trusted publishing
    steps:
      - uses: actions/checkout@v5
      - uses: actions/setup-python@v7
        with:
          python-version: "3.13"
      - name: Generate the Python SDK
        run: >
          curl --fail-with-body -X POST
          "https://latitude10.tech/api/registry/v1/sdks/python?version=latest"
          -H "Authorization: Bearer $LATITUDE10_KEY"
          -H "Content-Type: application/json"
          --data-binary @latitude10.sdk.json -o sdk-python.tgz
          && mkdir -p sdk-python && tar -xzf sdk-python.tgz -C sdk-python
        env:
          LATITUDE10_KEY: ${{ secrets.LATITUDE10_KEY }}
      - name: Type-check and build the Python SDK
        working-directory: sdk-python/package
        run: python -m pip install build pyright httpx && pyright && python -m build
      - name: Publish it to PyPI unless this version is already there
        uses: pypa/gh-action-pypi-publish@release/v1
        with:
          packages-dir: sdk-python/package/dist
          skip-existing: true
          # Without trusted publishing, save a PyPI API token as PYPI_API_TOKEN and uncomment:
          # password: ${{ secrets.PYPI_API_TOKEN }}
```

A version already on npm or PyPI is skipped, so re-running the workflow is safe.

## Without trusted publishing

Save an npm token as `NPM_TOKEN`, or a PyPI API token as `PYPI_API_TOKEN`, and uncomment the lines the workflow marks.

The packages are published from your repository, to your accounts. Latitude 10 never publishes a package for you and never opens a pull request in your repository.

## Where this comes from

- `app/sdk/_lib/ci.ts`
- `app/api/registry/v1/sdks/typescript/route.ts`
- `app/api/registry/v1/sdks/python/route.ts`
