diff --git a/.github/workflows/build-exe-for-python-sdk.yml b/.github/workflows/build-exe-for-python-sdk.yml index 5fc6de459d..02c04257b0 100644 --- a/.github/workflows/build-exe-for-python-sdk.yml +++ b/.github/workflows/build-exe-for-python-sdk.yml @@ -261,15 +261,16 @@ jobs: name: deepseek_harness_sdk-${{ needs.plan.outputs.version }}-py3-none-any.whl path: dist-python - - name: Install only the SDK into a clean venv and run zero-config + - name: Install local SDK and runtime wheels into a clean venv env: - VERSION: ${{ needs.plan.outputs.version }} + RUNTIME_WHEEL: ${{ steps.runtime.outputs.wheel }} + SDK_WHEEL: deepseek_harness_sdk-${{ needs.plan.outputs.version }}-py3-none-any.whl run: | set -euo pipefail python -m venv "$RUNNER_TEMP/dsh-sdk-smoke" "$RUNNER_TEMP/dsh-sdk-smoke/bin/python" -m pip install \ - --find-links dist-python \ - deepseek-harness-sdk=="$VERSION" + "dist-python/$SDK_WHEEL" \ + "dist-python/$RUNTIME_WHEEL" "$RUNNER_TEMP/dsh-sdk-smoke/bin/python" scripts/smoke-python-runtime.py \ --scenario sdk-default "$RUNNER_TEMP/dsh-sdk-smoke/bin/python" scripts/smoke-python-runtime.py \ @@ -299,7 +300,8 @@ jobs: if: runner.os == 'Linux' env: RUNNER_ARCH: ${{ runner.arch }} - VERSION: ${{ needs.plan.outputs.version }} + RUNTIME_WHEEL: ${{ steps.runtime.outputs.wheel }} + SDK_WHEEL: deepseek_harness_sdk-${{ needs.plan.outputs.version }}-py3-none-any.whl run: | set -euo pipefail case "$RUNNER_ARCH" in @@ -307,9 +309,9 @@ jobs: ARM64) image=quay.io/pypa/manylinux_2_28_aarch64 ;; *) echo "::error::Unsupported Linux runner architecture $RUNNER_ARCH"; exit 1 ;; esac - docker run --rm -e VERSION -e DSH_TELEMETRY_DISABLED -v "$PWD:/work" -w /work "$image" bash -euxo pipefail -c ' + docker run --rm -e RUNTIME_WHEEL -e SDK_WHEEL -e DSH_TELEMETRY_DISABLED -v "$PWD:/work" -w /work "$image" bash -euxo pipefail -c ' /opt/python/cp310-cp310/bin/python -m venv /tmp/dsh-sdk - /tmp/dsh-sdk/bin/python -m pip install --find-links /work/dist-python deepseek-harness-sdk=="$VERSION" + /tmp/dsh-sdk/bin/python -m pip install "/work/dist-python/$SDK_WHEEL" "/work/dist-python/$RUNTIME_WHEEL" /tmp/dsh-sdk/bin/python /work/scripts/smoke-python-runtime.py --scenario sdk-default /tmp/dsh-sdk/bin/python /work/scripts/smoke-python-runtime.py --scenario sdk-mcp ' diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index a395a8e8bd..f5b9c63c4b 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -68,9 +68,13 @@ jobs: print(f"version={release['pep440_version'](repository_version)}") PY - - name: Install and run the published entry path + - name: Install local release wheels and run the public entry path + env: + VERSION: ${{ steps.compatibility-version.outputs.version }} run: | - python -m pip install --find-links dist "deepseek-harness-sdk==${{ steps.compatibility-version.outputs.version }}" + python -m pip install \ + "dist/deepseek_harness_sdk-$VERSION-py3-none-any.whl" \ + "dist/deepseek_harness_runtime_bin-$VERSION-py3-none-manylinux_2_28_x86_64.whl" python scripts/smoke-python-runtime.py --scenario sdk-default python scripts/smoke-python-runtime.py --scenario sdk-mcp diff --git a/python/development.i18n.yaml b/python/development.i18n.yaml index 72df1143fc..a9cdaa8daa 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: fe62a109f2643afe0b9be1ed51b86be0b9fa731f -development.zh.md: d4ab9850d6c83dc17a740240f97cef89d61faaa0 +development.md: 617d030294dafa51aea513adb811bb5f377431c9 +development.zh.md: 2049ad12856c4107788aec168e3724965cebd5af diff --git a/python/development.md b/python/development.md index fe62a109f2..617d030294 100644 --- a/python/development.md +++ b/python/development.md @@ -61,10 +61,18 @@ The root `package.json` version is authoritative for both Python distributions. Build the pure SDK wheel once and one runtime wheel on each native platform: ```sh -version="$(node -p "require('./package.json').version")" +version="$(python - <<'PY' +import runpy + +release = runpy.run_path("scripts/build-python-release.py") +print(release["pep440_version"](release["repository_version"]())) +PY +)" python scripts/build-python-release.py --package sdk --output-dir dist-python python scripts/build-python-release.py --package runtime --platform macos-arm64 --runtime-exe dist-exe/dsh-jsonrpc-agent-pkg-macos-arm64 --output-dir dist-python -pip install --find-links dist-python deepseek-harness-sdk=="$version" +pip install \ + "dist-python/deepseek_harness_sdk-$version-py3-none-any.whl" \ + "dist-python/deepseek_harness_runtime_bin-$version-py3-none-macosx_14_0_arm64.whl" ``` The runtime distribution is wheel-only. The release pipeline publishes three platform wheels with the pure SDK wheel: Linux x64, Linux arm64, and macOS 14 or newer on arm64. A `python-v` tag is accepted only when it matches the repository version; prerelease repository versions such as `0.0.1-rc.1` use their normalized PEP 440 spelling, such as `0.0.1rc1`, inside wheel filenames and metadata. diff --git a/python/development.zh.md b/python/development.zh.md index d4ab9850d6..2049ad1285 100644 --- a/python/development.zh.md +++ b/python/development.zh.md @@ -61,10 +61,18 @@ with DeepSeekHarness() as harness: 纯 SDK wheel 包只需构建一次;每个原生平台分别构建一个运行时 wheel 包: ```sh -version="$(node -p "require('./package.json').version")" +version="$(python - <<'PY' +import runpy + +release = runpy.run_path("scripts/build-python-release.py") +print(release["pep440_version"](release["repository_version"]())) +PY +)" python scripts/build-python-release.py --package sdk --output-dir dist-python python scripts/build-python-release.py --package runtime --platform macos-arm64 --runtime-exe dist-exe/dsh-jsonrpc-agent-pkg-macos-arm64 --output-dir dist-python -pip install --find-links dist-python deepseek-harness-sdk=="$version" +pip install \ + "dist-python/deepseek_harness_sdk-$version-py3-none-any.whl" \ + "dist-python/deepseek_harness_runtime_bin-$version-py3-none-macosx_14_0_arm64.whl" ``` 运行时分发包仅提供 wheel 包。发布流水线会连同纯 SDK wheel 包一起发布三个平台 wheel 包:Linux x64、Linux arm64 和 macOS 14 或更高版本的 arm64。只有与仓库版本匹配时,才接受 `python-v` 标签;`0.0.1-rc.1` 之类的仓库预发布版本在 wheel 包文件名和元数据中使用规范化的 PEP 440 写法,例如 `0.0.1rc1`。 diff --git a/scripts/ci-workflow.spec.ts b/scripts/ci-workflow.spec.ts index 45712860e5..9c0f56c85a 100644 --- a/scripts/ci-workflow.spec.ts +++ b/scripts/ci-workflow.spec.ts @@ -268,7 +268,10 @@ describe('Python release workflows', () => { }, }) expect(pythonCompat.strategy).toMatchObject({ matrix: { python: ['3.10', '3.14'] } }) - expect(JSON.stringify(pythonCompat.steps)).toContain('deepseek-harness-sdk==${{ steps.compatibility-version.outputs.version }}') + const pythonCompatSteps = JSON.stringify(pythonCompat.steps) + expect(pythonCompatSteps).toContain('dist/deepseek_harness_sdk-$VERSION-py3-none-any.whl') + expect(pythonCompatSteps).toContain('dist/deepseek_harness_runtime_bin-$VERSION-py3-none-manylinux_2_28_x86_64.whl') + expect(pythonCompatSteps).not.toContain('--find-links') const validateSteps = JSON.stringify(validate.steps) const authorize = validate.steps.filter(isRecord).find(step => step.name === 'Authorize publication request') if (!isRecord(authorize) || typeof authorize.run !== 'string') { @@ -341,7 +344,14 @@ describe('Python release workflows', () => { expect(plan.if).toContain('inputs.ci') expect(plan.if).toContain('inputs.release') expect(JSON.stringify(plan.steps)).toContain('pep440_version') - expect(JSON.stringify(workflow)).toContain('macosx_14_0_arm64') + const workflowJson = JSON.stringify(workflow) + expect(workflowJson).toContain('macosx_14_0_arm64') + expect(workflowJson).toContain('dist-python/$SDK_WHEEL') + expect(workflowJson).toContain('dist-python/$RUNTIME_WHEEL') + expect(workflowJson).toContain('/work/dist-python/$SDK_WHEEL') + expect(workflowJson).toContain('/work/dist-python/$RUNTIME_WHEEL') + expect(workflowJson).not.toContain('--find-links dist-python') + expect(workflowJson).not.toContain('--find-links /work/dist-python') expect(manylinuxAddon).toMatchObject({ if: "runner.os == 'Linux'" }) expect(JSON.stringify(manylinuxAddon)).toContain('manylinux_2_28_x86_64') expect(JSON.stringify(manylinuxAddon)).toContain('manylinux_2_28_aarch64')