From 314a8c46cc88b1bb158e12bd0dba4995dc1e94aa Mon Sep 17 00:00:00 2001 From: Mish Ushakov <10400064+mishushakov@users.noreply.github.com> Date: Tue, 2 Jun 2026 15:02:25 +0200 Subject: [PATCH 1/5] ci: skip CI jobs when unaffected by changed paths Add a dorny/paths-filter "changes" detection job to the PR-triggered workflows so jobs only run when relevant paths change: - Lint / Typecheck: only when package code, spec, or lint configs change - Generated files: only when codegen inputs/outputs change - JS / Python / CLI SDK tests: only when the respective SDK changes (CLI also runs when the JS SDK changes, since it builds against it) The SDK test jobs are gated inside the reusable workflows via a new `run` input so the required matrix status checks still report (skipped jobs report success), keeping branch protection satisfied. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/cli_tests.yml | 6 +++ .github/workflows/generated_files.yml | 32 ++++++++++++++++ .github/workflows/js_sdk_tests.yml | 6 +++ .github/workflows/lint.yml | 29 ++++++++++++++ .github/workflows/python_sdk_tests.yml | 6 +++ .github/workflows/sdk_tests.yml | 53 ++++++++++++++++++++++++++ .github/workflows/typecheck.yml | 25 ++++++++++++ 7 files changed, 157 insertions(+) diff --git a/.github/workflows/cli_tests.yml b/.github/workflows/cli_tests.yml index 47fd73c8ea..83287db39f 100644 --- a/.github/workflows/cli_tests.yml +++ b/.github/workflows/cli_tests.yml @@ -7,6 +7,11 @@ on: required: false type: string default: '' + run: + description: 'Whether to actually run the build and tests. When false the matrix jobs are skipped (reported as success to required checks).' + required: false + type: boolean + default: true secrets: E2B_API_KEY: required: true @@ -16,6 +21,7 @@ permissions: jobs: test: + if: ${{ inputs.run }} defaults: run: working-directory: ./packages/cli diff --git a/.github/workflows/generated_files.yml b/.github/workflows/generated_files.yml index ff06ad5c23..d605fc9d56 100644 --- a/.github/workflows/generated_files.yml +++ b/.github/workflows/generated_files.yml @@ -7,8 +7,40 @@ permissions: contents: read jobs: + changes: + name: Detect changes + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + outputs: + generated: ${{ steps.filter.outputs.generated }} + steps: + - name: Filter changed paths + uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + generated: + - 'spec/**' + - 'codegen.Dockerfile' + - 'Makefile' + - 'packages/python-sdk/Makefile' + - 'packages/connect-python/**' + - 'packages/js-sdk/package.json' + - 'packages/js-sdk/src/api/schema.gen.ts' + - 'packages/js-sdk/src/envd/**' + - 'packages/js-sdk/src/volume/schema.gen.ts' + - 'packages/js-sdk/src/sandbox/mcp.d.ts' + - 'packages/python-sdk/e2b/api/**' + - 'packages/python-sdk/e2b/envd/**' + - 'packages/python-sdk/e2b_connect/**' + - '.github/workflows/generated_files.yml' + check-generated: name: Generated files + needs: changes + if: ${{ needs.changes.outputs.generated == 'true' }} runs-on: ubuntu-latest steps: diff --git a/.github/workflows/js_sdk_tests.yml b/.github/workflows/js_sdk_tests.yml index e235b9b221..a5e4000800 100644 --- a/.github/workflows/js_sdk_tests.yml +++ b/.github/workflows/js_sdk_tests.yml @@ -7,6 +7,11 @@ on: required: false type: string default: '' + run: + description: 'Whether to actually run the build and tests. When false the matrix jobs are skipped (reported as success to required checks).' + required: false + type: boolean + default: true secrets: E2B_API_KEY: required: true @@ -16,6 +21,7 @@ permissions: jobs: test: + if: ${{ inputs.run }} defaults: run: working-directory: ./packages/js-sdk diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index bcce93ac69..21e6dca8fd 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -6,8 +6,37 @@ on: pull_request: jobs: + changes: + name: Detect changes + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + outputs: + code: ${{ steps.filter.outputs.code }} + steps: + - name: Filter changed paths + uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + code: + - 'packages/**' + - 'spec/**' + - '.eslintrc.cjs' + - '.prettierrc' + - '.prettierignore' + - '.editorconfig' + - 'pnpm-lock.yaml' + - 'pnpm-workspace.yaml' + - 'package.json' + - '.tool-versions' + - '.github/workflows/lint.yml' + lint: name: Lint + needs: changes + if: ${{ needs.changes.outputs.code == 'true' }} runs-on: ubuntu-latest steps: diff --git a/.github/workflows/python_sdk_tests.yml b/.github/workflows/python_sdk_tests.yml index 6c74f777b7..a4b1be8366 100644 --- a/.github/workflows/python_sdk_tests.yml +++ b/.github/workflows/python_sdk_tests.yml @@ -7,6 +7,11 @@ on: required: false type: string default: '' + run: + description: 'Whether to actually run the build and tests. When false the matrix jobs are skipped (reported as success to required checks).' + required: false + type: boolean + default: true secrets: E2B_API_KEY: required: true @@ -16,6 +21,7 @@ permissions: jobs: test: + if: ${{ inputs.run }} defaults: run: working-directory: ./packages/python-sdk diff --git a/.github/workflows/sdk_tests.yml b/.github/workflows/sdk_tests.yml index 6e26cd1b85..882fd9eb37 100644 --- a/.github/workflows/sdk_tests.yml +++ b/.github/workflows/sdk_tests.yml @@ -10,44 +10,97 @@ permissions: contents: read jobs: + changes: + name: Detect changes + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + outputs: + js: ${{ steps.filter.outputs.js }} + python: ${{ steps.filter.outputs.python }} + cli: ${{ steps.filter.outputs.cli }} + steps: + - name: Filter changed paths + uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + shared: &shared + - '.github/workflows/sdk_tests.yml' + - 'spec/**' + - 'pnpm-lock.yaml' + - 'pnpm-workspace.yaml' + - 'package.json' + - '.tool-versions' + js: + - *shared + - '.github/workflows/js_sdk_tests.yml' + - 'packages/js-sdk/**' + python: + - *shared + - '.github/workflows/python_sdk_tests.yml' + - 'packages/python-sdk/**' + - 'packages/connect-python/**' + cli: + - *shared + - '.github/workflows/cli_tests.yml' + - 'packages/cli/**' + - 'packages/js-sdk/**' + js-tests: name: Production / JS SDK Tests + needs: changes uses: ./.github/workflows/js_sdk_tests.yml + with: + run: ${{ needs.changes.outputs.js == 'true' || github.event_name == 'workflow_dispatch' }} secrets: E2B_API_KEY: ${{ secrets.E2B_API_KEY }} python-tests: name: Production / Python SDK Tests + needs: changes uses: ./.github/workflows/python_sdk_tests.yml + with: + run: ${{ needs.changes.outputs.python == 'true' || github.event_name == 'workflow_dispatch' }} secrets: E2B_API_KEY: ${{ secrets.E2B_API_KEY }} cli-tests: name: Production / CLI Tests + needs: changes uses: ./.github/workflows/cli_tests.yml + with: + run: ${{ needs.changes.outputs.cli == 'true' || github.event_name == 'workflow_dispatch' }} secrets: E2B_API_KEY: ${{ secrets.E2B_API_KEY }} js-tests-staging: name: Staging / JS SDK Tests + needs: changes uses: ./.github/workflows/js_sdk_tests.yml with: E2B_DOMAIN: ${{ vars.E2B_DOMAIN_STAGING }} + run: ${{ needs.changes.outputs.js == 'true' || github.event_name == 'workflow_dispatch' }} secrets: E2B_API_KEY: ${{ secrets.E2B_API_KEY_STAGING }} python-tests-staging: name: Staging / Python SDK Tests + needs: changes uses: ./.github/workflows/python_sdk_tests.yml with: E2B_DOMAIN: ${{ vars.E2B_DOMAIN_STAGING }} + run: ${{ needs.changes.outputs.python == 'true' || github.event_name == 'workflow_dispatch' }} secrets: E2B_API_KEY: ${{ secrets.E2B_API_KEY_STAGING }} cli-tests-staging: name: Staging / CLI Tests + needs: changes uses: ./.github/workflows/cli_tests.yml with: E2B_DOMAIN: ${{ vars.E2B_DOMAIN_STAGING }} + run: ${{ needs.changes.outputs.cli == 'true' || github.event_name == 'workflow_dispatch' }} secrets: E2B_API_KEY: ${{ secrets.E2B_API_KEY_STAGING }} diff --git a/.github/workflows/typecheck.yml b/.github/workflows/typecheck.yml index 09e33d32cd..277b3966b5 100644 --- a/.github/workflows/typecheck.yml +++ b/.github/workflows/typecheck.yml @@ -4,8 +4,33 @@ on: pull_request: jobs: + changes: + name: Detect changes + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + outputs: + code: ${{ steps.filter.outputs.code }} + steps: + - name: Filter changed paths + uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + code: + - 'packages/**' + - 'spec/**' + - 'pnpm-lock.yaml' + - 'pnpm-workspace.yaml' + - 'package.json' + - '.tool-versions' + - '.github/workflows/typecheck.yml' + typecheck: name: Typecheck + needs: changes + if: ${{ needs.changes.outputs.code == 'true' }} runs-on: ubuntu-latest permissions: contents: read From bee9e2b21181b5f64a37d22eff47384482a36503 Mon Sep 17 00:00:00 2001 From: Mish Ushakov <10400064+mishushakov@users.noreply.github.com> Date: Tue, 2 Jun 2026 15:36:32 +0200 Subject: [PATCH 2/5] ci: skip paths-filter on workflow_dispatch to avoid checkout failure dorny/paths-filter falls back to git commands on non-PR events, which fails without a checkout. Guard the filter step to pull_request only; the run inputs already force a full run on workflow_dispatch. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/sdk_tests.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/sdk_tests.yml b/.github/workflows/sdk_tests.yml index 882fd9eb37..cacc1fe978 100644 --- a/.github/workflows/sdk_tests.yml +++ b/.github/workflows/sdk_tests.yml @@ -22,6 +22,10 @@ jobs: cli: ${{ steps.filter.outputs.cli }} steps: - name: Filter changed paths + # On workflow_dispatch there is no PR diff and paths-filter would fall + # back to git (failing without a checkout); the run inputs below force a + # full run for that event instead, so we only filter on pull_request. + if: github.event_name == 'pull_request' uses: dorny/paths-filter@v3 id: filter with: From 12abf2261d8dc430b896ef257575d4fb5d942001 Mon Sep 17 00:00:00 2001 From: Mish Ushakov <10400064+mishushakov@users.noreply.github.com> Date: Tue, 2 Jun 2026 18:22:02 +0200 Subject: [PATCH 3/5] ci: watch whole SDK source trees for generated-files check Enumerating individual generated outputs was fragile and missed the Python volume/mcp codegen targets. Generated files are interleaved with hand-written code inside the SDK source trees, so watch the whole trees to catch drift without maintaining a per-file allowlist. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/generated_files.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/generated_files.yml b/.github/workflows/generated_files.yml index d605fc9d56..d3cce50f2b 100644 --- a/.github/workflows/generated_files.yml +++ b/.github/workflows/generated_files.yml @@ -22,18 +22,18 @@ jobs: with: filters: | generated: + # Codegen inputs and tooling - 'spec/**' - 'codegen.Dockerfile' - 'Makefile' - 'packages/python-sdk/Makefile' - 'packages/connect-python/**' - 'packages/js-sdk/package.json' - - 'packages/js-sdk/src/api/schema.gen.ts' - - 'packages/js-sdk/src/envd/**' - - 'packages/js-sdk/src/volume/schema.gen.ts' - - 'packages/js-sdk/src/sandbox/mcp.d.ts' - - 'packages/python-sdk/e2b/api/**' - - 'packages/python-sdk/e2b/envd/**' + # Generated outputs are interleaved with hand-written code inside + # the SDK source trees, so watch the whole trees rather than an + # easily-stale list of individual generated files. + - 'packages/js-sdk/src/**' + - 'packages/python-sdk/e2b/**' - 'packages/python-sdk/e2b_connect/**' - '.github/workflows/generated_files.yml' From 530b52dbf34aa239a39cbc35cc342743bc9b67e9 Mon Sep 17 00:00:00 2001 From: Mish Ushakov <10400064+mishushakov@users.noreply.github.com> Date: Tue, 2 Jun 2026 18:24:14 +0200 Subject: [PATCH 4/5] ci: run generated-files check on any packages/ change Simpler and fully robust: any package change re-verifies generated code is in sync, with no per-path allowlist to maintain. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/generated_files.yml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/.github/workflows/generated_files.yml b/.github/workflows/generated_files.yml index d3cce50f2b..83d8a82d95 100644 --- a/.github/workflows/generated_files.yml +++ b/.github/workflows/generated_files.yml @@ -22,19 +22,10 @@ jobs: with: filters: | generated: - # Codegen inputs and tooling - 'spec/**' - 'codegen.Dockerfile' - 'Makefile' - - 'packages/python-sdk/Makefile' - - 'packages/connect-python/**' - - 'packages/js-sdk/package.json' - # Generated outputs are interleaved with hand-written code inside - # the SDK source trees, so watch the whole trees rather than an - # easily-stale list of individual generated files. - - 'packages/js-sdk/src/**' - - 'packages/python-sdk/e2b/**' - - 'packages/python-sdk/e2b_connect/**' + - 'packages/**' - '.github/workflows/generated_files.yml' check-generated: From 02c58eff7b1d2535983f26c5f9f0a6d5888a933c Mon Sep 17 00:00:00 2001 From: Mish Ushakov <10400064+mishushakov@users.noreply.github.com> Date: Tue, 2 Jun 2026 19:10:03 +0200 Subject: [PATCH 5/5] ci: include shared dep/tooling paths in generated-files filter The codegen toolchain versions are pinned via the lockfile/package.json and .tool-versions, so a dependency-only PR can change generated output. Watch the same shared paths as the lint/typecheck/sdk-tests filters. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/generated_files.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/generated_files.yml b/.github/workflows/generated_files.yml index 83d8a82d95..20d5e99410 100644 --- a/.github/workflows/generated_files.yml +++ b/.github/workflows/generated_files.yml @@ -26,6 +26,10 @@ jobs: - 'codegen.Dockerfile' - 'Makefile' - 'packages/**' + - 'pnpm-lock.yaml' + - 'pnpm-workspace.yaml' + - 'package.json' + - '.tool-versions' - '.github/workflows/generated_files.yml' check-generated: