Skip to content

SDK Generation Strategy & Versioning

Status (2026-06-20): This document is an archived RFC. Its primary recommendation (Option A "Never Commit Generated Code") was not adopted for the TypeScript SDK. The TypeScript generated files under sdk/typescript/generated/ are committed to git (they are required for the Cloudflare Workers build) and are kept up to date by CI in .github/workflows/Build-Container-Apps.yml. The Python SDK does follow Option A: its generated files under sdk/python/src/foundry_sdk/generated/ are git-ignored and produced on demand locally and by CI. The "Current Situation" framing below is retained for historical context only.

Current Situation

Problem

Generated SDK files (sdk/typescript/generated/, sdk/python/src/foundry_sdk/generated/) are in an inconsistent state:

  • Listed in .gitignore (intended to be ignored)
  • Still tracked by git (committed in history)
  • Show as modified on every regeneration
  • Create noise in PRs and branches
  • No clear workflow for SDK development

Git Status

$ git status sdk/*/generated
modified:   sdk/python/src/foundry_sdk/generated/__init__.py
modified:   sdk/python/src/foundry_sdk/generated/types.py
modified:   sdk/typescript/generated/types.ts
# ... many more files

Root Cause

Files were committed before being added to .gitignore. Git continues tracking them because:

.gitignore only prevents untracked files from being added. Already-tracked files remain tracked.


Strategy Options

Philosophy: Generated code is a build artifact, like compiled binaries.

Implementation

  1. Remove from git tracking (keep files locally):

    git rm -r --cached sdk/typescript/generated sdk/python/src/foundry_sdk/generated
    git commit -m "Stop tracking generated SDK files"
    

  2. Keep in .gitignore (already there):

    sdk/typescript/generated/
    sdk/python/src/foundry_sdk/generated/
    

  3. Generate on CI/CD (already doing this):

  4. GitHub Actions workflow generates before publishing
  5. Version matches application version
  6. Published to npm (TypeScript) and GitHub Releases (Python)

Local Development Workflow

For normal backend development: - No SDK regeneration needed - Frontend uses published SDK from npm/PyPI - Fast builds, no SDK noise

For SDK development (adding queries/commands/imports):

# Step 1: Make C# changes (add DataContract, etc.)
# Step 2: Build solution
dotnet build LBS.slnx --configuration Debug

# Step 3: Regenerate SDKs locally
.\scripts\generate-typescript-sdk.ps1
.\scripts\generate-python-sdk.ps1

# Step 4: Test with local SDKs
# TypeScript: Use `npm link` or direct import
# Python: Install locally with `pip install -e sdk/python`

# Step 5: Commit ONLY the C# changes
git add src/
git commit -m "feat: Add new ModelOutput importer"
git push

# Step 6: CI/CD generates and publishes SDK automatically
# New SDK version published on merge to main

Pros

  • Clean git history - No generated code diffs in PRs
  • No merge conflicts - Generated files never conflict
  • Always fresh - SDKs always generated from current source
  • Smaller repo - No generated code in history
  • Industry standard - Most projects don't commit generated code
  • Fast local builds - Only regenerate when needed

Cons

  • Initial setup - New devs must generate locally first time
  • Manual step - Must remember to regenerate when adding types
  • CI dependency - Published SDKs only available after CI/CD runs

Option B: Always Commit Generated Code

Philosophy: Generated code is source code, treat it like any other code.

Implementation

  1. Remove from .gitignore:

    # Remove these lines from .gitignore:
    # sdk/typescript/generated/
    # sdk/python/src/foundry_sdk/generated/
    

  2. Commit generated files:

    git add sdk/typescript/generated sdk/python/src/foundry_sdk/generated
    git commit -m "Track generated SDK files"
    

  3. Update workflow - Require regeneration before commits:

  4. Add pre-commit hook to regenerate SDKs
  5. Add CI check to ensure SDKs are up to date

Local Development Workflow

# Every time you modify queries/commands/imports:
dotnet build LBS.slnx
.\scripts\generate-typescript-sdk.ps1
.\scripts\generate-python-sdk.ps1
git add src/ sdk/
git commit -m "feat: Add new import with generated SDKs"
git push

Pros

  • Visible in PRs - Can review generated code changes
  • No CI wait - SDKs available immediately after clone
  • Explicit changes - See exactly what changed in generated code
  • Works offline - No CI needed for local SDK

Cons

  • Large PRs - Generated code diffs overwhelm real changes
  • Merge conflicts - Generated files conflict frequently
  • Repo bloat - Generated code in every commit
  • Easy to forget - Devs forget to regenerate before commit
  • Drift risk - Generated code can get out of sync

Option C: Hybrid - Commit to Release Branch Only

Philosophy: Keep development clean, commit for releases.

Implementation

  1. Never commit on feature branches (like Option A)
  2. Commit on main branch via CI/CD:
    # .github/workflows/commit-generated-sdks.yml
    - name: Generate SDKs
      run: ./scripts/generate-all-sdks.sh
    
    - name: Commit generated SDKs
      run: |
        git add sdk/*/generated
        git commit -m "chore: Update generated SDKs [skip ci]"
        git push
    

Pros

  • Clean feature branches - No generated code in PRs
  • Trackable releases - Can see SDK at any point in main
  • Best of both worlds - Clean development, visible releases

Cons

  • Complex workflow - Two different rules for different branches
  • Extra CI commits - One commit per merge creates noise
  • Confusing - Unclear when generated code should exist

Recommendation: Option A - Never Commit

Why?

  1. Matches current CI/CD - Already generating and publishing
  2. Industry standard - How most projects handle codegen
  3. Clean workflow - Clear separation of source vs. artifacts
  4. Scalability - Works well as SDK grows

Implementation Plan

Phase 1: Clean Up Git (Immediate)

# Remove from tracking (keeps local files)
git rm -r --cached sdk/typescript/generated sdk/python/src/foundry_sdk/generated

# Commit the removal
git commit -m "chore: Stop tracking generated SDK files

Generated SDKs are build artifacts and should not be committed.
They are automatically generated during CI/CD and published to:
- TypeScript: GitHub Packages (npm)
- Python: GitHub Releases

For local development, regenerate using:
  ./scripts/generate-typescript-sdk.ps1
  ./scripts/generate-python-sdk.ps1

Closes: Related to SDK generation workflow"

# Push to branch
git push

Phase 2: Document Workflow (Immediate)

Update docs/developer-guide/sdk/sdk-generation.md with clear sections: - When to regenerate locally (only when adding/modifying types) - How to test local SDKs (npm link, pip install -e) - How to consume published SDKs (normal workflow)

Phase 3: Add Developer Tooling (Optional)

# Add make/npm script for convenience
make sdk-generate
# or
npm run generate:sdk

Phase 4: Add CI Check (Optional)

Verify that generated code in CI matches what would be generated locally:

- name: Verify SDK generation is deterministic
  run: |
    ./scripts/generate-all-sdks.sh
    git diff --exit-code sdk/


Versioning Strategy

Current Approach (Keep)

  • SDK version = Application version
  • Format: YYYY.MMDD.HHmm.RUN_NUMBER
  • Example: 2025.1010.1420.42

Rationale

  • Clear correlation between API and SDK versions
  • Easy to identify which API version SDK supports
  • Automated versioning, no manual bumps
  • Timestamps make version unique

Distribution Channels

TypeScript SDK

  • Registry: GitHub Packages (npm)
  • Package: @luckboxstudios/foundry-sdk
  • Install:
    npm install @luckboxstudios/foundry-sdk@2025.1010.1420.42
    
  • Published: On merge to main

Python SDK

  • Registry: GitHub Releases
  • Package: Direct download from releases
  • Install:
    pip install https://github.com/luckboxstudios/LBS.Foundry/releases/download/python-sdk-v2025.1010.1420.42/foundry_sdk-2025.1010.1420.42-py3-none-any.whl
    
  • Published: On merge to main

Migration Path (Option A)

Step 1: Current Branch (LBS-611)

# On current branch, remove from tracking
git rm -r --cached sdk/typescript/generated sdk/python/src/foundry_sdk/generated
git commit -m "chore: Stop tracking generated SDK files"
git push origin LBS-611

Step 2: Local Regeneration

# Everyone on the team runs once:
dotnet build LBS.slnx --configuration Debug
.\scripts\generate-typescript-sdk.ps1
.\scripts\generate-python-sdk.ps1

# Files now exist locally but are ignored by git

Step 3: Update Documentation

  • Update docs/developer-guide/sdk/sdk-generation.md
  • Add section to docs/developer-guide/development-workflow.md
  • Add note to CONTRIBUTING.md (if exists)

Step 4: Team Communication

Send message to team:

SDK Generation Change

Generated SDK files are no longer committed to git. They're automatically published by CI/CD.

If you're adding queries/commands/imports: 1. Make C# changes 2. Run .\scripts\generate-typescript-sdk.ps1 to test locally 3. Commit only the C# changes 4. CI/CD generates and publishes SDK automatically

If you're just doing backend work: - Nothing changes! Use published SDKs as normal.


Decision Required

Please choose a strategy:

  • [ ] Option A - Never commit generated code (Recommended)
  • [ ] Option B - Always commit generated code
  • [ ] Option C - Hybrid approach
  • [ ] Custom - Different approach (describe below)

Additional considerations: - Do you want CI checks to verify SDK freshness? - Should we add npm scripts for convenience? - Any concerns about local development workflow?


References