binomic 0.1.0__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 (89) hide show
  1. binomic-0.1.0/.github/workflows/docs.yml +60 -0
  2. binomic-0.1.0/.github/workflows/pypub.yml +70 -0
  3. binomic-0.1.0/.github/workflows/pytest.yml +70 -0
  4. binomic-0.1.0/.github/workflows/release.yml +39 -0
  5. binomic-0.1.0/.gitignore +231 -0
  6. binomic-0.1.0/.pre-commit-config.yaml +34 -0
  7. binomic-0.1.0/.python-version +1 -0
  8. binomic-0.1.0/CHANGELOG.md +26 -0
  9. binomic-0.1.0/CONTRIBUTING.md +103 -0
  10. binomic-0.1.0/CONTRIBUTING_en.md +120 -0
  11. binomic-0.1.0/LICENSE +21 -0
  12. binomic-0.1.0/Makefile +462 -0
  13. binomic-0.1.0/PKG-INFO +179 -0
  14. binomic-0.1.0/README.md +161 -0
  15. binomic-0.1.0/README_en.md +170 -0
  16. binomic-0.1.0/docs/api.rst +50 -0
  17. binomic-0.1.0/docs/conf.py +57 -0
  18. binomic-0.1.0/docs/en/api.rst +50 -0
  19. binomic-0.1.0/docs/en/conf.py +52 -0
  20. binomic-0.1.0/docs/en/guide/architecture.md +23 -0
  21. binomic-0.1.0/docs/en/guide/litestar.md +24 -0
  22. binomic-0.1.0/docs/en/guide/quickstart.md +73 -0
  23. binomic-0.1.0/docs/en/index.md +33 -0
  24. binomic-0.1.0/docs/guide/architecture.md +20 -0
  25. binomic-0.1.0/docs/guide/litestar.md +23 -0
  26. binomic-0.1.0/docs/guide/quickstart.md +70 -0
  27. binomic-0.1.0/docs/index.md +29 -0
  28. binomic-0.1.0/pyproject.toml +277 -0
  29. binomic-0.1.0/src/binomic/__init__.py +0 -0
  30. binomic-0.1.0/src/binomic/base/__init__.py +13 -0
  31. binomic-0.1.0/src/binomic/base/constants.py +3 -0
  32. binomic-0.1.0/src/binomic/base/exceptions.py +17 -0
  33. binomic-0.1.0/src/binomic/base/schemas.py +39 -0
  34. binomic-0.1.0/src/binomic/broker/__init__.py +11 -0
  35. binomic-0.1.0/src/binomic/broker/handlers.py +33 -0
  36. binomic-0.1.0/src/binomic/broker/protocols.py +27 -0
  37. binomic-0.1.0/src/binomic/broker/redis.py +165 -0
  38. binomic-0.1.0/src/binomic/broker/types.py +21 -0
  39. binomic-0.1.0/src/binomic/client.py +114 -0
  40. binomic-0.1.0/src/binomic/config.py +16 -0
  41. binomic-0.1.0/src/binomic/message/__init__.py +3 -0
  42. binomic-0.1.0/src/binomic/message/schemas.py +54 -0
  43. binomic-0.1.0/src/binomic/plugin/__init__.py +0 -0
  44. binomic-0.1.0/src/binomic/plugin/litestar.py +100 -0
  45. binomic-0.1.0/src/binomic/py.typed +0 -0
  46. binomic-0.1.0/src/binomic/task/__init__.py +12 -0
  47. binomic-0.1.0/src/binomic/task/exceptions.py +14 -0
  48. binomic-0.1.0/src/binomic/task/registry.py +68 -0
  49. binomic-0.1.0/src/binomic/task/wrappers.py +94 -0
  50. binomic-0.1.0/src/binomic/tasks.py +9 -0
  51. binomic-0.1.0/src/binomic/worker/__init__.py +13 -0
  52. binomic-0.1.0/src/binomic/worker/master.py +114 -0
  53. binomic-0.1.0/src/binomic/worker/presence.py +65 -0
  54. binomic-0.1.0/src/binomic/worker/schemas.py +27 -0
  55. binomic-0.1.0/src/binomic/worker/worker.py +173 -0
  56. binomic-0.1.0/test_integration/__init__.py +0 -0
  57. binomic-0.1.0/test_integration/conftest.py +55 -0
  58. binomic-0.1.0/test_integration/tasks.py +19 -0
  59. binomic-0.1.0/test_integration/test_end_to_end_pipeline.py +63 -0
  60. binomic-0.1.0/test_integration/test_reclaim_pipeline.py +57 -0
  61. binomic-0.1.0/tests/__init__.py +0 -0
  62. binomic-0.1.0/tests/base/__init__.py +0 -0
  63. binomic-0.1.0/tests/base/test_constants.py +7 -0
  64. binomic-0.1.0/tests/base/test_exceptions.py +24 -0
  65. binomic-0.1.0/tests/base/test_schemas.py +48 -0
  66. binomic-0.1.0/tests/broker/__init__.py +0 -0
  67. binomic-0.1.0/tests/broker/conftest.py +19 -0
  68. binomic-0.1.0/tests/broker/test_handlers.py +29 -0
  69. binomic-0.1.0/tests/broker/test_protocols.py +14 -0
  70. binomic-0.1.0/tests/broker/test_redis.py +208 -0
  71. binomic-0.1.0/tests/broker/test_types.py +23 -0
  72. binomic-0.1.0/tests/conftest.py +89 -0
  73. binomic-0.1.0/tests/message/__init__.py +0 -0
  74. binomic-0.1.0/tests/message/test_schemas.py +71 -0
  75. binomic-0.1.0/tests/task/__init__.py +0 -0
  76. binomic-0.1.0/tests/task/conftest.py +23 -0
  77. binomic-0.1.0/tests/task/test_exceptions.py +12 -0
  78. binomic-0.1.0/tests/task/test_registry.py +86 -0
  79. binomic-0.1.0/tests/task/test_wrappers.py +155 -0
  80. binomic-0.1.0/tests/tasks.py +12 -0
  81. binomic-0.1.0/tests/test_client.py +86 -0
  82. binomic-0.1.0/tests/test_config.py +23 -0
  83. binomic-0.1.0/tests/worker/__init__.py +0 -0
  84. binomic-0.1.0/tests/worker/conftest.py +37 -0
  85. binomic-0.1.0/tests/worker/test_master.py +78 -0
  86. binomic-0.1.0/tests/worker/test_presence.py +81 -0
  87. binomic-0.1.0/tests/worker/test_schemas.py +34 -0
  88. binomic-0.1.0/tests/worker/test_worker.py +214 -0
  89. binomic-0.1.0/uv.lock +2202 -0
@@ -0,0 +1,60 @@
1
+ name: Docs
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths:
7
+ - 'docs/**'
8
+ - 'src/**'
9
+ - 'pyproject.toml'
10
+ - 'uv.lock'
11
+ - 'Makefile'
12
+ - '.github/workflows/docs.yml'
13
+ workflow_dispatch:
14
+
15
+ permissions:
16
+ contents: read
17
+ pages: write
18
+ id-token: write
19
+
20
+ concurrency:
21
+ group: ${{ github.workflow }}-${{ github.ref }}
22
+ cancel-in-progress: false
23
+
24
+ jobs:
25
+ build:
26
+ runs-on: ubuntu-latest
27
+
28
+ steps:
29
+ - uses: actions/checkout@v4
30
+
31
+ - name: Install uv
32
+ uses: astral-sh/setup-uv@v6
33
+ with:
34
+ python-version: "3.12"
35
+
36
+ - name: Sync dependencies
37
+ run: uv sync --no-default-groups --group docs
38
+
39
+ - name: Build documentation
40
+ run: make docs-build
41
+ env:
42
+ DOCS_ROOT_URL: https://ahsen17.github.io/binomic
43
+
44
+ - name: Upload Pages artifact
45
+ uses: actions/upload-pages-artifact@v3
46
+ with:
47
+ path: docs/_build/html
48
+
49
+ deploy:
50
+ needs: build
51
+ runs-on: ubuntu-latest
52
+
53
+ environment:
54
+ name: github-pages
55
+ url: ${{ steps.deployment.outputs.page_url }}
56
+
57
+ steps:
58
+ - name: Deploy to GitHub Pages
59
+ id: deployment
60
+ uses: actions/deploy-pages@v4
@@ -0,0 +1,70 @@
1
+ # This workflow will upload a Python Package to PyPI when a release is created
2
+ # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
3
+
4
+ # This workflow uses actions that are not certified by GitHub.
5
+ # They are provided by a third-party and are governed by
6
+ # separate terms of service, privacy policy, and support
7
+ # documentation.
8
+
9
+ name: Upload Python Package
10
+
11
+ on:
12
+ release:
13
+ types: [published]
14
+
15
+ permissions:
16
+ contents: read
17
+
18
+ jobs:
19
+ release-build:
20
+ runs-on: ubuntu-latest
21
+
22
+ steps:
23
+ - uses: actions/checkout@v4
24
+
25
+ - uses: actions/setup-python@v5
26
+ with:
27
+ python-version: "3.x"
28
+
29
+ - name: Build release distributions
30
+ run: |
31
+ # NOTE: put your own distribution build steps here.
32
+ python -m pip install build
33
+ python -m build
34
+
35
+ - name: Upload distributions
36
+ uses: actions/upload-artifact@v4
37
+ with:
38
+ name: release-dists
39
+ path: dist/
40
+
41
+ pypi-publish:
42
+ runs-on: ubuntu-latest
43
+ needs:
44
+ - release-build
45
+ permissions:
46
+ # IMPORTANT: this permission is mandatory for trusted publishing
47
+ id-token: write
48
+
49
+ # Dedicated environments with protections for publishing are strongly recommended.
50
+ # For more information, see: https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment#deployment-protection-rules
51
+ environment:
52
+ name: pypi
53
+ # OPTIONAL: uncomment and update to include your PyPI project URL in the deployment status:
54
+ # url: https://pypi.org/p/YOURPROJECT
55
+ #
56
+ # ALTERNATIVE: if your GitHub Release name is the PyPI project version string
57
+ # ALTERNATIVE: exactly, uncomment the following line instead:
58
+ # url: https://pypi.org/project/YOURPROJECT/${{ github.event.release.name }}
59
+
60
+ steps:
61
+ - name: Retrieve release distributions
62
+ uses: actions/download-artifact@v4
63
+ with:
64
+ name: release-dists
65
+ path: dist/
66
+
67
+ - name: Publish release distributions to PyPI
68
+ uses: pypa/gh-action-pypi-publish@release/v1
69
+ with:
70
+ packages-dir: dist/
@@ -0,0 +1,70 @@
1
+ name: Tests
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ changes:
10
+ runs-on: ubuntu-latest
11
+ outputs:
12
+ code: ${{ steps.filter.outputs.code }}
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Detect code changes
17
+ uses: dorny/paths-filter@v3
18
+ id: filter
19
+ with:
20
+ filters: |
21
+ code:
22
+ - 'src/**'
23
+ - 'tests/**'
24
+ - 'test_integration/**'
25
+ - 'pyproject.toml'
26
+ - 'uv.lock'
27
+ - 'Makefile'
28
+ - '.pre-commit-config.yaml'
29
+ - '.github/workflows/pytest.yml'
30
+
31
+ test:
32
+ needs: changes
33
+ if: needs.changes.outputs.code == 'true'
34
+ runs-on: ubuntu-latest
35
+
36
+ services:
37
+ redis:
38
+ image: redis:7.4-alpine
39
+ ports:
40
+ - 6379:6379
41
+ options: >-
42
+ --health-cmd "redis-cli ping"
43
+ --health-interval 10s
44
+ --health-timeout 5s
45
+ --health-retries 5
46
+
47
+ steps:
48
+ - uses: actions/checkout@v4
49
+
50
+ - name: Install uv
51
+ uses: astral-sh/setup-uv@v6
52
+ with:
53
+ python-version: "3.12"
54
+
55
+ - name: Sync dependencies
56
+ run: uv sync --dev
57
+
58
+ - name: Lint
59
+ run: |
60
+ uv run ruff check src tests test_integration
61
+ uv run ruff format --check src tests test_integration
62
+
63
+ - name: Type check
64
+ run: uv run mypy
65
+
66
+ - name: Unit tests
67
+ run: uv run pytest tests --cov -n auto
68
+
69
+ - name: Integration tests
70
+ run: uv run pytest test_integration -m integration
@@ -0,0 +1,39 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ permissions:
9
+ contents: write
10
+
11
+ jobs:
12
+ draft-release:
13
+ runs-on: ubuntu-latest
14
+
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ with:
18
+ fetch-depth: 0
19
+
20
+ - name: Install uv
21
+ uses: astral-sh/setup-uv@v6
22
+ with:
23
+ python-version: "3.12"
24
+
25
+ - name: Sync dependencies
26
+ run: uv sync --dev
27
+
28
+ - name: Build distributions
29
+ run: uv build
30
+
31
+ - name: Generate release notes
32
+ run: uv run git-cliff --latest --strip header > RELEASE_NOTES.md
33
+
34
+ - name: Create draft release
35
+ uses: softprops/action-gh-release@v2
36
+ with:
37
+ draft: true
38
+ body_path: RELEASE_NOTES.md
39
+ files: dist/*
@@ -0,0 +1,231 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[codz]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Configuration files
10
+ # *.ini
11
+ *.env
12
+ config.yaml
13
+ config.yml
14
+ config.toml
15
+ config.json
16
+ settings.*.json
17
+
18
+ # Temp files
19
+ *.log
20
+ tmp/
21
+ .runtime/
22
+
23
+ # Ai coding
24
+ .codex/
25
+ .agents/
26
+ .claude/
27
+ .cursor/
28
+ CLAUDE.md
29
+ AGENTS.md
30
+
31
+ # Distribution / packaging
32
+ .Python
33
+ build/
34
+ develop-eggs/
35
+ dist/
36
+ downloads/
37
+ eggs/
38
+ .eggs/
39
+ lib64/
40
+ parts/
41
+ sdist/
42
+ var/
43
+ wheels/
44
+ share/python-wheels/
45
+ *.egg-info/
46
+ .installed.cfg
47
+ *.egg
48
+ MANIFEST
49
+
50
+ # PyInstaller
51
+ # Usually these files are written by a python script from a template
52
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
53
+ *.manifest
54
+ *.spec
55
+
56
+ # Installer logs
57
+ pip-log.txt
58
+ pip-delete-this-directory.txt
59
+
60
+ # Unit test / coverage reports
61
+ htmlcov/
62
+ .tox/
63
+ .nox/
64
+ .coverage
65
+ .coverage.*
66
+ .cache
67
+ nosetests.xml
68
+ coverage.xml
69
+ *.cover
70
+ *.py.cover
71
+ .hypothesis/
72
+ .pytest_cache/
73
+ cover/
74
+
75
+ # Translations
76
+ *.mo
77
+ *.pot
78
+
79
+ # Django stuff:
80
+ *.log
81
+ local_settings.py
82
+ db.sqlite3
83
+ db.sqlite3-journal
84
+
85
+ # Flask stuff:
86
+ instance/
87
+ .webassets-cache
88
+
89
+ # Scrapy stuff:
90
+ .scrapy
91
+
92
+ # Sphinx documentation
93
+ docs/_build/
94
+
95
+ # PyBuilder
96
+ .pybuilder/
97
+ target/
98
+
99
+ # Jupyter Notebook
100
+ .ipynb_checkpoints
101
+
102
+ # VS Code settings
103
+ .vscode/
104
+
105
+ # IPython
106
+ profile_default/
107
+ ipython_config.py
108
+
109
+ # pyenv
110
+ # For a library or package, you might want to ignore these files since the code is
111
+ # intended to run in multiple environments; otherwise, check them in:
112
+ # .python-version
113
+
114
+ # pipenv
115
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
116
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
117
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
118
+ # install all needed dependencies.
119
+ #Pipfile.lock
120
+
121
+ # UV
122
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
123
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
124
+ # commonly ignored for libraries.
125
+ #uv.lock
126
+
127
+ # poetry
128
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
129
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
130
+ # commonly ignored for libraries.
131
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
132
+ #poetry.lock
133
+ #poetry.toml
134
+
135
+ # pdm
136
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
137
+ # pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
138
+ # https://pdm-project.org/en/latest/usage/project/#working-with-version-control
139
+ #pdm.lock
140
+ #pdm.toml
141
+ .pdm-python
142
+ .pdm-build/
143
+
144
+ # pixi
145
+ # Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
146
+ #pixi.lock
147
+ # Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
148
+ # in the .venv directory. It is recommended not to include this directory in version control.
149
+ .pixi
150
+
151
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
152
+ __pypackages__/
153
+
154
+ # Celery stuff
155
+ celerybeat-schedule
156
+ celerybeat.pid
157
+
158
+ # SageMath parsed files
159
+ *.sage.py
160
+
161
+ # Environments
162
+ .env
163
+ .envrc
164
+ .venv
165
+ env/
166
+ venv/
167
+ ENV/
168
+ env.bak/
169
+ venv.bak/
170
+
171
+ # Spyder project settings
172
+ .spyderproject
173
+ .spyproject
174
+
175
+ # Rope project settings
176
+ .ropeproject
177
+
178
+ # mkdocs documentation
179
+ /site
180
+
181
+ # mypy
182
+ .mypy_cache/
183
+ .dmypy.json
184
+ dmypy.json
185
+
186
+ # Pyre type checker
187
+ .pyre/
188
+
189
+ # pytype static type analyzer
190
+ .pytype/
191
+
192
+ # Cython debug symbols
193
+ cython_debug/
194
+
195
+ # PyCharm
196
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
197
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
198
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
199
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
200
+ #.idea/
201
+
202
+ # Abstra
203
+ # Abstra is an AI-powered process automation framework.
204
+ # Ignore directories containing user credentials, local state, and settings.
205
+ # Learn more at https://abstra.io/docs
206
+ .abstra/
207
+
208
+ # Visual Studio Code
209
+ # Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
210
+ # that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
211
+ # and can be added to the global gitignore or merged into this file. However, if you prefer,
212
+ # you could uncomment the following to ignore the entire vscode folder
213
+ # .vscode/
214
+
215
+ # Ruff stuff:
216
+ .ruff_cache/
217
+
218
+ # PyPI configuration file
219
+ .pypirc
220
+
221
+ # Cursor
222
+ # Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
223
+ # exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
224
+ # refer to https://docs.cursor.com/context/ignore-files
225
+ .cursorignore
226
+ .cursorindexingignore
227
+
228
+ # Marimo
229
+ marimo/_static/
230
+ marimo/_lsp/
231
+ __marimo__/
@@ -0,0 +1,34 @@
1
+ default_language_version:
2
+ python: "3"
3
+ repos:
4
+ - repo: https://github.com/compilerla/conventional-pre-commit
5
+ rev: v4.2.0
6
+ hooks:
7
+ - id: conventional-pre-commit
8
+ stages: [commit-msg]
9
+ - repo: https://github.com/pre-commit/pre-commit-hooks
10
+ rev: v5.0.0
11
+ hooks:
12
+ - id: check-ast
13
+ - id: check-case-conflict
14
+ - id: check-toml
15
+ - id: end-of-file-fixer
16
+ - id: mixed-line-ending
17
+ - id: trailing-whitespace
18
+ - repo: https://github.com/provinzkraut/unasyncd
19
+ rev: "v0.8.1"
20
+ hooks:
21
+ - id: unasyncd
22
+ additional_dependencies: ["ruff"]
23
+ - repo: https://github.com/astral-sh/ruff-pre-commit
24
+ rev: "v0.12.5"
25
+ hooks:
26
+ - id: ruff
27
+ args: ["--fix"]
28
+ types_or: [python, pyi]
29
+ - id: ruff-format
30
+ types_or: [python, pyi]
31
+ - repo: https://github.com/sphinx-contrib/sphinx-lint
32
+ rev: "v1.0.0"
33
+ hooks:
34
+ - id: sphinx-lint
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,26 @@
1
+ ## [unreleased]
2
+
3
+ ### 🚀 Features
4
+
5
+ - Base constructions
6
+ - Task module impl
7
+ - Broker protocol with redis impl
8
+ - Binomic worker
9
+ - Worker heartbeat tick append timestamp
10
+ - Binomic worker and master impl
11
+ - Binomic client
12
+ - Remove unused dependencies
13
+ - Example tasks
14
+ - Broker protocol and redis broker impl
15
+ - Binomic plugin for litestar
16
+ - Binomic client with factory and config
17
+
18
+ ### 🐛 Bug Fixes
19
+
20
+ - Mypy check error
21
+ - Makefile test integration command
22
+
23
+ ### 🚜 Refactor
24
+
25
+ - Task decorator rebuild
26
+ - Binomic worker rebuild
@@ -0,0 +1,103 @@
1
+ # 贡献指南
2
+
3
+ [中文] **·** [English](CONTRIBUTING_en.md)
4
+
5
+ 感谢关注 Binomic!本文档说明如何参与贡献。
6
+
7
+ ## AI 协助政策
8
+
9
+ **本项目接受 AI 协助开发的代码。** 但请注意:
10
+
11
+ - 你(提交者)必须**认真审查**提交的每一行代码,无论它由你本人还是 AI 协助编写;
12
+ - AI 协助的代码与本人编写的代码**承担同等责任**——正确性、安全性、许可证合规
13
+ 均由提交者负责;
14
+ - 提交即视为你完全理解并认可该变更,"这是 AI 写的"不构成缺陷的免责理由。
15
+
16
+ ## 开发环境
17
+
18
+ 本项目使用 [uv](https://docs.astral.sh/uv/) 管理依赖,要求 Python ≥ 3.12。
19
+
20
+ ```bash
21
+ git clone git@github.com:Ahsen17/binomic.git
22
+ cd binomic
23
+ make install # 创建虚拟环境并安装依赖
24
+ make check # lint + 类型检查 + 全部测试
25
+ ```
26
+
27
+ 常用命令:
28
+
29
+ | 命令 | 作用 |
30
+ |-|-|
31
+ | `make fix` | ruff 自动修复与格式化 |
32
+ | `make lint` | pre-commit + mypy(strict) |
33
+ | `make test` | 单元测试 |
34
+ | `make test-integration` | 集成测试(需要本地 Redis) |
35
+ | `make coverage` | 覆盖率报告(`fail_under = 80`) |
36
+
37
+ ## 贡献流程
38
+
39
+ 1. 在 [Issues](https://github.com/Ahsen17/binomic/issues) 中认领或提出问题;
40
+ 2. Fork 仓库并从 `main` 创建特性分支,如 `feat/broker-metrics`;
41
+ 3. 开发并补充测试(见下方"测试要求");
42
+ 4. 确保本地 `make check` 通过;
43
+ 5. 提交 Pull Request 到 `main`,CI(`pytest.yml`)必须全绿。
44
+
45
+ ## 提交规范
46
+
47
+ 提交信息遵循
48
+ [Conventional Commits](https://www.conventionalcommits.org/zh-hans/):
49
+
50
+ ```
51
+ <类型>(<范围>?): <描述>
52
+
53
+ <正文?>
54
+
55
+ <脚注?>
56
+ ```
57
+
58
+ 常用类型:`feat`、`fix`、`refactor`、`doc`、`perf`、`style`、`test`、`build`、
59
+ `chore`。CHANGELOG.md 由 [git-cliff](https://git-cliff.org) 依据提交历史自动
60
+ 生成,**原则上禁止手动编辑**。
61
+
62
+ ## 测试要求
63
+
64
+ - 测试目录镜像源码结构:`src/binomic/base/schemas.py` → `tests/base/test_schemas.py`;
65
+ - 通用 fixture 位于 `tests/conftest.py`,子模块 fixture 位于对应子模块的
66
+ `conftest.py`;
67
+ - 用例统一组织为 `class TestXX`;
68
+ - 外部依赖策略:单测使用 fakexx(如 fakeredis);无 fakexx 包的依赖用 async
69
+ mock;集成测试(`test_integration/`)使用真实服务;
70
+ - 新增功能必须附带测试,覆盖率不得低于 80%。
71
+
72
+ ## 发布流程(维护者)
73
+
74
+ ### 版本号命名规则
75
+
76
+ 遵循 [SemVer 2.0.0](https://semver.org/lang/zh-Hans/),tag 一律带 `v` 前缀:
77
+
78
+ - **正式版本**:`x.y.z`,如 `v1.2.0`;
79
+ - **非正式版本(beta)**:`x.y.z-beta.N`,如 `v1.2.0-beta.1`;`N` 从 1 开始,
80
+ 在同一 `x.y.z` 序列内顺延(`v1.2.0-beta.1`、`v1.2.0-beta.2`、…)。
81
+
82
+ 同一 `x.y.z` 可先发布若干 beta 验证,最终发布正式的 `x.y.z`。`release.yml`
83
+ 的 `v*` 通配对两类版本同样生效;是否标记为 pre-release 由人工在 draft 上调整。
84
+
85
+ ### 发布时序
86
+
87
+ 发布链路:tag → draft release → 人工确认 → PyPI。完整时序:
88
+
89
+ 1. 在 pyproject 中更新 `version`,提交
90
+ `chore(release): prepare for vX.Y.Z` 并合入 `main`
91
+ (git-cliff 会跳过该提交,不进 CHANGELOG);
92
+ 2. 在 main 上打 tag 并推送:`git tag vX.Y.Z && git push origin vX.Y.Z`;
93
+ 3. `release.yml` 自动创建 **draft** release,附带该版本
94
+ notes(git-cliff 生成)与 sdist/wheel 产物;
95
+ 4. 在本地运行 `make changelog` 再生成 CHANGELOG.md(须在 tag 存在之后运行,
96
+ 新版本段落才会出现),以 `doc: update changelog for vX.Y.Z` 提交合入;
97
+ 5. 在 GitHub Releases 页面人工调整 draft:标记 pre-release 或正式,
98
+ 确认后点击 Publish;
99
+ 6. 发布动作触发 `pypub.yml`,自动构建并上传 PyPI(trusted publishing)。
100
+
101
+ ## 行为准则
102
+
103
+ 保持尊重与专业。对事不对人,欢迎新人提问。