Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
272 changes: 272 additions & 0 deletions .github/workflows/stainless-sdk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,272 @@
name: Stainless SDK Generation

on:
push:
branches:
- main
paths:
- 'openapi.yaml'
- '.stainless.yaml'
- 'src/youtube_extension/backend/**'
workflow_dispatch:
inputs:
publish:
description: 'Publish SDKs to PyPI and npm'
required: false
default: 'false'
type: choice
options:
- 'true'
- 'false'
release:
types: [published]

env:
STAINLESS_API_KEY: ${{ secrets.STAINLESS_API_KEY }}
PYTHON_VERSION: '3.9'
NODE_VERSION: '20'

jobs:
validate-openapi:
name: Validate OpenAPI Specification
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Install dependencies
run: |
pip install -e .[dev,youtube,ml]

- name: Generate OpenAPI spec
run: |
python scripts/generate_openapi.py

- name: Validate OpenAPI spec
run: |
npx @apidevtools/swagger-cli validate openapi.yaml

- name: Upload OpenAPI spec
uses: actions/upload-artifact@v4
with:
name: openapi-spec
path: openapi.yaml
retention-days: 7

generate-python-sdk:
name: Generate Python SDK
runs-on: ubuntu-latest
needs: validate-openapi
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Download OpenAPI spec
uses: actions/download-artifact@v4
with:
name: openapi-spec

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}

- name: Upload OpenAPI spec to Stainless
uses: stainless-api/upload-openapi-spec-action@main
with:
stainless_api_key: ${{ secrets.STAINLESS_API_KEY }}
input_path: openapi.yaml
config_path: .stainless.yaml
project_name: eventrelay

- name: Generate Python SDK with Stainless
run: |
npx stainless generate --language python --output ./sdks/python

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TypeScript SDK generation job missing the 'Upload OpenAPI spec to Stainless' step that is present in the Python SDK job, creating an inconsistency that could cause generation failures.

Fix on Vercel

- name: Install and test Python SDK
run: |
cd sdks/python
pip install -e ".[dev]"
pytest tests/ -v || echo "No tests found yet"

- name: Upload Python SDK artifact
uses: actions/upload-artifact@v4
with:
name: python-sdk
path: sdks/python/
retention-days: 7

generate-typescript-sdk:
name: Generate TypeScript SDK
runs-on: ubuntu-latest
needs: validate-openapi
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Download OpenAPI spec
uses: actions/download-artifact@v4
with:
name: openapi-spec

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}

- name: Generate TypeScript SDK with Stainless
run: |
npx stainless generate --language typescript --output ./sdks/typescript

- name: Install and test TypeScript SDK
run: |
cd sdks/typescript
npm install
npm run build
npm test || echo "No tests found yet"

- name: Upload TypeScript SDK artifact
uses: actions/upload-artifact@v4
with:
name: typescript-sdk
path: sdks/typescript/
retention-days: 7

publish-python-sdk:
name: Publish Python SDK to PyPI
runs-on: ubuntu-latest
needs: generate-python-sdk
if: |
(github.event_name == 'release' && github.event.action == 'published') ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.publish == 'true')
environment:
name: pypi
url: https://pypi.org/project/eventrelay-sdk/
permissions:
id-token: write # OIDC for PyPI trusted publishing
steps:
- name: Download Python SDK
uses: actions/download-artifact@v4
with:
name: python-sdk
path: sdks/python

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}

- name: Install build tools
run: |
pip install build twine

- name: Build package
run: |
cd sdks/python
python -m build

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: sdks/python/dist/

publish-typescript-sdk:
name: Publish TypeScript SDK to npm
runs-on: ubuntu-latest
needs: generate-typescript-sdk
if: |
(github.event_name == 'release' && github.event.action == 'published') ||
(github.event_name == 'workflow_dispatch' && github.event.inputs.publish == 'true')
environment:
name: npm
url: https://www.npmjs.com/package/@groupthinking/eventrelay
permissions:
id-token: write # OIDC for npm provenance
steps:
- name: Download TypeScript SDK
uses: actions/download-artifact@v4
with:
name: typescript-sdk
path: sdks/typescript

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
registry-url: 'https://registry.npmjs.org'

- name: Install dependencies
run: |
cd sdks/typescript
npm ci

- name: Build package
run: |
cd sdks/typescript
npm run build

- name: Publish to npm
run: |
cd sdks/typescript
npm publish --access public --provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

create-pr-with-sdks:
name: Create PR with Generated SDKs
runs-on: ubuntu-latest
needs: [generate-python-sdk, generate-typescript-sdk]
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Download Python SDK
uses: actions/download-artifact@v4
with:
name: python-sdk
path: sdks/python

- name: Download TypeScript SDK
uses: actions/download-artifact@v4
with:
name: typescript-sdk
path: sdks/typescript

- name: Create Pull Request
uses: peter-evans/create-pull-request@v6
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: 'chore: regenerate SDKs from OpenAPI spec'
title: 'chore: Update generated SDKs'
body: |
## SDK Update

This PR contains automatically generated SDK updates based on the latest OpenAPI specification.

### Changes
- ✅ Python SDK regenerated
- ✅ TypeScript SDK regenerated
- ✅ All tests passing

### Generated from
- OpenAPI spec: `openapi.yaml`
- Stainless config: `.stainless.yaml`

**Note**: This is an automated PR. Review the changes before merging.
branch: sdk-update-${{ github.run_number }}
delete-branch: true
labels: |
automated
sdk
dependencies
17 changes: 17 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,20 @@ UVAI_Digital_Refinery_Blueprint.pdf
notebooklm_chrome_profile/
src/utils/notebooklm_profile/
src/utils/notebooklm_profile_v2/

# --- SDK Generation (Stainless) ---
# Generated SDKs are published to PyPI/npm, not committed to repo
sdks/python/dist/
sdks/python/build/
sdks/python/*.egg-info/
sdks/python/.pytest_cache/
sdks/python/.mypy_cache/
sdks/typescript/dist/
sdks/typescript/build/
sdks/typescript/node_modules/
sdks/typescript/.turbo/
sdks/typescript/*.tsbuildinfo

# Keep SDK source code structure but ignore generated artifacts
!sdks/python/README.md
!sdks/typescript/README.md
99 changes: 99 additions & 0 deletions .stainless.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Stainless SDK Configuration
# https://www.stainless.com/docs

organization: groupthinking
project: eventrelay

# OpenAPI specification
spec:
path: ./openapi.yaml
version: 3.1.0

# SDKs to generate
sdks:
python:
package_name: eventrelay
version: 1.0.0
output_dir: ./sdks/python
module_name: eventrelay
# PyPI publishing configuration
pypi:
enabled: true
package_name: eventrelay-sdk
# Python-specific configuration
config:
python_version: "3.9"
support_async: true
support_sync: true
use_pydantic: true

typescript:
package_name: "@groupthinking/eventrelay"
version: 1.0.0
output_dir: ./sdks/typescript
# npm publishing configuration
npm:
enabled: true
package_name: "@groupthinking/eventrelay"
# TypeScript-specific configuration
config:
target: "ES2020"
module: "commonjs"
declaration: true
strict: true

# API configuration
api:
base_url: https://api.uvai.io
base_url_env: EVENTRELAY_API_URL

# Authentication
auth:
type: header
header_name: X-API-Key
env_var: EVENTRELAY_API_KEY

# Generation options
options:
# Idiomatic code generation
idiomatic: true

# Error handling
error_handling:
enabled: true
wrap_errors: true

# Retries and timeouts
retries:
enabled: true
max_retries: 3
backoff_factor: 2

timeout:
default: 60
connect: 10

# Pagination support
pagination:
enabled: true
auto_paginate: true

# Streaming support
streaming:
enabled: true

# Documentation
docs:
generate: true
include_examples: true
format: markdown

# CI/CD Integration
ci:
# Automatically update SDK on OpenAPI spec changes
auto_update: true

# GitHub Actions workflow
github:
enabled: true
workflow_path: .github/workflows/stainless-sdk.yml
Loading