From 499c1262a222ef24006e434749d3db39669c82c2 Mon Sep 17 00:00:00 2001 From: Chinesezjc Date: Fri, 21 Aug 2026 08:56:19 +0800 Subject: [PATCH 1/5] ci(python): drop PR labeled trigger for python-release dry-run Remove the pull_request:[labeled] trigger from python-release.yml so the workflow no longer fires (and shows a gray skipped check) when a PR gets any non-dry-run label. The credential-free dry-run validation is now manual-only (workflow_dispatch with publish=false), preserving the validation capability without a PR gray segment. - python-release.yml: on is workflow_dispatch only; build.if is github.event_name == 'workflow_dispatch'. - ci-workflow.spec.ts: assert python-release has no pull_request event and the simplified build.if. - python/development.(md,zh.md) and 2026-08-11-python-publication-workflow note (en/zh/i18n): describe the manual dispatch-only dry-run path. Verification: ci-workflow.spec.ts 14/14, typecheck clean, note-format 585, verify-translation-pairing consistent. --- .../2026-08-11-python-publication-workflow.i18n.yaml | 4 ++-- .../2026-08-11-python-publication-workflow.md | 2 +- .../2026-08-11-python-publication-workflow.zh.md | 2 +- .github/workflows/python-release.yml | 12 +++++------- python/development.md | 2 +- python/development.zh.md | 2 +- scripts/ci-workflow.spec.ts | 5 ++--- 7 files changed, 13 insertions(+), 16 deletions(-) diff --git a/.agents/notes/implemented/process/2026-08-11-python-publication-workflow.i18n.yaml b/.agents/notes/implemented/process/2026-08-11-python-publication-workflow.i18n.yaml index d31b17817e..00f25fc5d6 100644 --- a/.agents/notes/implemented/process/2026-08-11-python-publication-workflow.i18n.yaml +++ b/.agents/notes/implemented/process/2026-08-11-python-publication-workflow.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-11-python-publication-workflow.md -2026-08-11-python-publication-workflow.md: 870db08e1d59ad7840fa9acf822915f83ecbd31b -2026-08-11-python-publication-workflow.zh.md: 0b2b4a71b909a510bc5a7f52132dbb0ba2bf3e67 +2026-08-11-python-publication-workflow.md: 15900d70f5c78eea92e8bbe908f395f243bea527 +2026-08-11-python-publication-workflow.zh.md: 17b9b14dd16d85301796a38bb64c464c94a8ab9a diff --git a/.agents/notes/implemented/process/2026-08-11-python-publication-workflow.md b/.agents/notes/implemented/process/2026-08-11-python-publication-workflow.md index 870db08e1d..15900d70f5 100644 --- a/.agents/notes/implemented/process/2026-08-11-python-publication-workflow.md +++ b/.agents/notes/implemented/process/2026-08-11-python-publication-workflow.md @@ -10,7 +10,7 @@ The Python SDK comprises one platform-independent client wheel and three native ## Decision -The `Release (Python)` GitHub workflow exposes credential-free validation to pull requests labeled `python-release-dry-run` and to manual runs with `publish=false`. Both paths call the native wheel builder for all three platforms, install the Linux release set on Python 3.10 and 3.14, download the four resulting artifacts, verify their exact filenames and package metadata, enforce PyPI's default per-file size limit, record SHA-256 hashes, and retain one aggregate release candidate. These jobs have only repository read permission and no registry credential or OIDC permission, and pull request events cannot enter either publication job. +The `Release (Python)` GitHub workflow exposes credential-free validation to manual runs with `publish=false`. The run calls the native wheel builder for all three platforms, installs the Linux release set on Python 3.10 and 3.14, downloads the four resulting artifacts, verifies their exact filenames and package metadata, enforces PyPI's default per-file size limit, records SHA-256 hashes, and retains one aggregate release candidate. These jobs have only repository read permission and no registry credential or OIDC permission, and a dry-run run cannot enter either publication job. A run with `publish=true` must use the `python-v` tag in the private automation repository, match that repository's `github.repository` to its repository-scoped `PYPI_PUBLISHER_REPOSITORY` variable, find `PUBLIC_PYPI_RELEASE_ENABLED=true`, and receive approval from the `pypi-runtime` and `pypi` GitHub environments for runtime and SDK publication, respectively. The read-only public mirror supplies the package metadata URLs but does not run release Actions. Only the two publication jobs receive `id-token: write`; PyPI Trusted Publishing exchanges the private repository identity for short-lived project credentials, so the repository stores no PyPI token. diff --git a/.agents/notes/implemented/process/2026-08-11-python-publication-workflow.zh.md b/.agents/notes/implemented/process/2026-08-11-python-publication-workflow.zh.md index 0b2b4a71b9..17b9b14dd1 100644 --- a/.agents/notes/implemented/process/2026-08-11-python-publication-workflow.zh.md +++ b/.agents/notes/implemented/process/2026-08-11-python-publication-workflow.zh.md @@ -10,7 +10,7 @@ Python SDK 由一个平台无关的客户端 wheel 包和三个原生运行时 w ## 决策 -GitHub 的 `Release (Python)` 工作流为带有 `python-release-dry-run` 标签的拉取请求和设置 `publish=false` 的手动运行提供无凭据验证。两条路径都会为全部三个平台调用原生 wheel 包构建器,在 Python 3.10 和 3.14 上安装 Linux 发行集合,下载所得四份产物,验证其精确文件名和包元数据,执行 PyPI 默认单文件大小限制,记录 SHA-256 哈希,并保留一份汇总候选发行版。这些作业只有仓库读取权限,没有注册表凭据或 OIDC 权限,拉取请求事件无法进入任何发布作业。 +GitHub 的 `Release (Python)` 工作流为设置 `publish=false` 的手动运行提供无凭据验证。该运行会为全部三个平台调用原生 wheel 包构建器,在 Python 3.10 和 3.14 上安装 Linux 发行集合,下载所得四份产物,验证其精确文件名和包元数据,执行 PyPI 默认单文件大小限制,记录 SHA-256 哈希,并保留一份汇总候选发行版。这些作业只有仓库读取权限,没有注册表凭据或 OIDC 权限,dry-run 运行无法进入任何发布作业。 设置 `publish=true` 时,运行必须在私有自动化仓库使用 `python-v` 标签,将该仓库的 `github.repository` 与其仓库级 `PYPI_PUBLISHER_REPOSITORY` 变量匹配,找到 `PUBLIC_PYPI_RELEASE_ENABLED=true`,并分别获得 GitHub `pypi-runtime` 和 `pypi` 环境对运行时与 SDK 发布的批准。只读公开镜像提供包元数据 URL,但不运行发布 Actions。只有两个发布作业获得 `id-token: write`;PyPI Trusted Publishing 会把私有仓库身份换成短期项目凭据,因此仓库不保存 PyPI token。 diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index f5b9c63c4b..d33ad71ba5 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -1,9 +1,9 @@ name: Release (Python) -# A PR labeled python-release-dry-run or a manual run with publish=false builds -# and validates the complete release without registry credentials. Publication -# is accepted only from a manual run on the matching python-v* tag when the -# private publisher-repository identity and public-PyPI switch are configured. +# A manual run with publish=false builds and validates the complete release +# without registry credentials. Publication is accepted only from a manual run +# on the matching python-v* tag when the private publisher-repository identity +# and public-PyPI switch are configured. on: workflow_dispatch: inputs: @@ -12,8 +12,6 @@ on: required: true type: boolean default: false - pull_request: - types: [labeled] permissions: contents: read @@ -27,7 +25,7 @@ concurrency: jobs: build: name: Build four wheels - if: github.event_name == 'workflow_dispatch' || github.event.label.name == 'python-release-dry-run' + if: github.event_name == 'workflow_dispatch' uses: ./.github/workflows/build-exe-for-python-sdk.yml with: targets: node24-linux-x64,node24-linux-arm64,node24-macos-arm64 diff --git a/python/development.md b/python/development.md index 617d030294..2c96a98b56 100644 --- a/python/development.md +++ b/python/development.md @@ -79,7 +79,7 @@ The runtime distribution is wheel-only. The release pipeline publishes three pla ## Validate a release candidate -Label a pull request `python-release-dry-run`, or manually run the GitHub `Release (Python)` workflow with `publish=false`, to build all four wheels, install the Linux release set on Python 3.10 and 3.14, check exact filenames and metadata, enforce PyPI's default per-file size limit, and retain one aggregate artifact with SHA-256 hashes. Both paths have no registry credentials; a pull request run cannot enter either publication job. +Manually run the GitHub `Release (Python)` workflow with `publish=false` to build all four wheels, install the Linux release set on Python 3.10 and 3.14, check exact filenames and metadata, enforce PyPI's default per-file size limit, and retain one aggregate artifact with SHA-256 hashes. The run has no registry credentials; a dry-run run cannot enter either publication job. Public publication runs from the private automation repository; package metadata points to the separate read-only public source mirror, which does not run release Actions. The private repository defines the repository variable `PYPI_PUBLISHER_REPOSITORY` as its own `owner/name` and keeps `PUBLIC_PYPI_RELEASE_ENABLED=false` except during an intentional release. diff --git a/python/development.zh.md b/python/development.zh.md index be2a6196ae..9eaab7c163 100644 --- a/python/development.zh.md +++ b/python/development.zh.md @@ -79,7 +79,7 @@ pip install \ ## 验证候选发行版 -为拉取请求添加 `python-release-dry-run` 标签,或手动运行 GitHub 的 `Release (Python)` 工作流并设置 `publish=false`,即可构建全部四个 wheel 包,在 Python 3.10 和 3.14 上安装 Linux 发行集合,检查精确文件名和元数据,执行 PyPI 默认单文件大小限制,并保留一份带 SHA-256 哈希的汇总产物。两条路径都没有注册表凭据,拉取请求运行无法进入任何发布作业。 +手动运行 GitHub 的 `Release (Python)` 工作流并设置 `publish=false`,即可构建全部四个 wheel 包,在 Python 3.10 和 3.14 上安装 Linux 发行集合,检查精确文件名和元数据,执行 PyPI 默认单文件大小限制,并保留一份带 SHA-256 哈希的汇总产物。该运行没有注册表凭据,dry-run 运行无法进入任何发布作业。 公开发布从私有自动化仓库运行;包元数据指向独立的只读公开源码镜像,该镜像不运行发布 Actions。私有仓库把仓库变量 `PYPI_PUBLISHER_REPOSITORY` 定义为自身的 `owner/name`,并且只在有意发布期间把 `PUBLIC_PYPI_RELEASE_ENABLED` 从 `false` 改为 `true`。 diff --git a/scripts/ci-workflow.spec.ts b/scripts/ci-workflow.spec.ts index ac4535bc1b..52fa275573 100644 --- a/scripts/ci-workflow.spec.ts +++ b/scripts/ci-workflow.spec.ts @@ -273,7 +273,6 @@ describe('Python release workflows', () => { it('keeps complete wheel validation separate from protected public publication', () => { const workflow = loadWorkflow('.github/workflows/python-release.yml') const dispatch = workflowEvent(workflow, 'workflow_dispatch') - const pullRequest = workflowEvent(workflow, 'pull_request') const build = workflowJob(workflow, 'build') const pythonCompat = workflowJob(workflow, 'python-compat') const validate = workflowJob(workflow, 'validate') @@ -289,9 +288,9 @@ describe('Python release workflows', () => { } expect(dispatch.inputs.publish).toMatchObject({ type: 'boolean', default: false }) - expect(pullRequest).toEqual({ types: ['labeled'] }) + expect(workflow.on).not.toHaveProperty('pull_request') expect(build).toMatchObject({ - if: "github.event_name == 'workflow_dispatch' || github.event.label.name == 'python-release-dry-run'", + if: "github.event_name == 'workflow_dispatch'", uses: './.github/workflows/build-exe-for-python-sdk.yml', with: { targets: 'node24-linux-x64,node24-linux-arm64,node24-macos-arm64', From cb5b762922dc0d679fca80f038e7d5e1601e15c6 Mon Sep 17 00:00:00 2001 From: Chinesezjc Date: Fri, 21 Aug 2026 11:51:50 +0800 Subject: [PATCH 2/5] fix(docs): correct zh locale link in composer-edit-range note The static gate (translation pairing) failed on a pre-existing master note: 2026-08-20-composer-edit-range-from-selection.zh.md:17 linked the zh target with the en .md path. Point it at the .zh.md target and re-record the i18n hash. This unblocks the required node 24 / static gate (it is not part of the python-release gray-check change but sits on the same PR's CI path). --- .../2026-08-20-composer-edit-range-from-selection.i18n.yaml | 2 +- .../bug-fix/2026-08-20-composer-edit-range-from-selection.zh.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.agents/notes/implemented/bug-fix/2026-08-20-composer-edit-range-from-selection.i18n.yaml b/.agents/notes/implemented/bug-fix/2026-08-20-composer-edit-range-from-selection.i18n.yaml index d84448b9d2..51652f6906 100644 --- a/.agents/notes/implemented/bug-fix/2026-08-20-composer-edit-range-from-selection.i18n.yaml +++ b/.agents/notes/implemented/bug-fix/2026-08-20-composer-edit-range-from-selection.i18n.yaml @@ -3,4 +3,4 @@ # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/bug-fix/2026-08-20-composer-edit-range-from-selection.md 2026-08-20-composer-edit-range-from-selection.md: f836fe4de297746d35f7343cd215e8522a0116d0 -2026-08-20-composer-edit-range-from-selection.zh.md: 56f7044ee7f60b72d32226451d663b3f18371c69 +2026-08-20-composer-edit-range-from-selection.zh.md: 86e65e4567c6d061b458e77be856aa1942cf0fe3 diff --git a/.agents/notes/implemented/bug-fix/2026-08-20-composer-edit-range-from-selection.zh.md b/.agents/notes/implemented/bug-fix/2026-08-20-composer-edit-range-from-selection.zh.md index 56f7044ee7..86e65e4567 100644 --- a/.agents/notes/implemented/bug-fix/2026-08-20-composer-edit-range-from-selection.zh.md +++ b/.agents/notes/implemented/bug-fix/2026-08-20-composer-edit-range-from-selection.zh.md @@ -14,7 +14,7 @@ Status: implemented 此时草稿看上去仍然正确,却已不携带任何结构化引用,提交走的是无 occurrence 的那条路,把草稿原样发出。宿主收到的是给人看的标签而不是所有者的模型形式,什么也解析不出来。专为阻止这种降级而存在的序列化守卫从不运行,因为它只在还有 occurrence 需要序列化时才触发。 -这条路径是在引用[变成字面内联文本](../feature/2026-07-27-web-file-and-session-references.md)之后才可达的。此前一个引用占据一个 `U+FFFC`——任何按键都打不出的字符,扫描无从撞车。 +这条路径是在引用[变成字面内联文本](../feature/2026-07-27-web-file-and-session-references.zh.md)之后才可达的。此前一个引用占据一个 `U+FFFC`——任何按键都打不出的字符,扫描无从撞车。 ## 决策 From 374f3cdb0770a80a7ea99909ec4e4d3ff042ebf1 Mon Sep 17 00:00:00 2001 From: Chinesezjc Date: Fri, 21 Aug 2026 11:53:50 +0800 Subject: [PATCH 3/5] fix(cic): re-record development pair and tighten python-release spec assertion Address PR #2875 review: - Re-record python/development.i18n.yaml (corpus verify-translation-pairing was out of sync after editing development.md/zh.md) and the 2026-08-11 python-publication-workflow pair after the dry-run wording tweak. - Tighten the python-release spec assertion to the exact event set (['workflow_dispatch']) instead of not.toHaveProperty('pull_request'). - Fix the 'dry-run run' wording in development.md and the note. Corpus-wide verify-translation-pairing (1001 pairs) and note-format (594) pass; ci-workflow.spec.ts 14/14. --- .../process/2026-08-11-python-publication-workflow.i18n.yaml | 2 +- .../process/2026-08-11-python-publication-workflow.md | 2 +- python/development.i18n.yaml | 4 ++-- python/development.md | 2 +- scripts/ci-workflow.spec.ts | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.agents/notes/implemented/process/2026-08-11-python-publication-workflow.i18n.yaml b/.agents/notes/implemented/process/2026-08-11-python-publication-workflow.i18n.yaml index 00f25fc5d6..b454ac5682 100644 --- a/.agents/notes/implemented/process/2026-08-11-python-publication-workflow.i18n.yaml +++ b/.agents/notes/implemented/process/2026-08-11-python-publication-workflow.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-11-python-publication-workflow.md -2026-08-11-python-publication-workflow.md: 15900d70f5c78eea92e8bbe908f395f243bea527 +2026-08-11-python-publication-workflow.md: db346dfb96d1657e732c72a3f7a3ca74f92a947a 2026-08-11-python-publication-workflow.zh.md: 17b9b14dd16d85301796a38bb64c464c94a8ab9a diff --git a/.agents/notes/implemented/process/2026-08-11-python-publication-workflow.md b/.agents/notes/implemented/process/2026-08-11-python-publication-workflow.md index 15900d70f5..db346dfb96 100644 --- a/.agents/notes/implemented/process/2026-08-11-python-publication-workflow.md +++ b/.agents/notes/implemented/process/2026-08-11-python-publication-workflow.md @@ -10,7 +10,7 @@ The Python SDK comprises one platform-independent client wheel and three native ## Decision -The `Release (Python)` GitHub workflow exposes credential-free validation to manual runs with `publish=false`. The run calls the native wheel builder for all three platforms, installs the Linux release set on Python 3.10 and 3.14, downloads the four resulting artifacts, verifies their exact filenames and package metadata, enforces PyPI's default per-file size limit, records SHA-256 hashes, and retains one aggregate release candidate. These jobs have only repository read permission and no registry credential or OIDC permission, and a dry-run run cannot enter either publication job. +The `Release (Python)` GitHub workflow exposes credential-free validation to manual runs with `publish=false`. The run calls the native wheel builder for all three platforms, installs the Linux release set on Python 3.10 and 3.14, downloads the four resulting artifacts, verifies their exact filenames and package metadata, enforces PyPI's default per-file size limit, records SHA-256 hashes, and retains one aggregate release candidate. These jobs have only repository read permission and no registry credential or OIDC permission, and a dry run cannot enter either publication job. A run with `publish=true` must use the `python-v` tag in the private automation repository, match that repository's `github.repository` to its repository-scoped `PYPI_PUBLISHER_REPOSITORY` variable, find `PUBLIC_PYPI_RELEASE_ENABLED=true`, and receive approval from the `pypi-runtime` and `pypi` GitHub environments for runtime and SDK publication, respectively. The read-only public mirror supplies the package metadata URLs but does not run release Actions. Only the two publication jobs receive `id-token: write`; PyPI Trusted Publishing exchanges the private repository identity for short-lived project credentials, so the repository stores no PyPI token. diff --git a/python/development.i18n.yaml b/python/development.i18n.yaml index 64a2cff09b..5165656123 100644 --- a/python/development.i18n.yaml +++ b/python/development.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write python/development.md -development.md: 617d030294dafa51aea513adb811bb5f377431c9 -development.zh.md: be2a6196aed13a4f748e1b178f34603bbd08e5ac +development.md: d684dafea21a8e71f7819279e5885b6e63b8f7f7 +development.zh.md: 9eaab7c1633870367d4de3b79cd630146d284ff2 diff --git a/python/development.md b/python/development.md index 2c96a98b56..d684dafea2 100644 --- a/python/development.md +++ b/python/development.md @@ -79,7 +79,7 @@ The runtime distribution is wheel-only. The release pipeline publishes three pla ## Validate a release candidate -Manually run the GitHub `Release (Python)` workflow with `publish=false` to build all four wheels, install the Linux release set on Python 3.10 and 3.14, check exact filenames and metadata, enforce PyPI's default per-file size limit, and retain one aggregate artifact with SHA-256 hashes. The run has no registry credentials; a dry-run run cannot enter either publication job. +Manually run the GitHub `Release (Python)` workflow with `publish=false` to build all four wheels, install the Linux release set on Python 3.10 and 3.14, check exact filenames and metadata, enforce PyPI's default per-file size limit, and retain one aggregate artifact with SHA-256 hashes. The run has no registry credentials; a dry run cannot enter either publication job. Public publication runs from the private automation repository; package metadata points to the separate read-only public source mirror, which does not run release Actions. The private repository defines the repository variable `PYPI_PUBLISHER_REPOSITORY` as its own `owner/name` and keeps `PUBLIC_PYPI_RELEASE_ENABLED=false` except during an intentional release. diff --git a/scripts/ci-workflow.spec.ts b/scripts/ci-workflow.spec.ts index 52fa275573..d5c135c398 100644 --- a/scripts/ci-workflow.spec.ts +++ b/scripts/ci-workflow.spec.ts @@ -288,7 +288,7 @@ describe('Python release workflows', () => { } expect(dispatch.inputs.publish).toMatchObject({ type: 'boolean', default: false }) - expect(workflow.on).not.toHaveProperty('pull_request') + expect(Object.keys(workflow.on)).toEqual(['workflow_dispatch']) expect(build).toMatchObject({ if: "github.event_name == 'workflow_dispatch'", uses: './.github/workflows/build-exe-for-python-sdk.yml', From ae193bfc077f482faaf884694bad191076648b64 Mon Sep 17 00:00:00 2001 From: Chinesezjc Date: Fri, 21 Aug 2026 11:54:36 +0800 Subject: [PATCH 4/5] fix(cic): narrow workflow.on before Object.keys in python-release assertion Guard workflow.on with isRecord before Object.keys to satisfy TS2769. --- scripts/ci-workflow.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/ci-workflow.spec.ts b/scripts/ci-workflow.spec.ts index d5c135c398..b5497b0e9e 100644 --- a/scripts/ci-workflow.spec.ts +++ b/scripts/ci-workflow.spec.ts @@ -288,6 +288,7 @@ describe('Python release workflows', () => { } expect(dispatch.inputs.publish).toMatchObject({ type: 'boolean', default: false }) + if (!isRecord(workflow.on)) throw new TypeError('python-release workflow must define on') expect(Object.keys(workflow.on)).toEqual(['workflow_dispatch']) expect(build).toMatchObject({ if: "github.event_name == 'workflow_dispatch'", From 7214d0d9588fb0e6b9477dc063c530ecdcfc1c95 Mon Sep 17 00:00:00 2001 From: Chinesezjc Date: Fri, 21 Aug 2026 11:55:57 +0800 Subject: [PATCH 5/5] refactor(python): drop now-always-true build.if python-release.yml only triggers on workflow_dispatch, so build.if: github.event_name == 'workflow_dispatch' is always true and redundant; remove it (the exact event set is already pinned in the spec). Update the spec assertion accordingly. --- .github/workflows/python-release.yml | 1 - scripts/ci-workflow.spec.ts | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index d33ad71ba5..d888d17a8a 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -25,7 +25,6 @@ concurrency: jobs: build: name: Build four wheels - if: github.event_name == 'workflow_dispatch' uses: ./.github/workflows/build-exe-for-python-sdk.yml with: targets: node24-linux-x64,node24-linux-arm64,node24-macos-arm64 diff --git a/scripts/ci-workflow.spec.ts b/scripts/ci-workflow.spec.ts index b5497b0e9e..ed59846160 100644 --- a/scripts/ci-workflow.spec.ts +++ b/scripts/ci-workflow.spec.ts @@ -291,7 +291,6 @@ describe('Python release workflows', () => { if (!isRecord(workflow.on)) throw new TypeError('python-release workflow must define on') expect(Object.keys(workflow.on)).toEqual(['workflow_dispatch']) expect(build).toMatchObject({ - if: "github.event_name == 'workflow_dispatch'", uses: './.github/workflows/build-exe-for-python-sdk.yml', with: { targets: 'node24-linux-x64,node24-linux-arm64,node24-macos-arm64',