nnrp-py 1.0.0rc2__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.
- nnrp_py-1.0.0rc2/.editorconfig +14 -0
- nnrp_py-1.0.0rc2/.github/PULL_REQUEST_TEMPLATE/bugfix.md +38 -0
- nnrp_py-1.0.0rc2/.github/PULL_REQUEST_TEMPLATE/docs.md +28 -0
- nnrp_py-1.0.0rc2/.github/PULL_REQUEST_TEMPLATE/feature.md +35 -0
- nnrp_py-1.0.0rc2/.github/PULL_REQUEST_TEMPLATE/maintenance.md +36 -0
- nnrp_py-1.0.0rc2/.github/PULL_REQUEST_TEMPLATE/release.md +44 -0
- nnrp_py-1.0.0rc2/.github/pull_request_template.md +41 -0
- nnrp_py-1.0.0rc2/.github/workflows/ci.yml +104 -0
- nnrp_py-1.0.0rc2/.github/workflows/release.yml +139 -0
- nnrp_py-1.0.0rc2/.gitignore +30 -0
- nnrp_py-1.0.0rc2/CONTRIBUTING.md +108 -0
- nnrp_py-1.0.0rc2/LICENSE +160 -0
- nnrp_py-1.0.0rc2/PKG-INFO +473 -0
- nnrp_py-1.0.0rc2/README.md +284 -0
- nnrp_py-1.0.0rc2/doc/todo/v1-preview1/implementation-todo.md +170 -0
- nnrp_py-1.0.0rc2/doc/todo/v1-preview2/implementation-todo.md +232 -0
- nnrp_py-1.0.0rc2/doc/todo/v1-preview3/01-foundation-and-contract.md +21 -0
- nnrp_py-1.0.0rc2/doc/todo/v1-preview3/02-connection-session-flow-control.md +20 -0
- nnrp_py-1.0.0rc2/doc/todo/v1-preview3/02a-connection-session-lifecycle.md +7 -0
- nnrp_py-1.0.0rc2/doc/todo/v1-preview3/02b-scheduling-credits-and-diagnostics.md +6 -0
- nnrp_py-1.0.0rc2/doc/todo/v1-preview3/02c-control-events-and-recovery.md +6 -0
- nnrp_py-1.0.0rc2/doc/todo/v1-preview3/03-cache-schema-profile-registry.md +19 -0
- nnrp_py-1.0.0rc2/doc/todo/v1-preview3/04-implementation-surface.md +20 -0
- nnrp_py-1.0.0rc2/doc/todo/v1-preview3/04a-rust-binding-adoption.md +5 -0
- nnrp_py-1.0.0rc2/doc/todo/v1-preview3/04b-python-host-api-surface.md +6 -0
- nnrp_py-1.0.0rc2/doc/todo/v1-preview3/04c-async-runtime-integration.md +5 -0
- nnrp_py-1.0.0rc2/doc/todo/v1-preview3/05-validation-and-docs.md +17 -0
- nnrp_py-1.0.0rc2/doc/todo/v1-preview3/implementation-todo.md +37 -0
- nnrp_py-1.0.0rc2/pyproject.toml +66 -0
- nnrp_py-1.0.0rc2/scripts/check_incremental_coverage.py +170 -0
- nnrp_py-1.0.0rc2/scripts/resolve_version.py +110 -0
- nnrp_py-1.0.0rc2/src/nnrp/__init__.py +152 -0
- nnrp_py-1.0.0rc2/src/nnrp/adapters/__init__.py +57 -0
- nnrp_py-1.0.0rc2/src/nnrp/adapters/quic.py +424 -0
- nnrp_py-1.0.0rc2/src/nnrp/adapters/tcp.py +412 -0
- nnrp_py-1.0.0rc2/src/nnrp/client/__init__.py +63 -0
- nnrp_py-1.0.0rc2/src/nnrp/client/profile.py +71 -0
- nnrp_py-1.0.0rc2/src/nnrp/client/transport.py +1654 -0
- nnrp_py-1.0.0rc2/src/nnrp/core/__init__.py +403 -0
- nnrp_py-1.0.0rc2/src/nnrp/core/enums.py +63 -0
- nnrp_py-1.0.0rc2/src/nnrp/core/header.py +97 -0
- nnrp_py-1.0.0rc2/src/nnrp/core/messages/__init__.py +238 -0
- nnrp_py-1.0.0rc2/src/nnrp/core/messages/control.py +1479 -0
- nnrp_py-1.0.0rc2/src/nnrp/core/messages/data.py +779 -0
- nnrp_py-1.0.0rc2/src/nnrp/core/packet.py +2663 -0
- nnrp_py-1.0.0rc2/src/nnrp/enums.py +11 -0
- nnrp_py-1.0.0rc2/src/nnrp/header.py +5 -0
- nnrp_py-1.0.0rc2/src/nnrp/server/__init__.py +17 -0
- nnrp_py-1.0.0rc2/src/nnrp/server/profile.py +11 -0
- nnrp_py-1.0.0rc2/src/nnrp/server/transport.py +509 -0
- nnrp_py-1.0.0rc2/src/nnrp/tools/__init__.py +107 -0
- nnrp_py-1.0.0rc2/src/nnrp/tools/golden_vectors.py +437 -0
- nnrp_py-1.0.0rc2/src/nnrp/tools/ordered_buffer.py +178 -0
- nnrp_py-1.0.0rc2/src/nnrp/tools/replay.py +1146 -0
- nnrp_py-1.0.0rc2/src/nnrp/tools/smoke.py +1056 -0
- nnrp_py-1.0.0rc2/tests/test_check_incremental_coverage.py +273 -0
- nnrp_py-1.0.0rc2/tests/test_control_messages.py +819 -0
- nnrp_py-1.0.0rc2/tests/test_data_messages.py +388 -0
- nnrp_py-1.0.0rc2/tests/test_golden_vectors.py +376 -0
- nnrp_py-1.0.0rc2/tests/test_header.py +148 -0
- nnrp_py-1.0.0rc2/tests/test_ordered_buffer.py +163 -0
- nnrp_py-1.0.0rc2/tests/test_packet.py +664 -0
- nnrp_py-1.0.0rc2/tests/test_profiles_and_exports.py +591 -0
- nnrp_py-1.0.0rc2/tests/test_quic_adapter.py +608 -0
- nnrp_py-1.0.0rc2/tests/test_release_version.py +183 -0
- nnrp_py-1.0.0rc2/tests/test_replay_tools.py +518 -0
- nnrp_py-1.0.0rc2/tests/test_server_transport.py +225 -0
- nnrp_py-1.0.0rc2/tests/test_smoke_tools.py +2302 -0
- nnrp_py-1.0.0rc2/tests/test_tcp_adapter.py +331 -0
- nnrp_py-1.0.0rc2/uv.lock +556 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
## Bug
|
|
2
|
+
|
|
3
|
+
- What was broken?
|
|
4
|
+
- How could the issue be reproduced?
|
|
5
|
+
|
|
6
|
+
## Root Cause
|
|
7
|
+
|
|
8
|
+
- What actually caused the issue?
|
|
9
|
+
|
|
10
|
+
## Fix
|
|
11
|
+
|
|
12
|
+
- What changed to fix it?
|
|
13
|
+
- What regression risk remains?
|
|
14
|
+
|
|
15
|
+
## Validation
|
|
16
|
+
|
|
17
|
+
- [ ] `ruff check .`
|
|
18
|
+
- [ ] `pytest -q`
|
|
19
|
+
- [ ] Regression test added or existing failure reproduced
|
|
20
|
+
|
|
21
|
+
Commands or workflow runs used:
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Release Impact
|
|
28
|
+
|
|
29
|
+
- [ ] No package output change
|
|
30
|
+
- [ ] Wheel or sdist contents changed
|
|
31
|
+
- [ ] Release workflow behavior changed
|
|
32
|
+
|
|
33
|
+
## Checklist
|
|
34
|
+
|
|
35
|
+
- [ ] Branch name matches repository conventions
|
|
36
|
+
- [ ] Commit messages follow Conventional Commits
|
|
37
|
+
- [ ] PR is squashed to one commit unless this is necessary `release/<version>` branch work
|
|
38
|
+
- [ ] User-facing behavior changes are documented
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
- What documentation changed?
|
|
4
|
+
- Who is the primary audience?
|
|
5
|
+
|
|
6
|
+
## Scope
|
|
7
|
+
|
|
8
|
+
- Files or sections updated:
|
|
9
|
+
- Any intentionally deferred follow-up:
|
|
10
|
+
|
|
11
|
+
## Validation
|
|
12
|
+
|
|
13
|
+
- [ ] Links and paths were checked
|
|
14
|
+
- [ ] Examples or commands were updated if needed
|
|
15
|
+
- [ ] Documentation stays consistent with current package and workflow behavior
|
|
16
|
+
|
|
17
|
+
Notes:
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Checklist
|
|
24
|
+
|
|
25
|
+
- [ ] Branch name matches repository conventions
|
|
26
|
+
- [ ] Commit messages follow Conventional Commits
|
|
27
|
+
- [ ] PR is squashed to one commit unless this is necessary `release/<version>` branch work
|
|
28
|
+
- [ ] No hidden product or workflow behavior changes were introduced
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
- What capability does this PR add?
|
|
4
|
+
- Why is it needed now?
|
|
5
|
+
|
|
6
|
+
## Implementation
|
|
7
|
+
|
|
8
|
+
- Main modules or flows changed:
|
|
9
|
+
- Any protocol, runtime, or packaging assumptions introduced:
|
|
10
|
+
- Follow-up work, if any:
|
|
11
|
+
|
|
12
|
+
## Validation
|
|
13
|
+
|
|
14
|
+
- [ ] `ruff check .`
|
|
15
|
+
- [ ] `pytest -q`
|
|
16
|
+
- [ ] Build or packaging checked if distribution output changed
|
|
17
|
+
|
|
18
|
+
Commands or workflow runs used:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Release Impact
|
|
25
|
+
|
|
26
|
+
- [ ] No package output change
|
|
27
|
+
- [ ] Wheel or sdist contents changed
|
|
28
|
+
- [ ] Release workflow behavior changed
|
|
29
|
+
|
|
30
|
+
## Checklist
|
|
31
|
+
|
|
32
|
+
- [ ] Branch name matches repository conventions
|
|
33
|
+
- [ ] Commit messages follow Conventional Commits
|
|
34
|
+
- [ ] PR is squashed to one commit unless this is necessary `release/<version>` branch work
|
|
35
|
+
- [ ] Documentation was updated when behavior changed
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
- What maintenance change is included?
|
|
4
|
+
- Why is it being made now?
|
|
5
|
+
|
|
6
|
+
## Change Type
|
|
7
|
+
|
|
8
|
+
- [ ] CI or workflow change
|
|
9
|
+
- [ ] Tooling or dependency maintenance
|
|
10
|
+
- [ ] Packaging metadata update
|
|
11
|
+
- [ ] Refactor with no intended behavior change
|
|
12
|
+
|
|
13
|
+
## Validation
|
|
14
|
+
|
|
15
|
+
- [ ] `ruff check .`
|
|
16
|
+
- [ ] `pytest -q`
|
|
17
|
+
- [ ] Targeted validation for the affected tooling or workflow path
|
|
18
|
+
|
|
19
|
+
Commands or workflow runs used:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Release Impact
|
|
26
|
+
|
|
27
|
+
- [ ] No package output change
|
|
28
|
+
- [ ] Wheel or sdist contents changed
|
|
29
|
+
- [ ] Release workflow behavior changed
|
|
30
|
+
|
|
31
|
+
## Checklist
|
|
32
|
+
|
|
33
|
+
- [ ] Branch name matches repository conventions
|
|
34
|
+
- [ ] Commit messages follow Conventional Commits
|
|
35
|
+
- [ ] PR is squashed to one commit unless this is necessary `release/<version>` branch work
|
|
36
|
+
- [ ] Follow-up operational work is documented if needed
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
- What release or release-preparation change is included?
|
|
4
|
+
|
|
5
|
+
## Versioning
|
|
6
|
+
|
|
7
|
+
- Target version:
|
|
8
|
+
- Why this version is needed:
|
|
9
|
+
|
|
10
|
+
## Package Impact
|
|
11
|
+
|
|
12
|
+
- [ ] Wheel metadata changed
|
|
13
|
+
- [ ] Sdist contents changed
|
|
14
|
+
- [ ] Release workflow behavior changed
|
|
15
|
+
|
|
16
|
+
Describe the release-facing impact:
|
|
17
|
+
|
|
18
|
+
## Validation
|
|
19
|
+
|
|
20
|
+
- [ ] `ruff check .`
|
|
21
|
+
- [ ] `pytest -q`
|
|
22
|
+
- [ ] `python -m build`
|
|
23
|
+
- [ ] Release workflow assumptions were checked
|
|
24
|
+
|
|
25
|
+
Commands or workflow runs used:
|
|
26
|
+
|
|
27
|
+
```text
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Manual Registry Steps
|
|
32
|
+
|
|
33
|
+
- [ ] No manual registry work required
|
|
34
|
+
- [ ] PyPI or TestPyPI state was reviewed
|
|
35
|
+
- [ ] GitHub Release asset expectations were reviewed
|
|
36
|
+
|
|
37
|
+
Notes:
|
|
38
|
+
|
|
39
|
+
## Checklist
|
|
40
|
+
|
|
41
|
+
- [ ] Branch name matches repository conventions
|
|
42
|
+
- [ ] Commit messages follow Conventional Commits
|
|
43
|
+
- [ ] PR is squashed to one commit unless this is necessary `release/<version>` branch work
|
|
44
|
+
- [ ] Release notes or docs were updated if needed
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
- PR type: feature / bugfix / docs / maintenance / release
|
|
4
|
+
- What changed?
|
|
5
|
+
- Why is it needed now?
|
|
6
|
+
|
|
7
|
+
## Implementation
|
|
8
|
+
|
|
9
|
+
- Main modules or flows changed:
|
|
10
|
+
- Any protocol, runtime, or packaging assumptions introduced:
|
|
11
|
+
- Follow-up work, if any:
|
|
12
|
+
|
|
13
|
+
## Validation
|
|
14
|
+
|
|
15
|
+
- [ ] `ruff check .`
|
|
16
|
+
- [ ] `pytest -q`
|
|
17
|
+
- [ ] Build or packaging checked if distribution output changed
|
|
18
|
+
|
|
19
|
+
Commands or workflow runs used:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Release Impact
|
|
26
|
+
|
|
27
|
+
- [ ] No package output change
|
|
28
|
+
- [ ] Wheel or sdist contents changed
|
|
29
|
+
- [ ] Release workflow behavior changed
|
|
30
|
+
|
|
31
|
+
## Checklist
|
|
32
|
+
|
|
33
|
+
- [ ] Branch name matches repository conventions
|
|
34
|
+
- [ ] Commit messages follow Conventional Commits
|
|
35
|
+
- [ ] PR is squashed to one commit unless this is necessary `release/<version>` branch work
|
|
36
|
+
- [ ] Documentation was updated when behavior changed
|
|
37
|
+
|
|
38
|
+
## Notes
|
|
39
|
+
|
|
40
|
+
- Specialized reference templates still live in `.github/PULL_REQUEST_TEMPLATE/`.
|
|
41
|
+
- GitHub does not show an automatic chooser for those files on the standard PR page, so this file acts as the default template.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
pull_request:
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
commit-policy:
|
|
10
|
+
if: github.event_name == 'pull_request'
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
|
|
13
|
+
steps:
|
|
14
|
+
- name: Enforce single-commit PR policy
|
|
15
|
+
shell: bash
|
|
16
|
+
run: |
|
|
17
|
+
set -euo pipefail
|
|
18
|
+
|
|
19
|
+
head_ref="${{ github.head_ref }}"
|
|
20
|
+
base_ref="${{ github.base_ref }}"
|
|
21
|
+
|
|
22
|
+
if [[ "$head_ref" =~ ^release/ ]] || [[ "$base_ref" =~ ^release/ ]]; then
|
|
23
|
+
echo "Release/version branch PR detected; multi-commit history is allowed when needed."
|
|
24
|
+
exit 0
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
commit_count='${{ github.event.pull_request.commits }}'
|
|
28
|
+
if [ "$commit_count" -ne 1 ]; then
|
|
29
|
+
echo "Normal PRs from feature/fix/docs/chore branches must contain exactly one commit before review. Current PR has $commit_count commits. Squash the history before requesting review."
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
test:
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
|
|
36
|
+
steps:
|
|
37
|
+
- name: Checkout
|
|
38
|
+
uses: actions/checkout@v4
|
|
39
|
+
with:
|
|
40
|
+
fetch-depth: 0
|
|
41
|
+
|
|
42
|
+
- name: Setup Python
|
|
43
|
+
uses: actions/setup-python@v5
|
|
44
|
+
with:
|
|
45
|
+
python-version: '3.11'
|
|
46
|
+
|
|
47
|
+
- name: Install dependencies
|
|
48
|
+
run: |
|
|
49
|
+
python -m pip install --upgrade pip
|
|
50
|
+
python -m pip install -e .[dev] build
|
|
51
|
+
|
|
52
|
+
- name: Lint
|
|
53
|
+
run: ruff check .
|
|
54
|
+
|
|
55
|
+
- name: Test with coverage
|
|
56
|
+
run: >-
|
|
57
|
+
pytest
|
|
58
|
+
--cov=src/nnrp
|
|
59
|
+
--cov=scripts
|
|
60
|
+
--cov-report=xml:artifacts/coverage/coverage.xml
|
|
61
|
+
--cov-fail-under=90
|
|
62
|
+
-q
|
|
63
|
+
|
|
64
|
+
- name: Incremental line coverage gate
|
|
65
|
+
if: github.event_name == 'pull_request' || github.event_name == 'push'
|
|
66
|
+
shell: bash
|
|
67
|
+
run: |
|
|
68
|
+
base_sha=""
|
|
69
|
+
head_sha=""
|
|
70
|
+
|
|
71
|
+
if [ "${{ github.event_name }}" = "pull_request" ]; then
|
|
72
|
+
base_sha="${{ github.event.pull_request.base.sha }}"
|
|
73
|
+
head_sha="${{ github.event.pull_request.head.sha }}"
|
|
74
|
+
else
|
|
75
|
+
base_sha="${{ github.event.before }}"
|
|
76
|
+
head_sha="${{ github.sha }}"
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
python scripts/check_incremental_coverage.py \
|
|
80
|
+
--base-sha "$base_sha" \
|
|
81
|
+
--head-sha "$head_sha" \
|
|
82
|
+
--threshold 90 \
|
|
83
|
+
--coverage-xml artifacts/coverage/coverage.xml
|
|
84
|
+
|
|
85
|
+
required-checks:
|
|
86
|
+
needs:
|
|
87
|
+
- commit-policy
|
|
88
|
+
- test
|
|
89
|
+
if: always()
|
|
90
|
+
runs-on: ubuntu-latest
|
|
91
|
+
|
|
92
|
+
steps:
|
|
93
|
+
- name: Enforce required CI path
|
|
94
|
+
shell: bash
|
|
95
|
+
run: |
|
|
96
|
+
if [ "${{ github.event_name }}" = "pull_request" ] && [ "${{ needs.commit-policy.result }}" != "success" ]; then
|
|
97
|
+
echo "PR commit policy validation failed."
|
|
98
|
+
exit 1
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
if [ "${{ needs.test.result }}" != "success" ]; then
|
|
102
|
+
echo "Lint, test, total coverage, or incremental coverage validation failed."
|
|
103
|
+
exit 1
|
|
104
|
+
fi
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
inputs:
|
|
9
|
+
ref:
|
|
10
|
+
description: Git ref to release when running manually
|
|
11
|
+
required: true
|
|
12
|
+
default: main
|
|
13
|
+
publish_github_release:
|
|
14
|
+
description: Publish or update the GitHub Release
|
|
15
|
+
required: true
|
|
16
|
+
type: boolean
|
|
17
|
+
default: true
|
|
18
|
+
publish_to_pypi:
|
|
19
|
+
description: Publish built distributions to PyPI
|
|
20
|
+
required: true
|
|
21
|
+
type: boolean
|
|
22
|
+
default: false
|
|
23
|
+
|
|
24
|
+
permissions:
|
|
25
|
+
contents: write
|
|
26
|
+
|
|
27
|
+
jobs:
|
|
28
|
+
package:
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
environment:
|
|
31
|
+
name: release
|
|
32
|
+
permissions:
|
|
33
|
+
contents: write
|
|
34
|
+
id-token: write
|
|
35
|
+
env:
|
|
36
|
+
PYPI_PUBLISH_MODE: ${{ vars.PYPI_PUBLISH_MODE || 'disabled' }}
|
|
37
|
+
PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
|
|
38
|
+
|
|
39
|
+
steps:
|
|
40
|
+
- name: Checkout
|
|
41
|
+
uses: actions/checkout@v4
|
|
42
|
+
with:
|
|
43
|
+
fetch-depth: 0
|
|
44
|
+
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.ref || github.ref }}
|
|
45
|
+
|
|
46
|
+
- name: Setup Python
|
|
47
|
+
uses: actions/setup-python@v5
|
|
48
|
+
with:
|
|
49
|
+
python-version: '3.11'
|
|
50
|
+
|
|
51
|
+
- name: Resolve version
|
|
52
|
+
id: version
|
|
53
|
+
run: |
|
|
54
|
+
python scripts/resolve_version.py show --github-output --run-number ""
|
|
55
|
+
|
|
56
|
+
- name: Validate pushed tag
|
|
57
|
+
if: github.event_name == 'push'
|
|
58
|
+
shell: bash
|
|
59
|
+
run: |
|
|
60
|
+
set -euo pipefail
|
|
61
|
+
|
|
62
|
+
expected_tag="${{ steps.version.outputs.tag_name }}"
|
|
63
|
+
actual_tag="${{ github.ref_name }}"
|
|
64
|
+
|
|
65
|
+
if [ "$actual_tag" != "$expected_tag" ]; then
|
|
66
|
+
echo "Release tag mismatch: expected $expected_tag but workflow was triggered by $actual_tag."
|
|
67
|
+
exit 1
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
- name: Create git tag
|
|
71
|
+
if: github.event_name == 'workflow_dispatch'
|
|
72
|
+
shell: bash
|
|
73
|
+
run: |
|
|
74
|
+
set -euo pipefail
|
|
75
|
+
|
|
76
|
+
git fetch --tags
|
|
77
|
+
tag="${{ steps.version.outputs.tag_name }}"
|
|
78
|
+
if [ -z "$(git tag --list "$tag")" ]; then
|
|
79
|
+
git config user.name "github-actions[bot]"
|
|
80
|
+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
|
81
|
+
git tag "$tag"
|
|
82
|
+
git push origin "$tag"
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
- name: Apply build version
|
|
86
|
+
run: |
|
|
87
|
+
python scripts/resolve_version.py apply --package-version "${{ steps.version.outputs.package_version }}"
|
|
88
|
+
|
|
89
|
+
- name: Install dependencies
|
|
90
|
+
run: |
|
|
91
|
+
python -m pip install --upgrade pip
|
|
92
|
+
python -m pip install -e .[dev] build twine
|
|
93
|
+
|
|
94
|
+
- name: Test
|
|
95
|
+
run: pytest -q
|
|
96
|
+
|
|
97
|
+
- name: Build distribution
|
|
98
|
+
run: python -m build
|
|
99
|
+
|
|
100
|
+
- name: Bundle release artifacts
|
|
101
|
+
run: |
|
|
102
|
+
python - <<'PY'
|
|
103
|
+
import pathlib
|
|
104
|
+
import zipfile
|
|
105
|
+
|
|
106
|
+
version = '${{ steps.version.outputs.package_version }}'
|
|
107
|
+
artifact_dir = pathlib.Path('artifacts')
|
|
108
|
+
artifact_dir.mkdir(exist_ok=True)
|
|
109
|
+
artifact = artifact_dir / f'nnrp-py-{version}.zip'
|
|
110
|
+
with zipfile.ZipFile(artifact, 'w', compression=zipfile.ZIP_DEFLATED) as archive:
|
|
111
|
+
for item in sorted(pathlib.Path('dist').glob('*')):
|
|
112
|
+
archive.write(item, item.name)
|
|
113
|
+
PY
|
|
114
|
+
|
|
115
|
+
- name: Upload workflow artifacts
|
|
116
|
+
uses: actions/upload-artifact@v4
|
|
117
|
+
with:
|
|
118
|
+
name: nnrp-py-release-${{ steps.version.outputs.package_version }}
|
|
119
|
+
path: artifacts/nnrp-py-${{ steps.version.outputs.package_version }}.zip
|
|
120
|
+
if-no-files-found: error
|
|
121
|
+
retention-days: 14
|
|
122
|
+
|
|
123
|
+
- name: Publish GitHub release
|
|
124
|
+
if: github.event_name == 'push' || inputs.publish_github_release
|
|
125
|
+
uses: softprops/action-gh-release@v2
|
|
126
|
+
with:
|
|
127
|
+
tag_name: ${{ steps.version.outputs.tag_name }}
|
|
128
|
+
name: ${{ steps.version.outputs.release_name }}
|
|
129
|
+
files: artifacts/nnrp-py-${{ steps.version.outputs.package_version }}.zip
|
|
130
|
+
|
|
131
|
+
- name: Publish to PyPI with Trusted Publisher
|
|
132
|
+
if: (github.event_name == 'push' || inputs.publish_to_pypi) && env.PYPI_PUBLISH_MODE == 'trusted'
|
|
133
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
134
|
+
|
|
135
|
+
- name: Publish to PyPI with API token
|
|
136
|
+
if: (github.event_name == 'push' || inputs.publish_to_pypi) && env.PYPI_PUBLISH_MODE == 'token' && env.PYPI_API_TOKEN != ''
|
|
137
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
138
|
+
with:
|
|
139
|
+
password: ${{ env.PYPI_API_TOKEN }}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
*.pyo
|
|
4
|
+
*.pyd
|
|
5
|
+
.Python
|
|
6
|
+
.coverage
|
|
7
|
+
.coverage.*
|
|
8
|
+
artifacts/coverage/
|
|
9
|
+
.hypothesis/
|
|
10
|
+
.mypy_cache/
|
|
11
|
+
.nox/
|
|
12
|
+
.pytest_cache/
|
|
13
|
+
.ruff_cache/
|
|
14
|
+
.tox/
|
|
15
|
+
.venv/
|
|
16
|
+
venv/
|
|
17
|
+
build/
|
|
18
|
+
dist/
|
|
19
|
+
htmlcov/
|
|
20
|
+
pip-wheel-metadata/
|
|
21
|
+
site/
|
|
22
|
+
.venv/
|
|
23
|
+
__pycache__/
|
|
24
|
+
.pytest_cache/
|
|
25
|
+
.mypy_cache/
|
|
26
|
+
.ruff_cache/
|
|
27
|
+
build/
|
|
28
|
+
dist/
|
|
29
|
+
*.egg-info/
|
|
30
|
+
*.pyc
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Contributing to nnrp-py
|
|
2
|
+
|
|
3
|
+
This repository publishes Python SDK packages and protocol tooling, so contribution flow needs to stay predictable.
|
|
4
|
+
|
|
5
|
+
## Branch Strategy
|
|
6
|
+
|
|
7
|
+
The protected integration branch should be the repository default branch.
|
|
8
|
+
|
|
9
|
+
For the public GitHub repository, use `main` as the protected integration branch.
|
|
10
|
+
|
|
11
|
+
Use short-lived topic branches for day-to-day work:
|
|
12
|
+
|
|
13
|
+
- `feature/<scope>-<topic>` for new capabilities
|
|
14
|
+
- `fix/<scope>-<topic>` for bug fixes
|
|
15
|
+
- `docs/<scope>-<topic>` for documentation-only changes
|
|
16
|
+
- `chore/<scope>-<topic>` for maintenance and tooling updates
|
|
17
|
+
- `release/<version>` only when stabilizing a public package release candidate
|
|
18
|
+
|
|
19
|
+
Rules:
|
|
20
|
+
|
|
21
|
+
- Branch from the latest default integration branch, normally `main`.
|
|
22
|
+
- Keep topic branches focused on one slice of work.
|
|
23
|
+
- Rebase or merge from the default integration branch regularly if the branch stays open.
|
|
24
|
+
- Merge back to the default integration branch through a pull request.
|
|
25
|
+
- Do not push directly to the default integration branch; enforce this with a GitHub ruleset or branch protection rule.
|
|
26
|
+
- Do not publish packages directly from topic branches.
|
|
27
|
+
|
|
28
|
+
`release/<version>` branches are optional and should be used only when a version needs stabilization passes, packaging rehearsals, or manual workflow runs without publishing from the default integration branch.
|
|
29
|
+
|
|
30
|
+
## Commit Message Convention
|
|
31
|
+
|
|
32
|
+
Use Conventional Commits.
|
|
33
|
+
|
|
34
|
+
Preferred forms:
|
|
35
|
+
|
|
36
|
+
- `feat: add transport probe state summary`
|
|
37
|
+
- `fix: reject malformed session migrate ack`
|
|
38
|
+
- `docs: clarify wheel build prerequisites`
|
|
39
|
+
- `chore: tighten CI dependency bootstrap`
|
|
40
|
+
- `test: add protocol vector regression`
|
|
41
|
+
- `refactor: simplify packet decode flow`
|
|
42
|
+
|
|
43
|
+
Rules:
|
|
44
|
+
|
|
45
|
+
- Keep the subject line imperative.
|
|
46
|
+
- Keep the first line concise.
|
|
47
|
+
- Use a scope only when it adds clarity.
|
|
48
|
+
- You can use multiple local commits while iterating, but normal PRs from `feature/*`, `fix/*`, `docs/*`, or `chore/*` branches must be squashed to exactly one commit before review.
|
|
49
|
+
- Only version-maintenance PRs that target or originate from `release/<version>` branches may keep multiple commits when that history is actually needed.
|
|
50
|
+
|
|
51
|
+
## Pull Request Expectations
|
|
52
|
+
|
|
53
|
+
Every PR should:
|
|
54
|
+
|
|
55
|
+
- target the default integration branch, normally `main`
|
|
56
|
+
- use the default GitHub PR template that auto-loads on the PR page; specialized reference variants remain in `.github/PULL_REQUEST_TEMPLATE/` when you need to adapt the structure
|
|
57
|
+
- explain the user-facing or engineering motivation
|
|
58
|
+
- summarize the main modules or flows changed
|
|
59
|
+
- list the validation performed
|
|
60
|
+
- mention release impact when distribution output changes
|
|
61
|
+
- contain exactly one commit before review unless it is a necessary `release/<version>` branch PR
|
|
62
|
+
- pass the `required-checks` GitHub Actions job before merge
|
|
63
|
+
|
|
64
|
+
PRs that violate the normal one-commit rule are not reviewed until they are squashed.
|
|
65
|
+
|
|
66
|
+
## Validation Expectations
|
|
67
|
+
|
|
68
|
+
Before opening or merging a PR, prefer the narrowest validation that proves the touched slice:
|
|
69
|
+
|
|
70
|
+
- `ruff check .`
|
|
71
|
+
- `pytest -q`
|
|
72
|
+
- `pytest --cov=src/nnrp --cov=scripts --cov-report=xml:artifacts/coverage/coverage.xml --cov-fail-under=90 -q` when validating the repository-wide coverage gate
|
|
73
|
+
- `python -m build` when wheel or sdist output changed
|
|
74
|
+
|
|
75
|
+
PRs that affect CI, packaging, or release assets should include the exact command or workflow path used for validation.
|
|
76
|
+
|
|
77
|
+
Changed production lines under `src/nnrp/` or `scripts/` must also keep at least 90% line coverage in CI before merge.
|
|
78
|
+
|
|
79
|
+
## Versioning and Release Notes
|
|
80
|
+
|
|
81
|
+
Do not reuse a published package version. If package contents change after publication, create a new version.
|
|
82
|
+
|
|
83
|
+
When preparing a release PR:
|
|
84
|
+
|
|
85
|
+
- update the version source intentionally
|
|
86
|
+
- confirm package metadata is correct
|
|
87
|
+
- confirm release assets have the expected names
|
|
88
|
+
- note any manual steps required on registries
|
|
89
|
+
|
|
90
|
+
Public package publishing is gated through the `Release` workflow and should only happen from a short release tag or an explicit manual dispatch.
|
|
91
|
+
|
|
92
|
+
- `Release` runs on pushed `v*` tags and on manual `workflow_dispatch`; normal branch pushes must not publish GitHub releases or PyPI packages.
|
|
93
|
+
- Use the `release` GitHub environment for any publish-capable job.
|
|
94
|
+
- Set `PYPI_PUBLISH_MODE` on the `release` environment to `disabled`, `trusted`, or `token` so tags do not publish to PyPI accidentally before registry binding is ready.
|
|
95
|
+
- If you keep token-based publishing, store `PYPI_API_TOKEN` as an environment secret on `release`, not as an unrestricted repository secret.
|
|
96
|
+
- If you switch to PyPI Trusted Publisher, keep `PYPI_PUBLISH_MODE=trusted`; no PyPI secret is required, but the `release` environment is still recommended for approvals, tag restrictions, and job scoping.
|
|
97
|
+
|
|
98
|
+
## Review Guidelines
|
|
99
|
+
|
|
100
|
+
Review for:
|
|
101
|
+
|
|
102
|
+
- protocol and wire compatibility risk
|
|
103
|
+
- packaging and release regressions
|
|
104
|
+
- missing tests for changed behavior
|
|
105
|
+
- CI workflow correctness
|
|
106
|
+
- documentation drift when user-facing behavior changes
|
|
107
|
+
|
|
108
|
+
Do not start normal feature, fix, docs, or maintenance review while the PR still carries multiple commits.
|