techrevati-runtime 0.1.0__tar.gz → 0.3.0.dev1__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.
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/.github/ISSUE_TEMPLATE/feature.md +3 -3
- techrevati_runtime-0.3.0.dev1/.github/workflows/ci.yml +124 -0
- techrevati_runtime-0.3.0.dev1/.github/workflows/codeql.yml +42 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/.github/workflows/docs.yml +4 -1
- techrevati_runtime-0.3.0.dev1/.github/workflows/release.yml +108 -0
- techrevati_runtime-0.3.0.dev1/CHANGELOG.md +560 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/CODEOWNERS +6 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/CONTRIBUTING.md +63 -2
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/PKG-INFO +8 -6
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/README.md +5 -5
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/SECURITY.md +22 -0
- techrevati_runtime-0.3.0.dev1/docs/api/checkpoint.md +9 -0
- techrevati_runtime-0.3.0.dev1/docs/api/governance.md +3 -0
- techrevati_runtime-0.3.0.dev1/docs/api/hooks.md +3 -0
- techrevati_runtime-0.3.0.dev1/docs/api/persistence.md +7 -0
- techrevati_runtime-0.3.0.dev1/docs/api/rate_limit.md +10 -0
- techrevati_runtime-0.3.0.dev1/docs/api/routing.md +9 -0
- techrevati_runtime-0.3.0.dev1/docs/api/scheduler.md +8 -0
- techrevati_runtime-0.3.0.dev1/docs/api/streaming.md +3 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/index.md +8 -1
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/migrating-from-0.0.x.md +2 -2
- techrevati_runtime-0.3.0.dev1/docs/migrating-from-0.1.x.md +71 -0
- techrevati_runtime-0.3.0.dev1/docs/patterns/durability.md +96 -0
- techrevati_runtime-0.3.0.dev1/docs/patterns/governance.md +194 -0
- techrevati_runtime-0.3.0.dev1/docs/patterns/hooks.md +262 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/patterns/orchestrator.md +9 -10
- techrevati_runtime-0.3.0.dev1/docs/patterns/rate-limiting.md +85 -0
- techrevati_runtime-0.3.0.dev1/docs/patterns/routing.md +82 -0
- techrevati_runtime-0.3.0.dev1/docs/patterns/streaming.md +177 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/tutorials/end-to-end.md +3 -3
- techrevati_runtime-0.3.0.dev1/examples/durable_agent.py +85 -0
- techrevati_runtime-0.3.0.dev1/examples/parallel_tools.py +42 -0
- techrevati_runtime-0.3.0.dev1/examples/pricing.json +46 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/examples/tiny_agent.py +5 -5
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/mkdocs.yml +16 -1
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/pyproject.toml +3 -1
- techrevati_runtime-0.3.0.dev1/scripts/check_module_coverage.py +77 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/src/techrevati/runtime/__init__.py +119 -1
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/src/techrevati/runtime/agent_events.py +54 -0
- techrevati_runtime-0.3.0.dev1/src/techrevati/runtime/checkpoint.py +356 -0
- techrevati_runtime-0.3.0.dev1/src/techrevati/runtime/governance.py +259 -0
- techrevati_runtime-0.3.0.dev1/src/techrevati/runtime/guardrails.py +433 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/src/techrevati/runtime/handoffs.py +2 -2
- techrevati_runtime-0.3.0.dev1/src/techrevati/runtime/hooks.py +515 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/src/techrevati/runtime/orchestrator.py +565 -26
- techrevati_runtime-0.3.0.dev1/src/techrevati/runtime/otel.py +308 -0
- techrevati_runtime-0.3.0.dev1/src/techrevati/runtime/persistence.py +169 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/src/techrevati/runtime/policy_engine.py +21 -0
- techrevati_runtime-0.3.0.dev1/src/techrevati/runtime/rate_limit.py +310 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/src/techrevati/runtime/retry_policy.py +123 -37
- techrevati_runtime-0.3.0.dev1/src/techrevati/runtime/routing.py +180 -0
- techrevati_runtime-0.3.0.dev1/src/techrevati/runtime/scheduler.py +142 -0
- techrevati_runtime-0.3.0.dev1/src/techrevati/runtime/streaming.py +118 -0
- techrevati_runtime-0.3.0.dev1/src/techrevati/runtime/usage_tracking.py +424 -0
- techrevati_runtime-0.3.0.dev1/tests/conftest.py +23 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/tests/test_async_circuit_breaker.py +1 -13
- techrevati_runtime-0.3.0.dev1/tests/test_async_guardrails.py +122 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/tests/test_async_orchestrator.py +13 -13
- techrevati_runtime-0.3.0.dev1/tests/test_checkpoint.py +377 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/tests/test_circuit_breaker.py +1 -13
- techrevati_runtime-0.3.0.dev1/tests/test_deprecation_warnings.py +66 -0
- techrevati_runtime-0.3.0.dev1/tests/test_governance.py +152 -0
- techrevati_runtime-0.3.0.dev1/tests/test_governance_events.py +101 -0
- techrevati_runtime-0.3.0.dev1/tests/test_governance_integration.py +200 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/tests/test_guardrails.py +48 -11
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/tests/test_handoffs.py +5 -5
- techrevati_runtime-0.3.0.dev1/tests/test_hooks.py +422 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/tests/test_max_iterations.py +7 -8
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/tests/test_orchestrator.py +18 -18
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/tests/test_otel.py +4 -4
- techrevati_runtime-0.3.0.dev1/tests/test_otel_atexit_cleanup.py +108 -0
- techrevati_runtime-0.3.0.dev1/tests/test_otel_nesting.py +141 -0
- techrevati_runtime-0.3.0.dev1/tests/test_pattern_and_prompt_injection_guardrails.py +153 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/tests/test_permissions.py +39 -0
- techrevati_runtime-0.3.0.dev1/tests/test_property_circuit_breaker.py +112 -0
- techrevati_runtime-0.3.0.dev1/tests/test_property_retry_policy.py +150 -0
- techrevati_runtime-0.3.0.dev1/tests/test_rate_limit.py +237 -0
- techrevati_runtime-0.3.0.dev1/tests/test_register_pricing_on_conflict.py +69 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/tests/test_retry_policy.py +3 -3
- techrevati_runtime-0.3.0.dev1/tests/test_routing.py +78 -0
- techrevati_runtime-0.3.0.dev1/tests/test_s0_regressions.py +245 -0
- techrevati_runtime-0.3.0.dev1/tests/test_s5_scheduler_persistence_async_policy.py +175 -0
- techrevati_runtime-0.3.0.dev1/tests/test_s5_usage_limits_and_caching.py +179 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/tests/test_sinks.py +6 -6
- techrevati_runtime-0.3.0.dev1/tests/test_step_retries.py +115 -0
- techrevati_runtime-0.3.0.dev1/tests/test_streaming.py +263 -0
- techrevati_runtime-0.3.0.dev1/tests/test_taskgroup_parallel_tools.py +84 -0
- techrevati_runtime-0.1.0/.github/workflows/ci.yml +0 -72
- techrevati_runtime-0.1.0/.github/workflows/release.yml +0 -38
- techrevati_runtime-0.1.0/CHANGELOG.md +0 -219
- techrevati_runtime-0.1.0/examples/pricing.json +0 -37
- techrevati_runtime-0.1.0/src/techrevati/runtime/guardrails.py +0 -138
- techrevati_runtime-0.1.0/src/techrevati/runtime/otel.py +0 -190
- techrevati_runtime-0.1.0/src/techrevati/runtime/usage_tracking.py +0 -232
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/.github/ISSUE_TEMPLATE/bug.md +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/.github/dependabot.yml +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/.gitignore +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/.pre-commit-config.yaml +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/LICENSE +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/api/circuit_breaker.md +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/api/guardrails.md +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/api/handoffs.md +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/api/orchestrator.md +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/api/otel.md +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/api/retry_policy.md +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/api/sinks.md +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/api/usage_tracking.md +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/changelog.md +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/getting-started.md +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/patterns/agent-events.md +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/patterns/circuit-breaker.md +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/patterns/lifecycle.md +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/patterns/permissions.md +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/patterns/policy.md +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/patterns/quality-gate.md +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/patterns/retry.md +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/docs/patterns/usage-tracking.md +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/src/techrevati/__init__.py +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/src/techrevati/runtime/agent_lifecycle.py +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/src/techrevati/runtime/circuit_breaker.py +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/src/techrevati/runtime/data/pricing.json +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/src/techrevati/runtime/permissions.py +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/src/techrevati/runtime/py.typed +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/src/techrevati/runtime/quality_gate.py +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/src/techrevati/runtime/sinks.py +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/tests/__init__.py +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/tests/test_agent_events.py +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/tests/test_agent_lifecycle.py +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/tests/test_policy_engine.py +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/tests/test_quality_gate.py +0 -0
- {techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/tests/test_usage_tracking.py +0 -0
{techrevati_runtime-0.1.0 → techrevati_runtime-0.3.0.dev1}/.github/ISSUE_TEMPLATE/feature.md
RENAMED
|
@@ -20,6 +20,6 @@ labels: enhancement
|
|
|
20
20
|
<!-- What would you do today as a workaround? Why doesn't it scale? -->
|
|
21
21
|
|
|
22
22
|
**Industry priors**
|
|
23
|
-
<!-- Has another agent SDK (OpenAI Agents SDK, LangGraph,
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
<!-- Has another agent SDK (OpenAI Agents SDK, LangGraph, etc.)
|
|
24
|
+
shipped something similar? Link it. We prefer landing
|
|
25
|
+
primitives that match industry conventions. -->
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
name: Test on Python ${{ matrix.python-version }}
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
strategy:
|
|
14
|
+
matrix:
|
|
15
|
+
python-version: ['3.11', '3.12', '3.13']
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
21
|
+
uses: actions/setup-python@v5
|
|
22
|
+
with:
|
|
23
|
+
python-version: ${{ matrix.python-version }}
|
|
24
|
+
cache: pip
|
|
25
|
+
cache-dependency-path: pyproject.toml
|
|
26
|
+
|
|
27
|
+
- name: Install package + dev dependencies
|
|
28
|
+
run: |
|
|
29
|
+
python -m pip install --upgrade pip
|
|
30
|
+
pip install -e ".[dev]"
|
|
31
|
+
|
|
32
|
+
- name: Lint with ruff
|
|
33
|
+
run: ruff check src/ tests/
|
|
34
|
+
|
|
35
|
+
- name: Format check with ruff
|
|
36
|
+
run: ruff format --check src/ tests/
|
|
37
|
+
|
|
38
|
+
- name: Type check with mypy
|
|
39
|
+
run: mypy src/ --strict
|
|
40
|
+
|
|
41
|
+
- name: Run tests
|
|
42
|
+
run: pytest tests/ -v --cov=src/techrevati --cov-report=term-missing --cov-report=xml
|
|
43
|
+
|
|
44
|
+
- name: Per-module coverage floor (>= 85%)
|
|
45
|
+
run: python scripts/check_module_coverage.py --threshold 85
|
|
46
|
+
|
|
47
|
+
- name: Upload coverage
|
|
48
|
+
uses: codecov/codecov-action@v4
|
|
49
|
+
with:
|
|
50
|
+
files: ./coverage.xml
|
|
51
|
+
fail_ci_if_error: false
|
|
52
|
+
|
|
53
|
+
build:
|
|
54
|
+
name: Build on Python ${{ matrix.python-version }}
|
|
55
|
+
runs-on: ubuntu-latest
|
|
56
|
+
needs: test
|
|
57
|
+
strategy:
|
|
58
|
+
matrix:
|
|
59
|
+
python-version: ['3.11', '3.12', '3.13']
|
|
60
|
+
|
|
61
|
+
steps:
|
|
62
|
+
- uses: actions/checkout@v4
|
|
63
|
+
|
|
64
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
65
|
+
uses: actions/setup-python@v5
|
|
66
|
+
with:
|
|
67
|
+
python-version: ${{ matrix.python-version }}
|
|
68
|
+
|
|
69
|
+
- name: Install build tools
|
|
70
|
+
run: pip install build
|
|
71
|
+
|
|
72
|
+
- name: Build distribution
|
|
73
|
+
run: python -m build
|
|
74
|
+
|
|
75
|
+
- name: Check wheel
|
|
76
|
+
run: |
|
|
77
|
+
pip install dist/*.whl
|
|
78
|
+
python -c "from techrevati import runtime; print(f'techrevati-runtime {runtime.__version__}')"
|
|
79
|
+
|
|
80
|
+
zero-deps-smoke:
|
|
81
|
+
name: Zero-deps smoke on Python ${{ matrix.python-version }}
|
|
82
|
+
runs-on: ubuntu-latest
|
|
83
|
+
needs: build
|
|
84
|
+
strategy:
|
|
85
|
+
matrix:
|
|
86
|
+
python-version: ['3.11', '3.12', '3.13']
|
|
87
|
+
|
|
88
|
+
steps:
|
|
89
|
+
- uses: actions/checkout@v4
|
|
90
|
+
|
|
91
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
92
|
+
uses: actions/setup-python@v5
|
|
93
|
+
with:
|
|
94
|
+
python-version: ${{ matrix.python-version }}
|
|
95
|
+
|
|
96
|
+
- name: Build distribution
|
|
97
|
+
run: |
|
|
98
|
+
pip install build
|
|
99
|
+
python -m build
|
|
100
|
+
|
|
101
|
+
- name: Install in an empty venv (no [dev], no [otel])
|
|
102
|
+
# Spin a fresh venv to verify the zero-runtime-dependency
|
|
103
|
+
# promise: the wheel must import with only stdlib + the wheel
|
|
104
|
+
# itself, no optional extras pulled in.
|
|
105
|
+
run: |
|
|
106
|
+
python -m venv smoke-venv
|
|
107
|
+
smoke-venv/bin/pip install --upgrade pip
|
|
108
|
+
smoke-venv/bin/pip install dist/*.whl
|
|
109
|
+
smoke-venv/bin/python -c "
|
|
110
|
+
import techrevati.runtime as r
|
|
111
|
+
assert r.__version__, '__version__ missing'
|
|
112
|
+
# Touch the public exports to make sure every module imports
|
|
113
|
+
# without optional deps installed.
|
|
114
|
+
from techrevati.runtime import (
|
|
115
|
+
AgentSession, OrchestrationSession, AsyncOrchestrationSession,
|
|
116
|
+
CircuitBreaker, AsyncCircuitBreaker,
|
|
117
|
+
TokenBucket, AsyncTokenBucket, RateLimiter,
|
|
118
|
+
StaticProviderRouter, RoundRobinProviderRouter,
|
|
119
|
+
InMemorySaver, SqliteSaver,
|
|
120
|
+
SqliteEventSink, SqliteUsageSink,
|
|
121
|
+
UsageLimits, ManualClock, SystemClock,
|
|
122
|
+
)
|
|
123
|
+
print(f'zero-deps smoke OK on techrevati-runtime {r.__version__}')
|
|
124
|
+
"
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: CodeQL
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
schedule:
|
|
9
|
+
# Weekly scan on Mondays — catches dependency-driven advisories
|
|
10
|
+
# that land after a PR has already been merged.
|
|
11
|
+
- cron: '0 6 * * 1'
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
actions: read
|
|
15
|
+
contents: read
|
|
16
|
+
security-events: write
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
analyze:
|
|
20
|
+
name: Analyze ${{ matrix.language }}
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
strategy:
|
|
23
|
+
fail-fast: false
|
|
24
|
+
matrix:
|
|
25
|
+
language: [python]
|
|
26
|
+
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@v4
|
|
29
|
+
|
|
30
|
+
- name: Initialize CodeQL
|
|
31
|
+
uses: github/codeql-action/init@v3
|
|
32
|
+
with:
|
|
33
|
+
languages: ${{ matrix.language }}
|
|
34
|
+
queries: security-and-quality
|
|
35
|
+
|
|
36
|
+
- name: Autobuild
|
|
37
|
+
uses: github/codeql-action/autobuild@v3
|
|
38
|
+
|
|
39
|
+
- name: Perform CodeQL Analysis
|
|
40
|
+
uses: github/codeql-action/analyze@v3
|
|
41
|
+
with:
|
|
42
|
+
category: "/language:${{ matrix.language }}"
|
|
@@ -26,7 +26,10 @@ jobs:
|
|
|
26
26
|
pip install mkdocs mkdocs-material mkdocstrings[python]
|
|
27
27
|
|
|
28
28
|
- name: Build documentation
|
|
29
|
-
|
|
29
|
+
# --strict turns broken refs and unresolved nav entries into
|
|
30
|
+
# hard failures so a doc regression cannot silently degrade
|
|
31
|
+
# the published site.
|
|
32
|
+
run: mkdocs build --strict
|
|
30
33
|
|
|
31
34
|
- name: Deploy to GitHub Pages
|
|
32
35
|
uses: peaceiris/actions-gh-pages@v3
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
# contents: write so softprops/action-gh-release can create the
|
|
10
|
+
# GitHub Release; id-token: write for PyPI trusted publishing.
|
|
11
|
+
contents: write
|
|
12
|
+
id-token: write
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
# Gate the release behind the same lint/type/test checks CI enforces
|
|
16
|
+
# on `main`. Without this, a tag push could publish a broken wheel to
|
|
17
|
+
# PyPI even if CI was red on the underlying commit. Matrix mirrors
|
|
18
|
+
# ci.yml so the gate has the same shape.
|
|
19
|
+
verify:
|
|
20
|
+
name: Verify on Python ${{ matrix.python-version }}
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
strategy:
|
|
23
|
+
matrix:
|
|
24
|
+
python-version: ['3.11', '3.12', '3.13']
|
|
25
|
+
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
|
|
29
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
30
|
+
uses: actions/setup-python@v5
|
|
31
|
+
with:
|
|
32
|
+
python-version: ${{ matrix.python-version }}
|
|
33
|
+
cache: pip
|
|
34
|
+
cache-dependency-path: pyproject.toml
|
|
35
|
+
|
|
36
|
+
- name: Install package + dev dependencies
|
|
37
|
+
run: |
|
|
38
|
+
python -m pip install --upgrade pip
|
|
39
|
+
pip install -e ".[dev]"
|
|
40
|
+
|
|
41
|
+
- name: Lint with ruff
|
|
42
|
+
run: ruff check src/ tests/
|
|
43
|
+
|
|
44
|
+
- name: Format check with ruff
|
|
45
|
+
run: ruff format --check src/ tests/
|
|
46
|
+
|
|
47
|
+
- name: Type check with mypy
|
|
48
|
+
run: mypy src/ --strict
|
|
49
|
+
|
|
50
|
+
- name: Run tests
|
|
51
|
+
run: pytest tests/ -v --cov=src/techrevati --cov-report=term-missing
|
|
52
|
+
|
|
53
|
+
- name: Per-module coverage floor (>= 85%)
|
|
54
|
+
run: python scripts/check_module_coverage.py --threshold 85
|
|
55
|
+
|
|
56
|
+
release:
|
|
57
|
+
name: Release to PyPI
|
|
58
|
+
runs-on: ubuntu-latest
|
|
59
|
+
needs: verify
|
|
60
|
+
|
|
61
|
+
steps:
|
|
62
|
+
- uses: actions/checkout@v4
|
|
63
|
+
|
|
64
|
+
- name: Set up Python
|
|
65
|
+
uses: actions/setup-python@v5
|
|
66
|
+
with:
|
|
67
|
+
python-version: '3.11'
|
|
68
|
+
|
|
69
|
+
- name: Install build tools
|
|
70
|
+
# cyclonedx-py is dev-only here — it generates the SBOM
|
|
71
|
+
# artifact and never touches the runtime install.
|
|
72
|
+
run: pip install build cyclonedx-bom
|
|
73
|
+
|
|
74
|
+
- name: Build distribution
|
|
75
|
+
run: python -m build
|
|
76
|
+
|
|
77
|
+
- name: Stage artifacts for PyPI
|
|
78
|
+
# Keep PyPI uploads strictly to wheel + sdist. The SBOM lives
|
|
79
|
+
# alongside the wheel on the GitHub Release but never lands on
|
|
80
|
+
# the index.
|
|
81
|
+
run: |
|
|
82
|
+
mkdir -p pypi-dist
|
|
83
|
+
cp dist/*.whl dist/*.tar.gz pypi-dist/
|
|
84
|
+
|
|
85
|
+
- name: Generate CycloneDX SBOM
|
|
86
|
+
# SBOM describes the build's dependency graph at publish time.
|
|
87
|
+
# PyPI's trusted-publishing attestations + this SBOM together
|
|
88
|
+
# give downstream consumers everything they need to verify
|
|
89
|
+
# provenance (see SECURITY.md for the verify command).
|
|
90
|
+
run: |
|
|
91
|
+
pip install dist/*.whl
|
|
92
|
+
cyclonedx-py environment --output-format json --output-file dist/sbom.cyclonedx.json
|
|
93
|
+
cyclonedx-py environment --output-format xml --output-file dist/sbom.cyclonedx.xml
|
|
94
|
+
|
|
95
|
+
- name: Publish to PyPI (Trusted Publishing)
|
|
96
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
97
|
+
with:
|
|
98
|
+
packages-dir: pypi-dist
|
|
99
|
+
|
|
100
|
+
- name: Create GitHub Release
|
|
101
|
+
uses: softprops/action-gh-release@v1
|
|
102
|
+
with:
|
|
103
|
+
generate_release_notes: true
|
|
104
|
+
files: |
|
|
105
|
+
dist/*.whl
|
|
106
|
+
dist/*.tar.gz
|
|
107
|
+
dist/sbom.cyclonedx.json
|
|
108
|
+
dist/sbom.cyclonedx.xml
|