From 441d76f1882d2106b73662bcce175d6f8da55301 Mon Sep 17 00:00:00 2001 From: mjoffre Date: Thu, 28 May 2026 01:38:12 +0000 Subject: [PATCH 1/5] ci: add automated SDK definition sync workflow Adds a GitHub Action that: - Runs daily at 08:00 UTC (also manual/repository_dispatch) - Downloads latest OpenAPI specs from sandbox and controlplane repos - Regenerates Python SDK clients via openapi-python-client with custom templates - Runs ruff format and lint on generated code - Creates a PR if definitions changed, no-op otherwise Tracks: ENG-2668 Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .github/workflows/update-sdk-definitions.yaml | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 .github/workflows/update-sdk-definitions.yaml diff --git a/.github/workflows/update-sdk-definitions.yaml b/.github/workflows/update-sdk-definitions.yaml new file mode 100644 index 0000000..1d330fb --- /dev/null +++ b/.github/workflows/update-sdk-definitions.yaml @@ -0,0 +1,102 @@ +name: Update SDK definitions + +on: + schedule: + - cron: "0 8 * * *" # daily at 08:00 UTC + workflow_dispatch: + repository_dispatch: + types: [update-sdk-definitions] + +permissions: + contents: write + pull-requests: write + +jobs: + update-definitions: + name: Regenerate SDK clients from upstream OpenAPI specs + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + ref: main + + - name: Install uv + uses: astral-sh/setup-uv@v4 + + - name: Install dependencies + run: uv sync --group dev + + - name: Regenerate sandbox SDK client + env: + GH_TOKEN: ${{ secrets.GH_CONTROLPLANE_TOKEN }} + run: | + echo "Downloading sandbox definition from blaxel-ai/sandbox" + curl -sf -H "Authorization: token ${GH_TOKEN}" \ + -H "Accept: application/vnd.github.v3.raw" \ + -o ./definition.yml \ + "https://api.github.com/repos/blaxel-ai/sandbox/contents/sandbox-api/docs/openapi.yml?ref=main" + + rm -rf src/blaxel/core/sandbox/client/api src/blaxel/core/sandbox/client/models + .venv/bin/openapi-python-client generate \ + --path=definition.yml \ + --output-path=./tmp-sdk-sandbox \ + --overwrite \ + --custom-template-path=./templates \ + --config=./openapi-python-client.yml + cp -r ./tmp-sdk-sandbox/blaxel/* ./src/blaxel/core/sandbox/client + rm -rf ./tmp-sdk-sandbox definition.yml + + - name: Regenerate controlplane SDK client + env: + GH_TOKEN: ${{ secrets.GH_CONTROLPLANE_TOKEN }} + run: | + echo "Downloading controlplane definition from blaxel-ai/controlplane" + curl -sf -H "Authorization: token ${GH_TOKEN}" \ + -H "Accept: application/vnd.github.v3.raw" \ + -o ./definition.yml \ + "https://api.github.com/repos/blaxel-ai/controlplane/contents/api/api/definitions/controlplane.yml?ref=main" + + rm -rf src/blaxel/core/client/api src/blaxel/core/client/models + .venv/bin/openapi-python-client generate \ + --path=definition.yml \ + --output-path=./tmp-sdk-python \ + --overwrite \ + --custom-template-path=./templates \ + --config=./openapi-python-client.yml + cp -r ./tmp-sdk-python/blaxel/* ./src/blaxel/core/client + rm -rf ./tmp-sdk-python definition.yml + + - name: Format and lint + run: | + uv run ruff format + uv run ruff check --fix + + - name: Check for changes + id: diff + run: | + if git diff --quiet; then + echo "changed=false" >> "$GITHUB_OUTPUT" + echo "No definition changes detected" + else + echo "changed=true" >> "$GITHUB_OUTPUT" + echo "Definition changes detected:" + git diff --stat + fi + + - name: Create pull request + if: steps.diff.outputs.changed == 'true' + uses: peter-evans/create-pull-request@v7 + with: + token: ${{ secrets.GITHUB_TOKEN }} + branch: automated/update-sdk-definitions + commit-message: "chore: update SDK definitions from upstream OpenAPI specs" + title: "chore: update SDK definitions from upstream OpenAPI specs" + body: | + Automated PR to sync the generated SDK clients with the latest OpenAPI specs from: + - [`blaxel-ai/sandbox`](https://github.com/blaxel-ai/sandbox) (sandbox client) + - [`blaxel-ai/controlplane`](https://github.com/blaxel-ai/controlplane) (controlplane client) + + Generated by the **Update SDK definitions** workflow. + labels: automated + delete-branch: true From c2be321ae5206976386537aca3c737adf5605343 Mon Sep 17 00:00:00 2001 From: mjoffre Date: Thu, 28 May 2026 01:39:49 +0000 Subject: [PATCH 2/5] ci: use git status --porcelain to detect untracked files git diff --quiet only checks tracked files; newly generated files from cp -r would be missed. git status --porcelain catches both tracked modifications and untracked new files. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .github/workflows/update-sdk-definitions.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/update-sdk-definitions.yaml b/.github/workflows/update-sdk-definitions.yaml index 1d330fb..3a50c76 100644 --- a/.github/workflows/update-sdk-definitions.yaml +++ b/.github/workflows/update-sdk-definitions.yaml @@ -75,13 +75,13 @@ jobs: - name: Check for changes id: diff run: | - if git diff --quiet; then + if [ -z "$(git status --porcelain)" ]; then echo "changed=false" >> "$GITHUB_OUTPUT" echo "No definition changes detected" else echo "changed=true" >> "$GITHUB_OUTPUT" echo "Definition changes detected:" - git diff --stat + git status --short fi - name: Create pull request From 964c41e77e719f18b7b7d3b6592e0899e9374437 Mon Sep 17 00:00:00 2001 From: mjoffre Date: Thu, 28 May 2026 01:42:23 +0000 Subject: [PATCH 3/5] ci: pin GitHub Actions to commit SHAs Pin actions/checkout, astral-sh/setup-uv, and peter-evans/create-pull-request to immutable commit SHAs for supply-chain security. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .github/workflows/update-sdk-definitions.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/update-sdk-definitions.yaml b/.github/workflows/update-sdk-definitions.yaml index 3a50c76..d812327 100644 --- a/.github/workflows/update-sdk-definitions.yaml +++ b/.github/workflows/update-sdk-definitions.yaml @@ -17,12 +17,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: ref: main - name: Install uv - uses: astral-sh/setup-uv@v4 + uses: astral-sh/setup-uv@38f3f104447c67c051c4a08e39b64a148898af3a # v4.2.0 - name: Install dependencies run: uv sync --group dev @@ -86,7 +86,7 @@ jobs: - name: Create pull request if: steps.diff.outputs.changed == 'true' - uses: peter-evans/create-pull-request@v7 + uses: peter-evans/create-pull-request@84ae59a2cdc2258d6fa0732dd66352dddae2a412 # v7.0.9 with: token: ${{ secrets.GITHUB_TOKEN }} branch: automated/update-sdk-definitions From a25fe386f5a46c026a372d66e634d69dab333b9e Mon Sep 17 00:00:00 2001 From: mjoffre Date: Thu, 28 May 2026 01:43:28 +0000 Subject: [PATCH 4/5] ci: use GITHUB_TOKEN for cross-repo reads (same org) No separate PAT needed since repos are in the same GitHub org. GITHUB_TOKEN has sufficient read access to blaxel-ai/sandbox and blaxel-ai/controlplane. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .github/workflows/update-sdk-definitions.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/update-sdk-definitions.yaml b/.github/workflows/update-sdk-definitions.yaml index d812327..ef83e0e 100644 --- a/.github/workflows/update-sdk-definitions.yaml +++ b/.github/workflows/update-sdk-definitions.yaml @@ -29,7 +29,7 @@ jobs: - name: Regenerate sandbox SDK client env: - GH_TOKEN: ${{ secrets.GH_CONTROLPLANE_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | echo "Downloading sandbox definition from blaxel-ai/sandbox" curl -sf -H "Authorization: token ${GH_TOKEN}" \ @@ -49,7 +49,7 @@ jobs: - name: Regenerate controlplane SDK client env: - GH_TOKEN: ${{ secrets.GH_CONTROLPLANE_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | echo "Downloading controlplane definition from blaxel-ai/controlplane" curl -sf -H "Authorization: token ${GH_TOKEN}" \ From 123acd623ea35564173d5ae1830c718c46905e06 Mon Sep 17 00:00:00 2001 From: mjoffre Date: Thu, 28 May 2026 01:48:52 +0000 Subject: [PATCH 5/5] ci: use public endpoints for spec downloads - Sandbox: raw.githubusercontent.com (public repo) - Controlplane: api.blaxel.ai/v0/openapi/controlplane.yml (public API) No auth tokens needed for either download. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .github/workflows/update-sdk-definitions.yaml | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/.github/workflows/update-sdk-definitions.yaml b/.github/workflows/update-sdk-definitions.yaml index ef83e0e..376d281 100644 --- a/.github/workflows/update-sdk-definitions.yaml +++ b/.github/workflows/update-sdk-definitions.yaml @@ -28,14 +28,10 @@ jobs: run: uv sync --group dev - name: Regenerate sandbox SDK client - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | echo "Downloading sandbox definition from blaxel-ai/sandbox" - curl -sf -H "Authorization: token ${GH_TOKEN}" \ - -H "Accept: application/vnd.github.v3.raw" \ - -o ./definition.yml \ - "https://api.github.com/repos/blaxel-ai/sandbox/contents/sandbox-api/docs/openapi.yml?ref=main" + curl -sf -o ./definition.yml \ + "https://raw.githubusercontent.com/blaxel-ai/sandbox/refs/heads/main/sandbox-api/docs/openapi.yml" rm -rf src/blaxel/core/sandbox/client/api src/blaxel/core/sandbox/client/models .venv/bin/openapi-python-client generate \ @@ -48,14 +44,10 @@ jobs: rm -rf ./tmp-sdk-sandbox definition.yml - name: Regenerate controlplane SDK client - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | echo "Downloading controlplane definition from blaxel-ai/controlplane" - curl -sf -H "Authorization: token ${GH_TOKEN}" \ - -H "Accept: application/vnd.github.v3.raw" \ - -o ./definition.yml \ - "https://api.github.com/repos/blaxel-ai/controlplane/contents/api/api/definitions/controlplane.yml?ref=main" + curl -sf -o ./definition.yml \ + "https://api.blaxel.ai/v0/openapi/controlplane.yml" rm -rf src/blaxel/core/client/api src/blaxel/core/client/models .venv/bin/openapi-python-client generate \