go-devops/docs/sdk-generation.md
Snider 481344a066 docs: add human-friendly documentation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 13:02:39 +00:00

6.7 KiB

title description
SDK Generation OpenAPI client generation for TypeScript, Python, Go, and PHP with breaking change detection.

SDK Generation

The sdk/ package generates typed API client libraries from OpenAPI specifications. It supports four languages, auto-detects spec files, and uses oasdiff for semantic breaking change detection. Configuration lives in the sdk: section of .core/release.yaml.

How it works

core build sdk                    # Generate SDKs using .core/release.yaml config
core build sdk --spec api.yaml    # Explicit spec file
core build sdk --lang typescript  # Single language only

The generation pipeline:

  1. Detect spec — find the OpenAPI file (config, common paths, or Laravel Scramble).
  2. Run diff — if enabled, compare current spec against the previous release and flag breaking changes.
  3. Generate — run the appropriate generator for each configured language.
  4. Output — write client libraries to sdk/{language}/.

OpenAPI spec detection

detect.go probes locations in priority order:

  1. Path configured in .core/release.yaml (sdk.spec field).
  2. Common file paths:
    • api/openapi.yaml, api/openapi.json
    • openapi.yaml, openapi.json
    • docs/api.yaml, docs/openapi.yaml
    • swagger.yaml
  3. Laravel Scramble — if scramble/scramble is in composer.json, runs php artisan scramble:export to generate the spec.
  4. Error if no spec found.

Generator interface

Each language generator implements:

type Generator interface {
    Language() string
    Generate(ctx context.Context, spec, outputDir string, config *Config) error
}

Generators are registered in a string-keyed registry, allowing overrides.

Language generators

Each generator uses a native tool when available and falls back to Docker-based generation:

Language Native tool Fallback Install
TypeScript openapi-typescript-codegen openapi-generator (Docker) npm i -g openapi-typescript-codegen
Python openapi-python-client openapi-generator (Docker) pip install openapi-python-client
Go oapi-codegen openapi-generator (Docker) go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@latest
PHP openapi-generator (Docker) Requires Docker

Fallback strategy

When the native tool is not installed, generators automatically fall back to running openapi-generator inside Docker:

func (g *TypeScriptGenerator) Generate(ctx context.Context, opts GenerateOptions) error {
    if g.Available() {
        return g.generateNative(ctx, opts)
    }
    return g.generateDocker(ctx, opts)
}

Output structure

Each generator writes to sdk/{language}/:

sdk/
├── typescript/
│   ├── package.json
│   ├── src/
│   │   ├── index.ts
│   │   ├── client.ts
│   │   └── models/
│   └── tsconfig.json
├── python/
│   ├── setup.py
│   ├── myapi/
│   │   ├── __init__.py
│   │   ├── client.py
│   │   └── models/
│   └── requirements.txt
├── go/
│   ├── go.mod
│   ├── client.go
│   └── models.go
└── php/
    ├── composer.json
    ├── src/
    │   ├── Client.php
    │   └── Models/
    └── README.md

Breaking change detection

diff.go uses oasdiff to compare two OpenAPI spec versions semantically. It detects:

  • Removed endpoints
  • Changed required parameters
  • Modified response schemas
  • Changed authentication requirements

Usage

core sdk diff                        # Compare current spec vs last release
core sdk diff --spec api.yaml --base v1.0.0
core sdk validate                    # Validate the spec without generating

CI exit codes

Exit code Meaning
0 No breaking changes
1 Breaking changes detected
2 Error (invalid spec, missing file)

Diff configuration

The sdk.diff section in release.yaml controls behaviour:

sdk:
  diff:
    enabled: true           # Run diff check before generation
    fail_on_breaking: true  # Abort on breaking changes (CI-friendly)

When fail_on_breaking is false, breaking changes produce a warning but generation continues.

Release integration

SDK generation integrates with the release pipeline. When the sdk: section is present in release.yaml, core build release runs SDK generation after building artefacts:

core build release
  -> build artefacts
  -> generate SDKs (if sdk: configured)
  -> run diff check (warns or fails on breaking)
  -> publish to GitHub release
  -> publish SDKs (optional)

SDK generation can also run independently:

core build sdk                           # Generate using release.yaml config
core build sdk --version v1.2.3          # Explicit version
core build sdk --dry-run                 # Preview without generating

Configuration reference

In .core/release.yaml:

sdk:
  spec: api/openapi.yaml       # OpenAPI spec path (auto-detected if omitted)

  languages:                    # Languages to generate
    - typescript
    - python
    - go
    - php

  output: sdk                   # Output directory (default: sdk/)

  package:
    name: myapi                 # Base package name
    version: "{{.Version}}"     # Template — uses release version

  diff:
    enabled: true               # Run breaking change detection
    fail_on_breaking: true      # Fail on breaking changes (for CI)

  publish:                      # Optional monorepo publishing
    repo: myorg/sdks
    path: packages/myapi

Field reference

Field Type Default Description
sdk.spec string auto-detect Path to OpenAPI spec
sdk.languages []string Languages to generate (typescript, python, go, php)
sdk.output string sdk/ Output directory
sdk.package.name string Base package name for generated clients
sdk.package.version string Version template (supports {{.Version}})
sdk.diff.enabled bool false Run breaking change detection
sdk.diff.fail_on_breaking bool false Abort on breaking changes
sdk.publish.repo string Monorepo target (owner/repo)
sdk.publish.path string Path within the monorepo

Dependencies

SDK generation relies on:

Dependency Purpose
github.com/getkin/kin-openapi OpenAPI 3.x spec parsing and validation
github.com/oasdiff/oasdiff Semantic API diff and breaking change detection