matelab-python-sdk 0.3.0a1__tar.gz → 0.3.0a2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/.agents/skills/matelab-sdk-release/SKILL.md +13 -8
  2. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/.workflow/release.yml +6 -34
  3. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/AGENTS.md +2 -2
  4. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/PKG-INFO +1 -1
  5. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/contracts/matelab-integration-v1.lock.json +3 -3
  6. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/contracts/matelab-integration-v1.openapi.yaml +7 -7
  7. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/docs/agent-workflows.md +8 -6
  8. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/docs/api.md +5 -5
  9. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/docs/development.md +26 -10
  10. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/docs/operation-coverage.yaml +1 -1
  11. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/pyproject.toml +1 -1
  12. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/src/matelab/_generated/models.py +1 -1
  13. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_release.py +3 -3
  14. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/uv.lock +1 -1
  15. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/.agents/skills/matelab-sdk-release/agents/openai.yaml +0 -0
  16. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/.agents/skills/matelab-sdk-release/scripts/verify_pypi.py +0 -0
  17. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/.env.example +0 -0
  18. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/.gitignore +0 -0
  19. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/.python-version +0 -0
  20. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/CONTEXT.md +0 -0
  21. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/LICENSE +0 -0
  22. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/NOTICE +0 -0
  23. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/README.md +0 -0
  24. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/docs/agent-architecture.md +0 -0
  25. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/scripts/check_installed_package.py +0 -0
  26. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/scripts/check_release.py +0 -0
  27. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/scripts/generate_models.py +0 -0
  28. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/src/matelab/__init__.py +0 -0
  29. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/src/matelab/_generated/__init__.py +0 -0
  30. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/src/matelab/_hashes.py +0 -0
  31. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/src/matelab/_transport.py +0 -0
  32. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/src/matelab/_wire_validation.py +0 -0
  33. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/src/matelab/client.py +0 -0
  34. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/src/matelab/domains/__init__.py +0 -0
  35. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/src/matelab/domains/_attachment_content.py +0 -0
  36. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/src/matelab/domains/cloud_drive.py +0 -0
  37. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/src/matelab/domains/groups.py +0 -0
  38. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/src/matelab/domains/literature.py +0 -0
  39. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/src/matelab/domains/notebooks.py +0 -0
  40. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/src/matelab/domains/records.py +0 -0
  41. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/src/matelab/domains/templates.py +0 -0
  42. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/src/matelab/domains/uploads.py +0 -0
  43. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/src/matelab/domains/users.py +0 -0
  44. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/src/matelab/errors.py +0 -0
  45. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/src/matelab/py.typed +0 -0
  46. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/src/matelab/session.py +0 -0
  47. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/src/matelab/streaming.py +0 -0
  48. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/conftest.py +0 -0
  49. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/provider/test_provider_smoke.py +0 -0
  50. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_async_attachment_upload.py +0 -0
  51. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_client.py +0 -0
  52. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_cloud_drive.py +0 -0
  53. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_comments_and_downloads.py +0 -0
  54. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_consumer_smoke.py +0 -0
  55. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_errors.py +0 -0
  56. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_extended_records.py +0 -0
  57. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_generation.py +0 -0
  58. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_groups.py +0 -0
  59. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_notebook_lifecycle.py +0 -0
  60. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_notebooks.py +0 -0
  61. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_operation_coverage.py +0 -0
  62. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_record_lifecycle.py +0 -0
  63. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_record_mutations.py +0 -0
  64. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_records.py +0 -0
  65. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_streaming.py +0 -0
  66. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_template_lifecycle.py +0 -0
  67. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_templates.py +0 -0
  68. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_transport.py +0 -0
  69. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_uploads_and_literature.py +0 -0
  70. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/test_users.py +0 -0
  71. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/typing/consumer.py +0 -0
  72. {matelab_python_sdk-0.3.0a1 → matelab_python_sdk-0.3.0a2}/tests/typing/pyproject.toml +0 -0
@@ -34,7 +34,8 @@ coverage 和当前态文档。公开接口和生命周期沿 public intent → w
34
34
  ## 2. 验证与审查
35
35
 
36
36
  执行 `docs/agent-workflows.md#delivery-gate`,具体命令取 `docs/development.md#development`。
37
- 代码、契约、依赖或构建行为变化先聚焦再完整测试;聚焦用例不能代替完整 `pytest`。修复需补充的用例来自契约、
37
+ 代码、契约、依赖或构建行为变化先聚焦再完整测试;聚焦用例不能代替完整 `pytest`。发布前的支持版本测试、静态
38
+ 检查和安装后消费验证在本地完成,发布 CI 不重复执行。修复需补充的用例来自契约、
38
39
  独立示例或可验证属性,不复刻实现,不增加 Provider 逐路由 conformance。
39
40
 
40
41
  真实 smoke 按 `docs/agent-workflows.md#provider-validation` 确认目标、ignore 和授权。授权覆盖隔离服务的登录、
@@ -58,17 +59,21 @@ SDK 版本与 spec 日历版本独立,不跳过未占用的预发布序号。`
58
59
  本项目版本。仅改版本时保持其余 lock 内容,使用发布 workflow 固定的 uv 检查兼容性。
59
60
 
60
61
  按需读配置/依赖章节;不因发布顺手升级依赖、Node、uv 或流水线插件。文档在提交前完成,仅维护受影响的当前态,不新建
61
- CHANGELOG。正常发布由 CI 完成可复现构建、制品审计和安装后消费;只有打包故障或打包配置变化需要时才本地构建,
62
- 使用临时目录,不积累 `dist/`。
62
+ CHANGELOG。本地为发布前消费验证、打包故障或打包配置变化按需构建,使用临时目录,不积累 `dist/`。
63
63
 
64
64
  复核最终 diff、版本、Contract pin 和有效验证证据,将本次尚未提交的实现、测试、文档及版本号放入同一个
65
65
  release commit。已有提交的历史仅在另有授权时改写。
66
66
 
67
- ## 4. 推送、发布并核验
67
+ ## 4. 推送与自动发布
68
68
 
69
- 执行 `docs/agent-workflows.md#release`:创建指向 release commit 的 annotated `v{version}` tag,推送
70
- `origin` 的 main/tag,并验证远端 refs;tag 推送自动触发发布 CI。跟踪该 commit/tag 的 CI,确认测试、
71
- 可复现构建、制品审计、安装后消费和 PyPI 上传成功;tag 推送成功不等于发布完成。
69
+ 本地验证通过后,按 `docs/agent-workflows.md#release` 完成:
70
+
71
+ 1. 创建指向本次 release commit 的新 annotated `v{version}` tag,版本与 `pyproject.toml` 一致。
72
+ 2. 推送 `origin` 的 main 和本次新 tag,核对远端 refs 均对应本次 release commit。
73
+ 3. 跟踪新 tag 自动触发的 Gitee 流水线,由其完成可复现构建、制品审计和 PyPI 上传;CI 不重复本地验证。
74
+
75
+ 已发布版本不可覆盖,对应 tag 不再移动。main 可以继续前进,无需与历史 tag 指向同一提交;
76
+ 后续发版使用新版本、新 tag。
72
77
 
73
78
  从本次 CI 构建审计输出或下载的制品取得 wheel/sdist 的 SHA-256,不能仅用 PyPI 自报哈希证明 CI/PyPI 一致。
74
79
  在 SDK 锁定开发环境中运行本技能的只读核验器:
@@ -85,5 +90,5 @@ uv run --frozen --no-sync python -B .agents/skills/matelab-sdk-release/scripts/v
85
90
  历史制品。PyPI 暂未可读时允许短暂重试,等待期间保持进度更新。
86
91
 
87
92
  失败时定位具体阶段,优先重试失败环节;不通过删测试、跳检查或自动另选版本制造成功。改变已推送历史或处理失败
88
- 候选前核对现有授权,已发布版本不可覆盖。最后报告版本/链接、单次提交、`origin` 的 main/tag refs、CI/PyPI 核验和工作区状态;
93
+ 候选前核对现有授权。最后报告版本/链接、发布提交、main 与新 tag 的远端 refs、Gitee/PyPI 核验和工作区状态;
89
94
  明确剩余失败或未验证项。
@@ -10,26 +10,26 @@ triggers:
10
10
  - v
11
11
  stages:
12
12
  - name: release
13
- displayName: Test, build and publish
13
+ displayName: Build and publish
14
14
  strategy: naturally
15
15
  trigger: auto
16
16
  steps:
17
17
  - step: build@python
18
18
  name: build-and-publish
19
- displayName: Validate and publish release
19
+ displayName: Build and publish release
20
20
  # Gitee's Python bootstraps uv; the SDK runs on uv-managed Python 3.15.
21
21
  pythonVersion: "3.14"
22
22
  commands: |
23
23
  set +x
24
24
  set -eu
25
- # Gitee injects its pytest tooling into Python's import path.
25
+ # Keep Gitee's Python tooling out of the build environment.
26
26
  unset PYTHONPATH PYTHONHOME
27
27
  python -m pip install --user --index-url https://pypi.org/simple "uv==0.13.7"
28
28
  export PATH="$(python -m site --user-base)/bin:$PATH"
29
29
  uv --version
30
30
  release_tag="v$(uv version --short)"
31
31
  build_ref="${GITEE_BRANCH:?Gitee build ref is required}"
32
- if [ "$build_ref" != main ] && [ "$build_ref" != "$release_tag" ]; then
32
+ if [ "$build_ref" != "$release_tag" ]; then
33
33
  echo "Release ref must be $release_tag; received $build_ref" >&2
34
34
  exit 1
35
35
  fi
@@ -37,20 +37,10 @@ stages:
37
37
  echo "Checkout does not match the Gitee build commit" >&2
38
38
  exit 1
39
39
  fi
40
+ : "${UV_PUBLISH_TOKEN:?Configure UV_PUBLISH_TOKEN as a protected pipeline secret}"
40
41
  export SOURCE_DATE_EPOCH="$(git show -s --format=%ct HEAD)"
41
- unset MATELAB_PROVIDER_BASE_URL MATELAB_PROVIDER_USERNAME MATELAB_PROVIDER_PASSWORD
42
-
43
- test_status=0
44
- for python_version in 3.12 3.13 3.14 3.15; do
45
- uv run --frozen --exact --python "$python_version" pytest -rs || test_status=1
46
- done
47
- test "$test_status" -eq 0
48
-
49
42
  export UV_PYTHON="$(cat .python-version)"
50
- uv run --frozen python scripts/generate_models.py --check
51
- uv run --frozen ruff check .
52
- uv run --frozen ruff format --check .
53
- uv run --frozen basedpyright
43
+ uv sync --frozen
54
44
 
55
45
  mkdir -p dist/release dist/reproducible
56
46
  uv build --no-build-isolation --out-dir dist/release
@@ -61,24 +51,6 @@ stages:
61
51
  (cd dist/release && sha256sum *.whl *.tar.gz > SHA256SUMS)
62
52
  cat dist/release/SHA256SUMS
63
53
 
64
- sdk_consumer_dir="$(mktemp -d)"
65
- trap 'rm -rf -- "$sdk_consumer_dir"' EXIT
66
- uv venv "$sdk_consumer_dir/venv"
67
- uv pip install \
68
- --python "$sdk_consumer_dir/venv/bin/python" \
69
- dist/release/*.whl \
70
- "basedpyright>=1.40.2" \
71
- "nodejs-wheel-binaries==22.20.0"
72
- "$sdk_consumer_dir/venv/bin/python" scripts/check_installed_package.py
73
- "$sdk_consumer_dir/venv/bin/basedpyright" \
74
- --pythonpath "$sdk_consumer_dir/venv/bin/python" \
75
- --project tests/typing/pyproject.toml
76
-
77
- if [ "$build_ref" = main ]; then
78
- echo "Validation passed on main; publishing requires tag $release_tag"
79
- exit 0
80
- fi
81
- : "${UV_PUBLISH_TOKEN:?Configure UV_PUBLISH_TOKEN as a protected pipeline secret}"
82
54
  uv publish --trusted-publishing never \
83
55
  --publish-url https://upload.pypi.org/legacy/ \
84
56
  dist/release/*.whl dist/release/*.tar.gz
@@ -12,8 +12,8 @@
12
12
  4. **验证**:按变更类型执行 [delivery gate](docs/agent-workflows.md#delivery-gate),复用仍覆盖当前变更的有效结果。
13
13
  5. **交付**:复核最终 diff 和状态,报告结果、验证证据、限制及未执行项。
14
14
 
15
- 本地仅为打包配置、构建元数据、发布脚本变化或制品故障按需构建。正式可复现构建、制品审计和安装后消费由
16
- 发布 CI 执行,本地无需重复构建或保留历史 `dist/` 产物。
15
+ 发布前在本地完成测试、静态检查和安装后消费验证;发布 CI 只负责可复现构建、制品审计和 PyPI 上传。
16
+ 本地为发布前消费验证、打包配置或制品故障按需构建,使用临时目录,不保留历史 `dist/` 产物。
17
17
 
18
18
  ## 分支指针
19
19
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: matelab-python-sdk
3
- Version: 0.3.0a1
3
+ Version: 0.3.0a2
4
4
  Summary: Reusable async Python client for the Matelab Integration Contract
5
5
  Author: CMPDC, Institute of Physics, Chinese Academy of Sciences
6
6
  License-Expression: Apache-2.0
@@ -2,12 +2,12 @@
2
2
  "schema_version": 1,
3
3
  "contract_line": "integration-v1",
4
4
  "release": {
5
- "tag": "v2026.11.2",
6
- "commit": "a986f73b0edc6bb67f2993a9ee1291aba31df5e5"
5
+ "tag": "v2026.11.4",
6
+ "commit": "199f1ae307e0561bd7c4ec8ce5af22d05486e7e9"
7
7
  },
8
8
  "openapi": {
9
9
  "source_path": "openapi/matelab-integration-v1.openapi.yaml",
10
10
  "snapshot": "matelab-integration-v1.openapi.yaml",
11
- "sha256": "4a485f0ab2b589136cdcccad77407d8b5768e6e8cbb8e3a7636d8b9a07649991"
11
+ "sha256": "769629096ccdd9d4198aefd738e522afa268ec77a146cf4548fc3b1715985b49"
12
12
  }
13
13
  }
@@ -1,7 +1,7 @@
1
1
  openapi: 3.1.0
2
2
  info:
3
3
  title: Matelab Integration Contract
4
- version: "2026.11.2"
4
+ version: "2026.11.4"
5
5
  description: |
6
6
  Current PHP wire contract for generating SDKs against the selected
7
7
  `matelab-server` Provider version.
@@ -18,7 +18,7 @@ info:
18
18
  x-contract-line: integration-v1
19
19
  x-provider-evidence:
20
20
  repository: /home/tnzhu/projects/matelab-server
21
- commit: f5a714e17cd76076efe7579db279936ac29b50a6
21
+ commit: fa4172020c6a9f2955ed02a763bfce909ef63aa3
22
22
  verificationRuntime:
23
23
  baseUrl: https://matelab.iphy.ac.cn/eln-test/api
24
24
  container: matelab-test-server-1
@@ -53,6 +53,7 @@ info:
53
53
  - lib/Route.php
54
54
  - lib/HttpServer.php
55
55
  - lib/WsServer.php
56
+ - lib/Taskscheduler.php
56
57
  - start.php
57
58
  - lib/MultiException.php
58
59
  - config/Db.php
@@ -62,17 +63,16 @@ info:
62
63
  - sql/matelab.sql
63
64
  - sql/recommend.sql
64
65
  x-provider-audit:
65
- currentCommit: f5a714e17cd76076efe7579db279936ac29b50a6
66
- previousReleaseEvidenceCommit: 00f17b6ce0906bb78b0a3e9bb8c50abee90ca3d0
67
- lastProviderVerifiedCommit: f5a714e17cd76076efe7579db279936ac29b50a6
66
+ currentCommit: fa4172020c6a9f2955ed02a763bfce909ef63aa3
67
+ previousReleaseEvidenceCommit: f5a714e17cd76076efe7579db279936ac29b50a6
68
+ lastProviderVerifiedCommit: fa4172020c6a9f2955ed02a763bfce909ef63aa3
68
69
  contractStatus: current-provider-aligned
69
70
  # Summary of changes adopted by current Supported Routes since the last
70
71
  # released contract, including contract corrections. The Provider diff is
71
72
  # previousReleaseEvidenceCommit -> currentCommit. Accumulate unreleased
72
73
  # updates against that fixed release baseline; use [] if no relevant changes.
73
74
  # Entries are not per-change verification results or a cumulative history.
74
- incorporatedChanges:
75
- - {operationId: stageTemporaryFile, change: filename-independent-continuation-with-final-fragment-name-and-extensionless-abort}
75
+ incorporatedChanges: []
76
76
  x-consumer-evidence:
77
77
  - repository: /home/tnzhu/projects/matelab-mcp
78
78
  commit: 94a129b2df0ef0fbcf179c10550fb7c9a5dd2e6f
@@ -32,7 +32,7 @@
32
32
  `reportUnannotatedClassAttribute`、`reportIncompatibleUnannotatedOverride`,其他设置放在其后。沿用 SDK 的目标
33
33
  Python 版本与检查路径,不照搬其他项目的值。
34
34
  - 升级 runtime、build 或 dev 依赖时,必须将验证通过的新版本同步为 `pyproject.toml` 中对应依赖的 `>=` 下限,
35
- 同时更新对应 CI 约束(包括安装后消费检查)。`uv.lock` 必须通过 `uv lock` 等 uv 命令自动更新,不手工编辑。
35
+ 同时更新对应 CI 和本地安装后消费校验中的约束。`uv.lock` 必须通过 `uv lock` 等 uv 命令自动更新,不手工编辑。
36
36
  例外:`nodejs-wheel-binaries` 保留系统所需的精确版本,并同步 lock 和对应 CI 约束。
37
37
  - 构建后端依赖和 wheel package 显式配置;metadata 与制品检查从这些声明推导预期值。
38
38
 
@@ -91,10 +91,12 @@ Ruff/Basedpyright 诊断通过修复代码或精确 ignore 解决,不缩小检
91
91
  1. 按 [版本规则](development.md#versioning) 选择 SDK 版本,读取 `[project].version`,确认待发布版本未发布
92
92
  且 Contract pin 完整。公开接口删除、重命名、类型收紧或不兼容行为变化按 breaking change 处理。
93
93
  完成标准:版本、当前文档和 tag 名 `v{version}` 一致。
94
- 2. 提交前同步受影响的当前文档,完成 [delivery gate](#delivery-gate)。构建元数据或发布流程变化时,核对
94
+ 2. 提交前同步受影响的当前文档,在本地完成 [delivery gate](#delivery-gate)、支持版本测试与安装后消费校验。
95
+ 构建元数据或发布流程变化时,核对
95
96
  metadata 与流水线固定版本的 uv 是否兼容;需要本地制品证据时使用
96
97
  [手工构建命令](development.md#reproducible-release-build)。创建已审查、已授权的 release commit。
97
- 3. 创建指向 release commit 的 annotated `v{version}` tag,推送 `origin` 的 main/tag;tag 推送自动触发
98
- [发布 CI](../.workflow/release.yml)。
99
- 4. 跟踪发布 CI 的测试、可复现构建、制品审计、安装后消费和 PyPI publish。
100
- 完成标准:`origin` 的 main/tag 对应 release commit,CI 全部通过,PyPI 对应版本与 CI 制品哈希一致。
98
+ 3. 本地验证通过后,创建指向 release commit 的新 annotated `v{version}` tag,推送 `origin` 的 main 和新 tag;
99
+ tag 推送自动触发 Gitee [发布 CI](../.workflow/release.yml)。已发布版本不可覆盖,对应 tag 不再移动;main 可继续
100
+ 前进,无需与旧 tag 指向同一提交,后续发版使用新版本、新 tag。
101
+ 4. 跟踪新 tag 的 Gitee 可复现构建、制品审计和 PyPI 上传;CI 不重复本地测试、静态检查或消费校验。
102
+ 完成标准:本地验证通过,本次推送的 main/新 tag 对应 release commit,Gitee 发布成功,PyPI 与 CI 制品哈希一致。
@@ -5,13 +5,13 @@ See the [README](../README.md) for installation and quick start and [CONTEXT.md]
5
5
 
6
6
  ## Contract
7
7
 
8
- The SDK is pinned to the immutable `matelab-spec v2026.11.2` Contract Release. The sole pin,
8
+ The SDK is pinned to the immutable `matelab-spec v2026.11.4` Contract Release. The sole pin,
9
9
  [contracts/matelab-integration-v1.lock.json](../contracts/matelab-integration-v1.lock.json), records peeled commit
10
- `a986f73b0edc6bb67f2993a9ee1291aba31df5e5`, source `openapi/matelab-integration-v1.openapi.yaml`, the local snapshot path,
11
- and SHA-256 `4a485f0ab2b589136cdcccad77407d8b5768e6e8cbb8e3a7636d8b9a07649991`. The annotated tag object is
12
- `dc7a09dccf4187100cd05241757fc3f500107bdd`.
10
+ `199f1ae307e0561bd7c4ec8ce5af22d05486e7e9`, source `openapi/matelab-integration-v1.openapi.yaml`, the local snapshot path,
11
+ and SHA-256 `769629096ccdd9d4198aefd738e522afa268ec77a146cf4548fc3b1715985b49`. The annotated tag object is
12
+ `b1748d96763669461cfa9467d6a4cd1273f53b41`.
13
13
 
14
- The Contract uses Provider source evidence from `f5a714e17cd76076efe7579db279936ac29b50a6`; v2026.11.2 validation ran
14
+ The Contract uses Provider source evidence from `fa4172020c6a9f2955ed02a763bfce909ef63aa3`; v2026.11.4 validation ran
15
15
  against an isolated test instance and does not establish production behavior. The Front Consumer evidence
16
16
  `f7a7b952d7981f169d5c2585aea5c94b418086a3` informs cross-Consumer capability review but does not define the SDK interface.
17
17
 
@@ -17,8 +17,8 @@ according to its public impact.
17
17
 
18
18
  Use Python 3.15 for development; `.python-version` selects it for `uv sync` and `uv run`.
19
19
  The SDK supports Python 3.12 and newer. Source syntax, type checking, and generated models target Python 3.12.
20
- Release CI tests Python 3.12, 3.13, 3.14, and 3.15. Generated-model, lint, formatting, and type checks run only on
21
- Python 3.15, which also builds the distributions and checks the installed-wheel consumer.
20
+ Run tests and static checks locally before release. Generated-model, lint, formatting, and type checks use Python 3.15.
21
+ Release CI uses Python 3.15 for reproducible builds, artifact audits, and PyPI upload; it does not rerun tests.
22
22
 
23
23
  ```bash
24
24
  uv sync --frozen
@@ -35,6 +35,16 @@ Contract or generator changes regenerate private models with `uv run python scri
35
35
  `pyproject.toml` declares dependency minimums; `uv.lock` fixes the development and release environment.
36
36
  The exact Node.js wheel pin preserves compatibility with glibc 2.17 on the development host.
37
37
 
38
+ Before release, also test all supported Python versions locally, with Provider connection variables unset:
39
+
40
+ ```bash
41
+ test_status=0
42
+ for python_version in 3.12 3.13 3.14 3.15; do
43
+ uv run --frozen --exact --python "$python_version" pytest -rs || test_status=1
44
+ done
45
+ test "$test_status" -eq 0
46
+ ```
47
+
38
48
  ## Opt-in Provider consumer smoke
39
49
 
40
50
  The smoke checks authentication, complete Session persistence and restoration, refresh with identity preservation,
@@ -57,19 +67,25 @@ for target authorization and keep credentials out of Git.
57
67
 
58
68
  ## Reproducible release build
59
69
 
60
- Pushing a `v{version}` release tag to `origin` automatically triggers [CI](../.workflow/release.yml): checks, reproducible
61
- builds, artifact audits, installed-wheel validation, and PyPI publishing. Preparation follows the
70
+ After local validation, pushing a `v{version}` release tag to `origin` automatically triggers
71
+ [CI](../.workflow/release.yml): reproducible builds, artifact audits, and PyPI publishing.
72
+ The workflow accepts only the tag matching the declared version. Preparation follows the
62
73
  [release workflow](agent-workflows.md#release).
63
- A manual run of `main` performs validation without publishing.
64
74
 
65
- Local builds are only needed for packaging changes or artifact diagnostics. To reproduce CI artifacts, use the release
66
- tag's checkout and committer timestamp, the locked environment, and a temporary output directory:
75
+ For local installed-wheel validation or packaging diagnostics, use the intended release checkout and committer
76
+ timestamp, the locked environment, and a temporary output directory:
67
77
 
68
78
  ```bash
69
79
  export SOURCE_DATE_EPOCH="$(git show -s --format=%ct HEAD)"
70
80
  sdk_release_build_dir="$(mktemp -d)"
81
+ trap 'rm -rf -- "$sdk_release_build_dir"' EXIT
71
82
  uv sync --frozen
72
- uv build --no-build-isolation --out-dir "$sdk_release_build_dir"
73
- uv run python scripts/check_release.py "$sdk_release_build_dir"/*.whl "$sdk_release_build_dir"/*.tar.gz
74
- (cd "$sdk_release_build_dir" && sha256sum *.whl *.tar.gz > SHA256SUMS)
83
+ uv build --no-build-isolation --out-dir "$sdk_release_build_dir/dist"
84
+ uv run python scripts/check_release.py "$sdk_release_build_dir"/dist/*.whl "$sdk_release_build_dir"/dist/*.tar.gz
85
+ uv venv --python 3.15 "$sdk_release_build_dir/consumer"
86
+ uv pip install --python "$sdk_release_build_dir/consumer/bin/python" \
87
+ "$sdk_release_build_dir"/dist/*.whl "basedpyright>=1.40.2" "nodejs-wheel-binaries==22.20.0"
88
+ "$sdk_release_build_dir/consumer/bin/python" scripts/check_installed_package.py
89
+ "$sdk_release_build_dir/consumer/bin/basedpyright" \
90
+ --pythonpath "$sdk_release_build_dir/consumer/bin/python" --project tests/typing/pyproject.toml
75
91
  ```
@@ -3,7 +3,7 @@
3
3
  schema_version: 1
4
4
  contract:
5
5
  line: integration-v1
6
- release: v2026.11.2
6
+ release: v2026.11.4
7
7
  operation_count: 71
8
8
 
9
9
  operations:
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "matelab-python-sdk"
7
- version = "0.3.0a1"
7
+ version = "0.3.0a2"
8
8
  description = "Reusable async Python client for the Matelab Integration Contract"
9
9
  requires-python = ">=3.12"
10
10
  keywords = ["matelab", "electronic-lab-notebook", "eln", "asyncio", "sdk"]
@@ -11,7 +11,7 @@ from pydantic import ConfigDict, Field, RootModel, SecretStr, StrictBool, Strict
11
11
 
12
12
  from matelab._wire_validation import WireModel
13
13
 
14
- OPENAPI_INFO_VERSION = "2026.11.2"
14
+ OPENAPI_INFO_VERSION = "2026.11.4"
15
15
 
16
16
 
17
17
  class ResponseEnvelope(WireModel):
@@ -129,9 +129,9 @@ def test_release_dependencies_publish_minimum_versions() -> None:
129
129
  assert build == [dev["hatchling"]]
130
130
  assert project["license"] == "Apache-2.0"
131
131
  assert project["license-files"] == ["LICENSE", "NOTICE"]
132
- workflow = (_ROOT / ".workflow" / "release.yml").read_text()
133
- assert str(dev["basedpyright"]) in workflow
134
- assert str(dev["nodejs-wheel-binaries"]) in workflow
132
+ development = (_ROOT / "docs" / "development.md").read_text()
133
+ assert str(dev["basedpyright"]) in development
134
+ assert str(dev["nodejs-wheel-binaries"]) in development
135
135
 
136
136
 
137
137
  def test_built_metadata_contains_public_dependency_and_python_contract(built_wheel: Path) -> None:
@@ -412,7 +412,7 @@ wheels = [
412
412
 
413
413
  [[package]]
414
414
  name = "matelab-python-sdk"
415
- version = "0.3.0a1"
415
+ version = "0.3.0a2"
416
416
  source = { editable = "." }
417
417
  dependencies = [
418
418
  { name = "httpx2" },