orchestrate-multi-repo-sdks
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseOrchestrate Multi-Repo SDKs
多仓库SDK编排
Manage SDK generation when each language SDK lives in its own repository (e.g., , , ).
myapi-typescriptmyapi-pythonmyapi-go当各语言SDK存放在独立仓库(例如、、)时,管理SDK生成流程。
myapi-typescriptmyapi-pythonmyapi-goWhen to Use
适用场景
- SDKs for different languages in separate repositories
- Need PR-triggered cross-repo SDK generation
- Want automated PR reconciliation (merge/close SDK PRs when spec PR closes)
- Different teams maintain different language SDKs
- User says: "multi-repo SDK", "cross-repo workflows", "SDK PR sync"
- 不同语言的SDK位于独立仓库中
- 需要由PR触发的跨仓库SDK生成
- 希望实现PR自动协调(当规格PR关闭时,合并/关闭SDK PR)
- 不同团队维护不同语言的SDK
- 用户提及:“多仓库SDK”、“跨仓库工作流”、“SDK PR同步”
Architecture
架构
┌─────────────────────────────────────────────────────────┐
│ API Spec Repository │
├─────────────────────────────────────────────────────────┤
│ PR opened │ PR merged/closed │ Main push │
│ ↓ │ ↓ │ ↓ │
│ kick-off │ reconcile-prs │ sync │
└───────────────┴──────────────────────┴──────────────────┘
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ typescript │ │ python-sdk │ │ go-sdk │
│ SDK PR │ │ SDK PR │ │ SDK PR │
└──────────────┘ └──────────────┘ └──────────────┘┌─────────────────────────────────────────────────────────┐
│ API Spec Repository │
├─────────────────────────────────────────────────────────┤
│ PR opened │ PR merged/closed │ Main push │
│ ↓ │ ↓ │ ↓ │
│ kick-off │ reconcile-prs │ sync │
└───────────────┴──────────────────────┴──────────────────┘
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ typescript │ │ python-sdk │ │ go-sdk │
│ SDK PR │ │ SDK PR │ │ SDK PR │
└──────────────┘ └──────────────┘ └──────────────┘Workflow 1: Kick Off Generation (PR Trigger)
工作流1:触发生成(PR触发)
Triggers SDK generation in each language repo when spec PR opens:
yaml
undefined当规格PR打开时,触发各语言仓库的SDK生成:
yaml
undefined.github/workflows/kick-off-generation.yaml
.github/workflows/kick-off-generation.yaml
name: Kick Off SDK Generation
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
trigger_sdk_repos:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- repo: myapi-typescript
- repo: myapi-python
- repo: myapi-go
steps:
- name: Trigger SDK generation
env:
GH_TOKEN: ${{ secrets.SDK_REPOS_PAT }}
run: |
gh workflow run sdk_generation.yaml
--repo "your-org/${{ matrix.repo }}"
--field feature_branch="${{ github.head_ref }}"
--repo "your-org/${{ matrix.repo }}"
--field feature_branch="${{ github.head_ref }}"
undefinedname: Kick Off SDK Generation
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
trigger_sdk_repos:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- repo: myapi-typescript
- repo: myapi-python
- repo: myapi-go
steps:
- name: Trigger SDK generation
env:
GH_TOKEN: ${{ secrets.SDK_REPOS_PAT }}
run: |
gh workflow run sdk_generation.yaml
--repo "your-org/${{ matrix.repo }}"
--field feature_branch="${{ github.head_ref }}"
--repo "your-org/${{ matrix.repo }}"
--field feature_branch="${{ github.head_ref }}"
undefinedWorkflow 2: Reconcile PRs (On Merge/Close)
工作流2:PR协调(合并/关闭时)
Auto-merge or close SDK PRs when spec PR closes:
yaml
undefined当规格PR关闭时,自动合并或关闭SDK PR:
yaml
undefined.github/workflows/reconcile-prs.yaml
.github/workflows/reconcile-prs.yaml
name: Reconcile SDK PRs
on:
pull_request:
types: [closed]
jobs:
manage_sdk_prs:
runs-on: ubuntu-latest
strategy:
matrix:
repo: [myapi-typescript, myapi-python, myapi-go]
steps:
- name: Manage SDK PR
env:
GH_TOKEN: ${{ secrets.SDK_REPOS_PAT }}
run: |
branch="${{ github.event.pull_request.head.ref }}"
was_merged="${{ github.event.pull_request.merged }}"
pr_number=$(gh pr list --repo "your-org/${{ matrix.repo }}" \
--head "$branch" --json number --jq '.[0].number')
if [[ -n "$pr_number" ]]; then
if [[ "$was_merged" == "true" ]]; then
gh pr merge "$pr_number" --repo "your-org/${{ matrix.repo }}" \
--squash --delete-branch
else
gh pr close "$pr_number" --repo "your-org/${{ matrix.repo }}"
fi
fiundefinedname: Reconcile SDK PRs
on:
pull_request:
types: [closed]
jobs:
manage_sdk_prs:
runs-on: ubuntu-latest
strategy:
matrix:
repo: [myapi-typescript, myapi-python, myapi-go]
steps:
- name: Manage SDK PR
env:
GH_TOKEN: ${{ secrets.SDK_REPOS_PAT }}
run: |
branch="${{ github.event.pull_request.head.ref }}"
was_merged="${{ github.event.pull_request.merged }}"
pr_number=$(gh pr list --repo "your-org/${{ matrix.repo }}" \
--head "$branch" --json number --jq '.[0].number')
if [[ -n "$pr_number" ]]; then
if [[ "$was_merged" == "true" ]]; then
gh pr merge "$pr_number" --repo "your-org/${{ matrix.repo }}" \
--squash --delete-branch
else
gh pr close "$pr_number" --repo "your-org/${{ matrix.repo }}"
fi
fiundefinedSDK Repository Workflow
SDK仓库工作流
Each SDK repo needs a dispatchable workflow:
yaml
undefined每个SDK仓库需要一个可调度的工作流:
yaml
undefined.github/workflows/sdk_generation.yaml (in each SDK repo)
.github/workflows/sdk_generation.yaml (in each SDK repo)
name: SDK Generation
on:
workflow_dispatch:
inputs:
feature_branch:
description: 'Feature branch from spec repo'
required: false
jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create branch
if: inputs.feature_branch != ''
run: git checkout -b "${{ inputs.feature_branch }}"
- name: Generate SDK
run: speakeasy run -y
env:
SPEAKEASY_API_KEY: ${{ secrets.SPEAKEASY_API_KEY }}
- name: Create PR
if: inputs.feature_branch != ''
run: |
git add -A && git commit -m "chore: regenerate SDK" || exit 0
git push -u origin "${{ inputs.feature_branch }}"
gh pr create --title "SDK update" --body "Auto-generated" || trueundefinedname: SDK Generation
on:
workflow_dispatch:
inputs:
feature_branch:
description: 'Feature branch from spec repo'
required: false
jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create branch
if: inputs.feature_branch != ''
run: git checkout -b "${{ inputs.feature_branch }}"
- name: Generate SDK
run: speakeasy run -y
env:
SPEAKEASY_API_KEY: ${{ secrets.SPEAKEASY_API_KEY }}
- name: Create PR
if: inputs.feature_branch != ''
run: |
git add -A && git commit -m "chore: regenerate SDK" || exit 0
git push -u origin "${{ inputs.feature_branch }}"
gh pr create --title "SDK update" --body "Auto-generated" || trueundefinedRequired Secrets
所需密钥
| Secret | Where | Purpose |
|---|---|---|
| All repos | Speakeasy CLI auth |
| Spec repo | PAT with |
| 密钥 | 位置 | 用途 |
|---|---|---|
| 所有仓库 | Speakeasy CLI 认证 |
| 规格仓库 | 拥有SDK仓库 |
PR Status Reporting
PR状态报告
Report SDK generation status back to spec PR:
yaml
- name: Update PR comment
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
marker="<!-- sdk-${{ matrix.repo }}-status -->"
comment="$marker
### ${{ matrix.repo }} SDK
| Status | PR |
|--------|-----|
| ✅ Success | [View PR](url) |"
gh api "repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" \
-f body="$comment"将SDK生成状态反馈至规格PR:
yaml
- name: Update PR comment
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
marker="<!-- sdk-${{ matrix.repo }}-status -->"
comment="$marker
### ${{ matrix.repo }} SDK
| Status | PR |
|--------|-----|
| ✅ Success | [View PR](url) |"
gh api "repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" \
-f body="$comment"Multi-Repo vs Monorepo
多仓库 vs 单仓库
| Aspect | Multi-Repo | Monorepo |
|---|---|---|
| Isolation | Independent versioning | Shared versioning |
| CI Complexity | Higher | Lower |
| Best For | Different teams/cadences | Unified releases |
| 维度 | 多仓库 | 单仓库 |
|---|---|---|
| 隔离性 | 独立版本控制 | 共享版本控制 |
| CI复杂度 | 较高 | 较低 |
| 适用场景 | 不同团队/发布节奏 | 统一发布 |
Troubleshooting
故障排查
| Issue | Solution |
|---|---|
| PAT permissions | Ensure |
| Branch not found | SDK repo must have workflow on |
| PR not created | Check if branch already has PR |
| 问题 | 解决方案 |
|---|---|
| PAT权限不足 | 确保拥有 |
| 分支未找到 | SDK仓库的工作流必须存在于 |
| 未创建PR | 检查分支是否已存在对应的PR |
Related Skills
相关技能
- - SDK repo setup
start-new-sdk-project - - Single repo, multiple targets
orchestrate-multi-target-sdks
- - SDK仓库搭建
start-new-sdk-project - - 单仓库多目标SDK编排
orchestrate-multi-target-sdks