This is an automated email from the ASF dual-hosted git repository.

jason810496 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git


The following commit(s) were added to refs/heads/main by this push:
     new 270b2abfc25 Run TypeScript SDK unit tests on pull requests (#74513)
270b2abfc25 is described below

commit 270b2abfc258c512a0b931af425904321360d043
Author: Zhen-Lun (Kevin) Hong <[email protected]>
AuthorDate: Mon Oct 12 19:12:50 2026 +0800

    Run TypeScript SDK unit tests on pull requests (#74513)
    
    * Run TypeScript SDK unit tests on pull requests
    
    * Skip TypeScript SDK unit tests for ts-sdk/docs changes
---
 .github/workflows/ci-amd.yml                       | 36 ++++++++++++++++++++++
 .github/workflows/ci-arm.yml                       | 36 ++++++++++++++++++++++
 dev/breeze/doc/ci/04_selective_checks.md           |  4 +++
 .../src/airflow_breeze/utils/selective_checks.py   | 11 ++++---
 .../src/airflow_breeze/utils/verification_plan.py  |  1 +
 dev/breeze/tests/test_selective_checks.py          | 36 ++++++++++++++++++++--
 6 files changed, 118 insertions(+), 6 deletions(-)

diff --git a/.github/workflows/ci-amd.yml b/.github/workflows/ci-amd.yml
index 1d4a4340c01..bbd4a7bae76 100644
--- a/.github/workflows/ci-amd.yml
+++ b/.github/workflows/ci-amd.yml
@@ -139,6 +139,7 @@ jobs:
       run-coverage: ${{ steps.source-run-info.outputs.run-coverage }}
       run-go-sdk-tests: ${{ steps.selective-checks.outputs.run-go-sdk-tests }}
       run-java-sdk-tests: ${{ 
steps.selective-checks.outputs.run-java-sdk-tests }}
+      run-ts-sdk-tests: ${{ steps.selective-checks.outputs.run-ts-sdk-tests }}
       run-ts-sdk-docs: ${{ steps.selective-checks.outputs.run-ts-sdk-docs }}
       run-helm-tests: ${{ steps.selective-checks.outputs.run-helm-tests }}
       run-kubernetes-tests: ${{ 
steps.selective-checks.outputs.run-kubernetes-tests }}
@@ -1029,6 +1030,40 @@ jobs:
           go install golang.org/x/vuln/cmd/[email protected]
           govulncheck ./...
 
+  tests-ts-sdk:
+    name: "TypeScript SDK tests"
+    needs: [build-info]
+    runs-on: ${{ fromJSON(needs.build-info.outputs.runner-type) }}
+    timeout-minutes: 15
+    permissions:
+      contents: read
+    if: needs.build-info.outputs.run-ts-sdk-tests == 'true'
+    steps:
+      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
+        uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1  # 
v7.0.1
+        with:
+          persist-credentials: false
+      - name: Setup pnpm
+        uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413  # 
v6.1.0
+        with:
+          package_json_file: ts-sdk/package.json
+          run_install: false
+      # keep this in sync with the Node version in ts-sdk-release.yml
+      - name: Setup node
+        uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020  # 
v7.0.0
+        with:
+          node-version: "24.19.0"
+          cache: 'pnpm'
+          cache-dependency-path: ts-sdk/pnpm-lock.yaml
+      - name: Install dependencies
+        working-directory: ./ts-sdk
+        run: pnpm install --frozen-lockfile
+      - name: Run TypeScript SDK tests
+        working-directory: ./ts-sdk
+        run: pnpm test
+        env:
+          FORCE_COLOR: 2
+
   tests-java-sdk:
     name: "Java SDK tests"
     needs: [build-info]
@@ -1194,6 +1229,7 @@ jobs:
       - tests-airflow-ctl
       - tests-go-sdk
       - tests-java-sdk
+      - tests-ts-sdk
       - build-java-sdk-docs
       - build-ts-sdk-docs
       - tests-with-lowest-direct-resolution-core
diff --git a/.github/workflows/ci-arm.yml b/.github/workflows/ci-arm.yml
index 889ca016b54..86f748b347e 100644
--- a/.github/workflows/ci-arm.yml
+++ b/.github/workflows/ci-arm.yml
@@ -128,6 +128,7 @@ jobs:
       run-coverage: ${{ steps.source-run-info.outputs.run-coverage }}
       run-go-sdk-tests: ${{ steps.selective-checks.outputs.run-go-sdk-tests }}
       run-java-sdk-tests: ${{ 
steps.selective-checks.outputs.run-java-sdk-tests }}
+      run-ts-sdk-tests: ${{ steps.selective-checks.outputs.run-ts-sdk-tests }}
       run-ts-sdk-docs: ${{ steps.selective-checks.outputs.run-ts-sdk-docs }}
       run-helm-tests: ${{ steps.selective-checks.outputs.run-helm-tests }}
       run-kubernetes-tests: ${{ 
steps.selective-checks.outputs.run-kubernetes-tests }}
@@ -1018,6 +1019,40 @@ jobs:
           go install golang.org/x/vuln/cmd/[email protected]
           govulncheck ./...
 
+  tests-ts-sdk:
+    name: "TypeScript SDK tests"
+    needs: [build-info]
+    runs-on: ${{ fromJSON(needs.build-info.outputs.runner-type) }}
+    timeout-minutes: 15
+    permissions:
+      contents: read
+    if: needs.build-info.outputs.run-ts-sdk-tests == 'true'
+    steps:
+      - name: "Checkout ${{ github.ref }} ( ${{ github.sha }} )"
+        uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1  # 
v7.0.1
+        with:
+          persist-credentials: false
+      - name: Setup pnpm
+        uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413  # 
v6.1.0
+        with:
+          package_json_file: ts-sdk/package.json
+          run_install: false
+      # keep this in sync with the Node version in ts-sdk-release.yml
+      - name: Setup node
+        uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020  # 
v7.0.0
+        with:
+          node-version: "24.19.0"
+          cache: 'pnpm'
+          cache-dependency-path: ts-sdk/pnpm-lock.yaml
+      - name: Install dependencies
+        working-directory: ./ts-sdk
+        run: pnpm install --frozen-lockfile
+      - name: Run TypeScript SDK tests
+        working-directory: ./ts-sdk
+        run: pnpm test
+        env:
+          FORCE_COLOR: 2
+
   tests-java-sdk:
     name: "Java SDK tests"
     needs: [build-info]
@@ -1183,6 +1218,7 @@ jobs:
       - tests-airflow-ctl
       - tests-go-sdk
       - tests-java-sdk
+      - tests-ts-sdk
       - build-java-sdk-docs
       - build-ts-sdk-docs
       - tests-with-lowest-direct-resolution-core
diff --git a/dev/breeze/doc/ci/04_selective_checks.md 
b/dev/breeze/doc/ci/04_selective_checks.md
index 8940f5a289f..f2955c32214 100644
--- a/dev/breeze/doc/ci/04_selective_checks.md
+++ b/dev/breeze/doc/ci/04_selective_checks.md
@@ -468,6 +468,9 @@ together using `pytest-xdist` (pytest-xdist distributes the 
tests among parallel
     (`PROVIDERS_WITH_PROCESS_GLOBAL_TEST_SIDE_EFFECTS`, currently 
`cncf.kubernetes`), the side-effect
     provider is added to the same `Providers[...]` test type, because the two 
share one pytest process on
     canary and the changed tests must pass after it
+* `TS SDK unit tests` (the vitest suite run by `pnpm test` in `ts-sdk/`, 
exposed as the
+  `run-ts-sdk-tests` output) run when `TS SDK files` change: anything under 
`ts-sdk/` except `.md`
+  files, `ts-sdk/api-docs/`, and `ts-sdk/docs/` (the docs toolchain's own 
package).
 * `Java SDK E2E tests` (the `java_sdk` mode of the deployed-stack tests, 
exposed as the
   `run-java-sdk-e2e-tests` output) run when the Java SDK sources (`java-sdk/`, 
excluding `.md`), the
   Java test-fixture and native-Dag bundles 
(`airflow-e2e-tests/java-test-bundle/`,
@@ -648,6 +651,7 @@ GitHub Actions to pass the list of parameters to a command 
to execute
 | run-task-sdk-tests                                      | Whether Task SDK 
tests should be run ("true"/"false")                                            
       | true                                     |      |
 | run-ts-sdk-docs                                         | Whether the 
TypeScript SDK API reference should be built — on `ts-sdk/api-docs/`, 
`ts-sdk/docs/`, or `ts-sdk/src/` changes, including Markdown ("true"/"false")   
       | true                                     |      |
 | run-ts-sdk-e2e-tests                                    | Whether TypeScript 
SDK e2e tests should be run — on runtime-affecting `ts-sdk/`, TS e2e test, Node 
coordinator, or native Lang-SDK Dag parsing changes ("true"/"false") | true     
                                |      |
+| run-ts-sdk-tests                                        | Whether TypeScript 
SDK unit tests should be run — on `ts-sdk/` changes except Markdown, 
`api-docs/`, and `docs/` ("true"/"false") | true                                
     |      |
 | run-ui-tests                                            | Whether UI tests 
should be run ("true"/"false")                                                  
       | true                                     |      |
 | run-unit-tests                                          | Whether unit tests 
should be run ("true"/"false")                                                  
     | true                                     |      |
 | run-www-tests                                           | Whether Legacy WWW 
tests should be run ("true"/"false")                                            
     | true                                     |      |
diff --git a/dev/breeze/src/airflow_breeze/utils/selective_checks.py 
b/dev/breeze/src/airflow_breeze/utils/selective_checks.py
index 940ace8d401..246107a835d 100644
--- a/dev/breeze/src/airflow_breeze/utils/selective_checks.py
+++ b/dev/breeze/src/airflow_breeze/utils/selective_checks.py
@@ -555,10 +555,9 @@ CI_FILE_GROUP_MATCHES: HashableDict[FileGroupForCi] = 
HashableDict(
         ],
         FileGroupForCi.TS_SDK_FILES: [
             # Documentation entry points and `.md` files do not affect the 
generated
-            # supervisor schema. `ts-sdk/docs/package.json` and its lock file 
are excluded
-            # too — they pin the docs toolchain's own dependencies and do not 
affect the SDK
-            # build.
-            
r"^ts-sdk/(?!api-docs/)(?!.*\.md$)(?!docs/package(-lock)?\.json$).*",
+            # supervisor schema or the unit tests. `ts-sdk/docs/` is excluded 
too — it is the
+            # docs toolchain's own package, with its own tests that vitest 
does not run.
+            r"^ts-sdk/(?!api-docs/)(?!docs/)(?!.*\.md$).*",
         ],
         FileGroupForCi.ASSET_FILES: [
             r"^airflow-core/src/airflow/assets/",
@@ -1353,6 +1352,10 @@ class SelectiveChecks:
     def run_java_sdk_tests(self) -> bool:
         return self._should_be_run(FileGroupForCi.JAVA_SDK_FILES)
 
+    @cached_property
+    def run_ts_sdk_tests(self) -> bool:
+        return self._should_be_run(FileGroupForCi.TS_SDK_FILES)
+
     @cached_property
     def run_ts_sdk_docs(self) -> bool:
         return self._should_be_run(FileGroupForCi.TS_SDK_DOCS_FILES)
diff --git a/dev/breeze/src/airflow_breeze/utils/verification_plan.py 
b/dev/breeze/src/airflow_breeze/utils/verification_plan.py
index 6c48ad51cec..d7fa2041ca8 100644
--- a/dev/breeze/src/airflow_breeze/utils/verification_plan.py
+++ b/dev/breeze/src/airflow_breeze/utils/verification_plan.py
@@ -54,6 +54,7 @@ FLAG_COMMANDS: dict[str, tuple[tuple[str, str, str], ...]] = {
         ("unit", "cd java-sdk && ./gradlew test", "host"),
         ("docs", "breeze build-docs --sdk-docs-only --sdk=java", "breeze"),
     ),
+    "run_ts_sdk_tests": (("unit", "cd ts-sdk && pnpm install --frozen-lockfile 
&& pnpm test", "host"),),
     "run_ts_sdk_docs": (("docs", "breeze build-docs --sdk-docs-only 
--sdk=typescript", "breeze"),),
     "run_agent_framework_tests": (
         (
diff --git a/dev/breeze/tests/test_selective_checks.py 
b/dev/breeze/tests/test_selective_checks.py
index f27a3e6fe87..5533390a721 100644
--- a/dev/breeze/tests/test_selective_checks.py
+++ b/dev/breeze/tests/test_selective_checks.py
@@ -1553,13 +1553,38 @@ def assert_outputs_are_printed(expected_outputs: 
dict[str, str], stderr: str):
         pytest.param(
             ("ts-sdk/src/sdk/client.ts",),
             {
+                "run-ts-sdk-tests": "true",
                 "run-ts-sdk-docs": "true",
             },
-            id="Build ts-sdk docs when the documented sources change",
+            id="Run ts-sdk unit tests and build docs when the documented 
sources change",
+        ),
+        pytest.param(
+            ("ts-sdk/pnpm-lock.yaml",),
+            {
+                "run-ts-sdk-tests": "true",
+                "run-ts-sdk-docs": "false",
+            },
+            id="Run ts-sdk unit tests when the lock file changes",
+        ),
+        pytest.param(
+            ("ts-sdk/docs/package.json",),
+            {
+                "run-ts-sdk-tests": "false",
+            },
+            id="Skip ts-sdk unit tests when only the docs toolchain's 
package.json changes",
+        ),
+        pytest.param(
+            ("ts-sdk/docs/typedoc.config.mjs",),
+            {
+                "run-ts-sdk-tests": "false",
+                "run-ts-sdk-docs": "true",
+            },
+            id="Skip ts-sdk unit tests but build docs when the docs toolchain 
config changes",
         ),
         pytest.param(
             ("ts-sdk/docs/index.md",),
             {
+                "run-ts-sdk-tests": "false",
                 "run-ts-sdk-docs": "true",
                 "run-ts-sdk-e2e-tests": "false",
             },
@@ -1568,6 +1593,7 @@ def assert_outputs_are_printed(expected_outputs: 
dict[str, str], stderr: str):
         pytest.param(
             ("ts-sdk/api-docs/dag-authoring-api.ts",),
             {
+                "run-ts-sdk-tests": "false",
                 "run-ts-sdk-docs": "true",
                 "run-ts-sdk-e2e-tests": "false",
                 "prod-image-build": "false",
@@ -1591,9 +1617,10 @@ def assert_outputs_are_printed(expected_outputs: 
dict[str, str], stderr: str):
         pytest.param(
             ("ts-sdk/README.md",),
             {
+                "run-ts-sdk-tests": "false",
                 "run-ts-sdk-docs": "false",
             },
-            id="Skip ts-sdk docs build for a ts-sdk README-only change",
+            id="Skip ts-sdk unit tests and docs build for a ts-sdk README-only 
change",
         ),
         pytest.param(
             
("airflow-e2e-tests/java-test-bundle/src/java/org/apache/airflow/e2e/TestBundleBuilder.java",),
@@ -2081,6 +2108,11 @@ def 
test_java_sdk_conformance_hook_runs_for_serializer_changes(files: tuple[str,
             True,
             id="skipped when only the docs toolchain's lock file changes",
         ),
+        pytest.param(
+            ("ts-sdk/docs/typedoc.config.mjs",),
+            True,
+            id="skipped when only the docs toolchain's config changes",
+        ),
         pytest.param(
             ("ts-sdk/api-docs/dag-authoring-api.ts",),
             True,

Reply via email to