SDK Generation & Publishing Process¶
This document explains how and when the TypeScript and Python SDKs are generated and published.
Table of Contents¶
- Overview
- How SDKs Are Generated
- When SDKs Are Generated
- Manual Generation
- Automated Publishing
- Version Strategy
- Prerequisites
Overview¶
The LBS Foundry platform provides auto-generated client SDKs in two languages:
| SDK | Language | Distribution | Auto-Published |
|---|---|---|---|
| TypeScript SDK | TypeScript | GitHub Packages (npm) | Yes |
| Python SDK | Python | GitHub Releases | Yes |
Both SDKs are generated from the same C# domain types using the LBS.Tools.SdkGenerator tool.
How SDKs Are Generated¶
Generation Tool¶
Tool: LBS.Tools.SdkGenerator
Location: src/Tools/LBS.Tools.SdkGenerator/
Process:
graph TD
A[C# Domain Types] --> B[TypeScanner]
B --> C[ScannedType Objects]
C --> D{Language?}
D -->|TypeScript| E[TypeScriptGenerator]
D -->|Python| F[PythonGenerator]
E --> G[TypeScript Files]
F --> H[Python Files]
- Scan Assemblies - Uses Roslyn
MetadataLoadContextto scan compiled C# assemblies - Extract Metadata - Reads
[DataContract]attributes for type names and namespaces - Type Mapping - Maps C# types to TypeScript or Python equivalents
- Code Generation - Generates interfaces/dataclasses and builder functions
- Output - Writes generated code to SDK directories
CLI Command¶
dotnet run --project src/Tools/LBS.Tools.SdkGenerator/LBS.Tools.SdkGenerator.csproj -- \
<assembly-dir> \
<reference-dir> \
<output-dir> \
--language <typescript|python>
Example:
# TypeScript
dotnet run --project src/Tools/LBS.Tools.SdkGenerator/LBS.Tools.SdkGenerator.csproj -- \
"src/Domain/LBS.Ballr.Core/bin/Debug/net10.0/LBS.Ballr.Core.dll" \
"C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\10.0.0\ref\net10.0" \
"sdk/typescript/generated" \
--language typescript
# Python
dotnet run --project src/Tools/LBS.Tools.SdkGenerator/LBS.Tools.SdkGenerator.csproj -- \
"src/Domain/LBS.Ballr.Core/bin/Debug/net10.0/LBS.Ballr.Core.dll" \
"C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\10.0.0\ref\net10.0" \
"sdk/python/src/foundry_sdk/generated" \
--language python
When SDKs Are Generated¶
1. Local Development (Manual)¶
When: Whenever a developer needs updated SDK types locally
How: Run generation scripts
# Windows
.\scripts\generate-typescript-sdk.ps1
.\scripts\generate-python-sdk.ps1
# Linux/macOS
./scripts/generate-typescript-sdk.sh
./scripts/generate-python-sdk.sh
Use Cases: - Testing new query/command/import types - Developing frontend features that use new APIs - Testing bulk import operations locally - Validating type changes before merge
2. Automated CI/CD¶
When: Automatically triggered when domain types change
Production Releases (Main Branch)¶
TypeScript SDK¶
Workflow: .github/workflows/Build-Container-Apps.yml (unified workflow)
Triggers:
- Push to main branch
- Changes in src/Domain/**/*.cs
- Changes in src/Tools/LBS.Tools.SdkGenerator/**
- Manual workflow dispatch
Steps:
1. Build C# solution
2. Generate TypeScript SDK
3. Install npm dependencies
4. Build TypeScript
5. Version with timestamp: 0.YYMMDD.HHMM.RUN_NUMBER
6. Publish to GitHub Packages
Result: @luckboxstudios/foundry-sdk@0.250110.1423.123
Python SDK¶
Workflow: .github/workflows/Build-Container-Apps.yml (unified workflow)
Triggers:
- Push to main branch
- Changes in src/Domain/**/*.cs
- Changes in src/Tools/LBS.Tools.SdkGenerator/**
- Manual workflow dispatch
Steps:
1. Build C# solution
2. Generate Python SDK
3. Update version in pyproject.toml
4. Build Python package (wheel + source distribution)
5. Version with timestamp: 0.YYMMDD.HHMM.RUN_NUMBER
6. Create GitHub Release with SDK files as assets
Result: GitHub Release python-sdk-v0.250110.1423.123 with downloadable wheel and source distribution
PR Builds (Pre-release SDKs)¶
When: Automatically triggered on PR builds (same workflow as production)
Workflow: .github/workflows/Build-Container-Apps.yml (unified workflow)
PR builds use the same publishing jobs as production builds, but with automatic versioning to mark them as pre-releases:
Version Format: YYYY.MMDD.HHMM.RUN-pr
- Example: 2025.1011.1430.123-pr
- The -pr suffix is automatically added for pull request builds
- Same versioning logic used for NuGet packages
- Python Note: Package version converted to PEP 440 format (2025.1011.1430.123.dev0)
Behavior:
- TypeScript SDK published to GitHub Packages with -pr version
- Python SDK published to GitHub Releases (package uses .dev0, release tagged with -pr)
- Git tag created: v2025.1011.1430.123-pr
- Does not affect @latest tags or stable releases
TypeScript SDK (PR)¶
Published to: GitHub Packages (@luckboxstudios/foundry-sdk)
Installation:
Revert to stable:
Python SDK (PR)¶
Published to: GitHub Releases (marked as pre-release)
Version Conversion: -pr → .dev0 (PEP 440 compliant)
- Release tag: python-sdk-v2025.1011.1430.123-pr
- Package version: 2025.1011.1430.123.dev0
Installation:
pip install https://github.com/luckboxstudios/LBS.Foundry/releases/download/python-sdk-v2025.1011.1430.123-pr/foundry_sdk-2025.1011.1430.123.dev0-py3-none-any.whl
Revert to stable:
pip install https://github.com/luckboxstudios/LBS.Foundry/releases/latest/download/foundry_sdk-py3-none-any.whl
Unified Workflow¶
PR created/updated with domain type changes
↓
Build-Container-Apps.yml workflow runs
↓
├─→ Build & Test
├─→ Build Docker Containers
├─→ Publish NuGet Packages (with -pr)
├─→ Publish Python SDK (marked prerelease)
├─→ Publish TypeScript SDK (with -pr)
└─→ Create Git Tag (v2025.1011.1430.123-pr)
↓
Test pre-release SDKs in your apps
↓
PR merged to main
↓
Same workflow runs without -pr suffix
↓
Stable versions published
3. Manual Workflow Dispatch¶
When: On-demand when needed
How:
1. Go to GitHub Actions
2. Select "Generate and Publish TypeScript SDK" or "Generate and Publish Python SDK"
3. Click "Run workflow"
4. Select branch (usually main)
5. Click "Run workflow"
Use Cases: - Force republish after a failed CI run - Publish SDK without code changes - Testing workflow changes
Manual Generation¶
Prerequisites¶
- .NET 10 SDK
- (TypeScript) Node.js 18+ & npm
- (Python) Python 3.11+
Step-by-Step¶
TypeScript SDK¶
# 1. Build the solution
dotnet build LBS.slnx --configuration Release
# 2. Generate SDK
.\scripts\generate-typescript-sdk.ps1
# 3. Build TypeScript
cd sdk/typescript
pnpm install
pnpm build
# 4. (Optional) Test locally
pnpm link --global
# In your frontend project:
pnpm link --global @luckboxstudios/foundry-sdk
Python SDK¶
# 1. Build the solution
dotnet build LBS.slnx --configuration Release
# 2. Generate SDK
.\scripts\generate-python-sdk.ps1
# 3. Install in development mode
cd sdk/python
pip install -e .
# 4. (Optional) Build package
python -m build
Automated Publishing¶
TypeScript (GitHub Packages)¶
Registry: https://npm.pkg.github.com
Package: @luckboxstudios/foundry-sdk
Installation:
Windows users: See GitHub Token Setup Guide for Windows for detailed instructions.
# Configure pnpm (uses same .npmrc file)
echo "@luckboxstudios:registry=https://npm.pkg.github.com" >> ~/.npmrc
echo "//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN" >> ~/.npmrc
# Install
pnpm add @luckboxstudios/foundry-sdk
Authentication:
- Local development: GitHub Personal Access Token (see setup guide)
- CI/CD: GITHUB_TOKEN (automatically provided by GitHub Actions)
- Required permission: read:packages
Python (GitHub Releases)¶
Location: GitHub Releases
Package: foundry-sdk
Installation:
# Latest version
pip install https://github.com/luckboxstudios/LBS.Foundry/releases/latest/download/foundry_sdk-py3-none-any.whl
# Specific version
pip install https://github.com/luckboxstudios/LBS.Foundry/releases/download/python-sdk-v0.250110.1423.123/foundry_sdk-0.250110.1423.123-py3-none-any.whl
Using requirements.txt:
foundry-sdk @ https://github.com/luckboxstudios/LBS.Foundry/releases/latest/download/foundry_sdk-py3-none-any.whl
Authentication:
- Uses GITHUB_TOKEN (automatically provided by GitHub Actions)
- No additional secrets required
Version Strategy¶
Timestamp-Based Versioning¶
Both SDKs use timestamp-based versioning to ensure uniqueness and sortability:
Format: 0.YYMMDD.HHMM.RUN_NUMBER
Example: 0.250110.1423.123
- 0 - Major version (reserved for future breaking changes)
- 250110 - Date (January 10, 2025)
- 1423 - Time (14:23 UTC)
- 123 - GitHub Actions run number
Benefits: - Unique version for every publish - Chronologically sortable - Easy to identify when SDK was generated - Automatic - no manual version bumping
Semantic Versioning (Future)¶
When the SDK API stabilizes, consider switching to semantic versioning: - Major - Breaking changes to generated types - Minor - New types/properties added (backward compatible) - Patch - Bug fixes in client libraries (not generated code)
Prerequisites¶
For CI/CD (GitHub Actions)¶
TypeScript SDK¶
GITHUB_TOKEN(automatically provided)packages: writepermission (configured in workflow)
Python SDK¶
GITHUB_TOKEN(automatically provided)contents: writepermission (configured in workflow)- No additional secrets required!
For Local Development¶
TypeScript¶
- .NET 10 SDK
- Node.js 18+
- npm or pnpm
Python¶
- .NET 10 SDK
- Python 3.11+
- pip
Troubleshooting¶
"Project not found" during Docker build¶
Problem: Docker build fails because LBS.Tools.SdkGenerator project is missing
Solution: Ensure DockerFile includes:
COPY src/Tools/LBS.Tools.SdkGenerator/LBS.Tools.SdkGenerator.csproj src/Tools/LBS.Tools.SdkGenerator/
GitHub Actions: "Could not find core assembly"¶
Problem: SDK generation fails in CI with assembly resolution error
Solution: Verify reference path in workflow:
Update if .NET version changes.
GitHub Releases: "Resource not accessible by integration"¶
Problem: Python SDK release creation fails
Solution:
1. Verify workflow has contents: write permission in workflow file
2. Check GITHUB_TOKEN permissions in repository settings
3. Ensure workflow is running on appropriate branch (main)
Generated SDK has wrong imports¶
Problem: Python imports fail or TypeScript imports incorrect
Solution: Regenerate SDK with updated generator:
Summary¶
Quick Reference¶
| Scenario | TypeScript | Python |
|---|---|---|
| Local Development | .\scripts\generate-typescript-sdk.ps1 |
.\scripts\generate-python-sdk.ps1 |
| Production Release | On merge to main (Build-Container-Apps.yml) |
On merge to main (Build-Container-Apps.yml) |
| PR Build (Pre-release) | On PR build (Build-Container-Apps.yml) | On PR build (Build-Container-Apps.yml) |
| Install Stable | pnpm add @luckboxstudios/foundry-sdk |
pip install https://github.com/{org}/{repo}/releases/latest/download/foundry_sdk-py3-none-any.whl |
| Install PR Version | pnpm add @luckboxstudios/foundry-sdk@2025.1011.1430.123-pr |
pip install https://github.com/{org}/{repo}/releases/download/python-sdk-v2025.1011.1430.123-pr/foundry_sdk-2025.1011.1430.123.dev0-py3-none-any.whl |
| Distribution | GitHub Packages (npm) | GitHub Releases |
| Version Format (Stable) | YYYY.MMDD.HHMM.RUN |
YYYY.MMDD.HHMM.RUN |
| Version Format (PR) | YYYY.MMDD.HHMM.RUN-pr |
YYYY.MMDD.HHMM.RUN.dev0 (PEP 440) |
| Workflow | Unified Build-Container-Apps.yml | Unified Build-Container-Apps.yml |
| Authentication | GitHub PAT required | No authentication required |
Workflow Summary¶
Developer adds/modifies query/command/import
↓
Commit & push to branch
↓
Create PR → Review → Merge to main
↓
GitHub Actions triggered (domain types changed)
↓
├─→ TypeScript SDK: Generate → Build → Publish to GitHub Packages (npm)
└─→ Python SDK: Generate → Build → Create GitHub Release (wheel + tar.gz)
↓
Frontend/Python apps can install updated SDKs from GitHub
Related Documentation¶
- SDK Generation Guide - Technical deep dive
- TypeScript SDK README - TypeScript usage
- Python SDK README - Python usage
- ADR-007 - Architecture decisions