Skip to content

SDK Generation & Publishing Process

This document explains how and when the TypeScript and Python SDKs are generated and published.

Table of Contents


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]
  1. Scan Assemblies - Uses Roslyn MetadataLoadContext to scan compiled C# assemblies
  2. Extract Metadata - Reads [DataContract] attributes for type names and namespaces
  3. Type Mapping - Maps C# types to TypeScript or Python equivalents
  4. Code Generation - Generates interfaces/dataclasses and builder functions
  5. 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:

pnpm add @luckboxstudios/foundry-sdk@2025.1011.1430.123-pr

Revert to stable:

pnpm add @luckboxstudios/foundry-sdk@latest

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: write permission (configured in workflow)

Python SDK

  • GITHUB_TOKEN (automatically provided)
  • contents: write permission (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:

"/usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/10.0.0/ref/net10.0"

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:

.\scripts\generate-typescript-sdk.ps1
.\scripts\generate-python-sdk.ps1


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