stemtrace 0.3.4__tar.gz → 0.3.6__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 (156) hide show
  1. {stemtrace-0.3.4 → stemtrace-0.3.6}/.bumpversion.toml +1 -1
  2. {stemtrace-0.3.4 → stemtrace-0.3.6}/.github/dependabot.yml +10 -1
  3. stemtrace-0.3.6/.github/workflows/ci.yml +230 -0
  4. {stemtrace-0.3.4 → stemtrace-0.3.6}/.github/workflows/e2e.yml +26 -18
  5. {stemtrace-0.3.4 → stemtrace-0.3.6}/.github/workflows/release.yml +27 -20
  6. stemtrace-0.3.6/CHANGELOG.md +162 -0
  7. stemtrace-0.3.6/Dockerfile +69 -0
  8. stemtrace-0.3.6/Dockerfile.e2e +37 -0
  9. {stemtrace-0.3.4 → stemtrace-0.3.6}/PKG-INFO +27 -4
  10. {stemtrace-0.3.4 → stemtrace-0.3.6}/README.md +23 -1
  11. {stemtrace-0.3.4 → stemtrace-0.3.6}/build_ui.py +44 -3
  12. stemtrace-0.3.6/docs/brand/stemtrace-mark-light.svg +1 -0
  13. stemtrace-0.3.6/docs/brand/stemtrace-mark.svg +1 -0
  14. {stemtrace-0.3.4 → stemtrace-0.3.6}/examples/fastapi_integration.py +1 -1
  15. {stemtrace-0.3.4 → stemtrace-0.3.6}/examples/with_auth.py +1 -1
  16. {stemtrace-0.3.4 → stemtrace-0.3.6}/examples/with_login.py +1 -1
  17. {stemtrace-0.3.4 → stemtrace-0.3.6}/pyproject.toml +7 -4
  18. stemtrace-0.3.6/scripts/wait_for_http.py +77 -0
  19. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/__init__.py +1 -1
  20. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/core/ports.py +21 -1
  21. stemtrace-0.3.6/src/stemtrace/library/transports/redis.py +381 -0
  22. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/api/routes.py +19 -3
  23. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/api/schemas.py +6 -0
  24. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/consumer.py +109 -12
  25. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/biome.json +1 -1
  26. stemtrace-0.3.6/src/stemtrace/server/ui/frontend/index.html +19 -0
  27. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/package-lock.json +679 -1227
  28. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/package.json +12 -6
  29. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/api/client.ts +1 -0
  30. stemtrace-0.3.6/src/stemtrace/server/ui/frontend/src/components/SproutMark.tsx +42 -0
  31. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/components/TimelineBar.tsx +1 -1
  32. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/routes/__root.tsx +10 -4
  33. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/static.py +63 -4
  34. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/templates/login.html +4 -0
  35. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/conftest.py +2 -2
  36. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/integration/test_fastapi_integration.py +30 -26
  37. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/integration/test_rabbitmq_transport.py +3 -3
  38. stemtrace-0.3.6/tests/integration/test_redis_resilience_docker.py +205 -0
  39. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/integration/test_redis_transport.py +7 -7
  40. stemtrace-0.3.6/tests/integration/test_static_ui.py +977 -0
  41. stemtrace-0.3.6/tests/integration/test_wait_for_http_redirects.py +80 -0
  42. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/integration/test_workers_refresh.py +5 -3
  43. stemtrace-0.3.6/tests/unit/test_build_ui_hook.py +68 -0
  44. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/unit/test_consumer.py +334 -13
  45. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/unit/test_events.py +21 -21
  46. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/unit/test_examples.py +12 -8
  47. stemtrace-0.3.6/tests/unit/test_favicon.py +48 -0
  48. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/unit/test_form_login.py +26 -0
  49. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/unit/test_graph.py +88 -88
  50. stemtrace-0.3.6/tests/unit/test_redis_resilience.py +424 -0
  51. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/unit/test_routes.py +59 -6
  52. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/unit/test_store.py +10 -10
  53. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/unit/test_transports.py +48 -15
  54. stemtrace-0.3.6/tests/unit/test_wait_for_http_script.py +103 -0
  55. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/unit/test_websocket.py +2 -2
  56. {stemtrace-0.3.4 → stemtrace-0.3.6}/uv.lock +133 -111
  57. stemtrace-0.3.4/.github/workflows/ci.yml +0 -189
  58. stemtrace-0.3.4/CHANGELOG.md +0 -126
  59. stemtrace-0.3.4/Dockerfile +0 -58
  60. stemtrace-0.3.4/Dockerfile.e2e +0 -27
  61. stemtrace-0.3.4/scripts/wait_for_http.py +0 -41
  62. stemtrace-0.3.4/src/stemtrace/library/transports/redis.py +0 -165
  63. stemtrace-0.3.4/src/stemtrace/server/ui/frontend/index.html +0 -16
  64. stemtrace-0.3.4/tests/integration/test_static_ui.py +0 -451
  65. {stemtrace-0.3.4 → stemtrace-0.3.6}/.dockerignore +0 -0
  66. {stemtrace-0.3.4 → stemtrace-0.3.6}/.gitignore +0 -0
  67. {stemtrace-0.3.4 → stemtrace-0.3.6}/.pre-commit-config.yaml +0 -0
  68. {stemtrace-0.3.4 → stemtrace-0.3.6}/.python-version +0 -0
  69. {stemtrace-0.3.4 → stemtrace-0.3.6}/CONTRIBUTING.md +0 -0
  70. {stemtrace-0.3.4 → stemtrace-0.3.6}/LICENSE +0 -0
  71. {stemtrace-0.3.4 → stemtrace-0.3.6}/Makefile +0 -0
  72. {stemtrace-0.3.4 → stemtrace-0.3.6}/docker-compose.e2e.rabbitmq.yml +0 -0
  73. {stemtrace-0.3.4 → stemtrace-0.3.6}/docker-compose.e2e.yml +0 -0
  74. {stemtrace-0.3.4 → stemtrace-0.3.6}/docker-compose.rabbitmq.yml +0 -0
  75. {stemtrace-0.3.4 → stemtrace-0.3.6}/docker-compose.yml +0 -0
  76. {stemtrace-0.3.4 → stemtrace-0.3.6}/docs/screenshots/task_details.png +0 -0
  77. {stemtrace-0.3.4 → stemtrace-0.3.6}/docs/screenshots/unregistered.png +0 -0
  78. {stemtrace-0.3.4 → stemtrace-0.3.6}/docs/screenshots/workflow.png +0 -0
  79. {stemtrace-0.3.4 → stemtrace-0.3.6}/examples/celery_app.py +0 -0
  80. {stemtrace-0.3.4 → stemtrace-0.3.6}/progress.md +0 -0
  81. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/core/__init__.py +0 -0
  82. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/core/events.py +0 -0
  83. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/core/exceptions.py +0 -0
  84. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/core/graph.py +0 -0
  85. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/library/__init__.py +0 -0
  86. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/library/bootsteps.py +0 -0
  87. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/library/config.py +0 -0
  88. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/library/scrubbing.py +0 -0
  89. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/library/signals.py +0 -0
  90. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/library/transports/__init__.py +0 -0
  91. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/library/transports/memory.py +0 -0
  92. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/library/transports/rabbitmq.py +0 -0
  93. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/py.typed +0 -0
  94. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/__init__.py +0 -0
  95. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/__main__.py +0 -0
  96. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/api/__init__.py +0 -0
  97. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/api/websocket.py +0 -0
  98. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/fastapi/__init__.py +0 -0
  99. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/fastapi/auth.py +0 -0
  100. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/fastapi/extension.py +0 -0
  101. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/fastapi/form_auth.py +0 -0
  102. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/fastapi/login_routes.py +0 -0
  103. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/fastapi/router.py +0 -0
  104. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/store.py +0 -0
  105. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/__init__.py +0 -0
  106. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/playwright.config.ts +0 -0
  107. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/postcss.config.js +0 -0
  108. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/api/queries.ts +0 -0
  109. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/components/DateRangePicker.tsx +0 -0
  110. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/components/Filters.tsx +0 -0
  111. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/components/TaskGraph.tsx +0 -0
  112. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/components/TaskList.tsx +0 -0
  113. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/components/TaskStateBadge.tsx +0 -0
  114. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/components/TaskTimeline.tsx +0 -0
  115. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/components/Tooltip.tsx +0 -0
  116. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/hooks/WebSocketContext.tsx +0 -0
  117. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/hooks/useInfiniteScroll.ts +0 -0
  118. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/index.css +0 -0
  119. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/main.tsx +0 -0
  120. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/routes/graph.$rootId.tsx +0 -0
  121. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/routes/graphs.tsx +0 -0
  122. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/routes/index.tsx +0 -0
  123. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/routes/registry.tsx +0 -0
  124. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/routes/tasks.$taskId.tsx +0 -0
  125. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/routes/workers.tsx +0 -0
  126. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/utils/format.ts +0 -0
  127. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/src/vite-env.d.ts +0 -0
  128. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/tests/fixtures/mock-api.ts +0 -0
  129. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/tests/fixtures/mock-data.ts +0 -0
  130. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/tests/graphs.spec.ts +0 -0
  131. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/tests/registry.spec.ts +0 -0
  132. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/tests/task-detail.spec.ts +0 -0
  133. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/tests/tasks.spec.ts +0 -0
  134. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/tests/workers.spec.ts +0 -0
  135. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/tsconfig.json +0 -0
  136. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/tsconfig.tsbuildinfo +0 -0
  137. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/ui/frontend/vite.config.ts +0 -0
  138. {stemtrace-0.3.4 → stemtrace-0.3.6}/src/stemtrace/server/websocket.py +0 -0
  139. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/__init__.py +0 -0
  140. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/e2e/__init__.py +0 -0
  141. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/e2e/conftest.py +0 -0
  142. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/e2e/tasks.py +0 -0
  143. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/e2e/test_api_e2e.py +0 -0
  144. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/e2e/test_workers_e2e.py +0 -0
  145. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/integration/__init__.py +0 -0
  146. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/integration/test_embedded_static.py +0 -0
  147. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/unit/__init__.py +0 -0
  148. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/unit/test_auth.py +0 -0
  149. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/unit/test_bootsteps.py +0 -0
  150. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/unit/test_config.py +0 -0
  151. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/unit/test_exceptions.py +0 -0
  152. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/unit/test_form_auth.py +0 -0
  153. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/unit/test_init.py +0 -0
  154. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/unit/test_scrubbing.py +0 -0
  155. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/unit/test_signals.py +0 -0
  156. {stemtrace-0.3.4 → stemtrace-0.3.6}/tests/unit/test_ui_static_prefix.py +0 -0
@@ -1,5 +1,5 @@
1
1
  [tool.bumpversion]
2
- current_version = "0.3.4"
2
+ current_version = "0.3.6"
3
3
  parse = "(?P<major>\\d+)\\.(?P<minor>\\d+)\\.(?P<patch>\\d+)"
4
4
  serialize = ["{major}.{minor}.{patch}"]
5
5
  commit = true
@@ -1,6 +1,7 @@
1
1
  version: 2
2
2
  updates:
3
- - package-ecosystem: pip
3
+ # Python dependencies: pyproject.toml + uv.lock (CI and images install from the lock)
4
+ - package-ecosystem: uv
4
5
  directory: /
5
6
  schedule:
6
7
  interval: weekly
@@ -20,3 +21,11 @@ updates:
20
21
  interval: weekly
21
22
  commit-message:
22
23
  prefix: "chore(deps)"
24
+
25
+ # Base images in Dockerfile and Dockerfile.e2e (tags pinned by digest)
26
+ - package-ecosystem: docker
27
+ directory: /
28
+ schedule:
29
+ interval: weekly
30
+ commit-message:
31
+ prefix: "chore(deps)"
@@ -0,0 +1,230 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [main]
6
+ push:
7
+ branches: [main]
8
+ workflow_dispatch:
9
+
10
+ concurrency:
11
+ group: ${{ github.workflow }}-${{ github.ref }}
12
+ cancel-in-progress: true
13
+
14
+ jobs:
15
+ lint:
16
+ if: github.event_name == 'pull_request'
17
+ runs-on: ubuntu-latest
18
+ env:
19
+ UV_PYTHON: "3.12"
20
+ STEMTRACE_SKIP_UI_BUILD: "1"
21
+ steps:
22
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
23
+
24
+ - name: Set up Python
25
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
26
+ with:
27
+ python-version: "3.12"
28
+
29
+ - name: Install uv
30
+ uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
31
+ with:
32
+ enable-cache: true
33
+
34
+ - name: Install dependencies
35
+ run: uv sync --locked --no-build --all-extras
36
+
37
+ - name: Lint with ruff
38
+ run: uv run --locked --no-build ruff check src/ tests/
39
+
40
+ - name: Check formatting
41
+ run: uv run --locked --no-build ruff format --check src/ tests/
42
+
43
+ type-check:
44
+ if: github.event_name == 'pull_request'
45
+ runs-on: ubuntu-latest
46
+ env:
47
+ UV_PYTHON: "3.12"
48
+ STEMTRACE_SKIP_UI_BUILD: "1"
49
+ steps:
50
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
51
+
52
+ - name: Set up Python
53
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
54
+ with:
55
+ python-version: "3.12"
56
+
57
+ - name: Install uv
58
+ uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
59
+ with:
60
+ enable-cache: true
61
+
62
+ - name: Install dependencies
63
+ run: uv sync --locked --no-build --all-extras
64
+
65
+ - name: Type check with mypy
66
+ run: uv run --locked --no-build mypy src/ --strict
67
+
68
+ test:
69
+ if: github.event_name == 'pull_request'
70
+ runs-on: ubuntu-latest
71
+ env:
72
+ UV_PYTHON: ${{ matrix.python-version }}
73
+ STEMTRACE_SKIP_UI_BUILD: "1"
74
+ strategy:
75
+ matrix:
76
+ python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
77
+ steps:
78
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
79
+
80
+ - name: Set up Python ${{ matrix.python-version }}
81
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
82
+ with:
83
+ python-version: ${{ matrix.python-version }}
84
+
85
+ - name: Install uv
86
+ uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
87
+ with:
88
+ enable-cache: true
89
+
90
+ - name: Install dependencies
91
+ run: uv sync --locked --no-build --all-extras
92
+
93
+ - name: Run tests
94
+ run: uv run --locked --no-build pytest --cov=stemtrace --cov-branch --cov-report=xml --cov-fail-under=95
95
+
96
+ - name: Upload coverage
97
+ uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1
98
+ if: matrix.python-version == '3.12'
99
+ with:
100
+ token: ${{ secrets.CODECOV_TOKEN }}
101
+ files: ./coverage.xml
102
+ fail_ci_if_error: false
103
+
104
+ audit:
105
+ name: Audit runtime dependencies
106
+ runs-on: ubuntu-latest
107
+ env:
108
+ UV_PYTHON: "3.12"
109
+ steps:
110
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
111
+
112
+ - name: Set up Python
113
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
114
+ with:
115
+ python-version: "3.12"
116
+
117
+ - name: Install uv
118
+ uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
119
+ with:
120
+ enable-cache: true
121
+
122
+ - name: Export locked runtime dependencies
123
+ run: uv export --frozen --no-emit-project --no-dev --output-file requirements-audit.txt
124
+
125
+ - name: Audit for known vulnerabilities
126
+ run: uvx --no-build pip-audit==2.10.1 --strict --require-hashes --disable-pip -r requirements-audit.txt
127
+
128
+ frontend:
129
+ if: github.event_name == 'pull_request'
130
+ runs-on: ubuntu-latest
131
+ defaults:
132
+ run:
133
+ working-directory: src/stemtrace/server/ui/frontend
134
+ steps:
135
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
136
+
137
+ - name: Set up Node.js
138
+ uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
139
+ with:
140
+ node-version: "22"
141
+ cache: "npm"
142
+ cache-dependency-path: src/stemtrace/server/ui/frontend/package-lock.json
143
+
144
+ - name: Install dependencies
145
+ run: npm ci --ignore-scripts
146
+
147
+ - name: Lint with Biome
148
+ run: npm run check
149
+
150
+ - name: Type check with TypeScript
151
+ run: npm run typecheck
152
+
153
+ build:
154
+ if: github.event_name == 'pull_request'
155
+ runs-on: ubuntu-latest
156
+ env:
157
+ UV_PYTHON: "3.12"
158
+ needs: [lint, type-check, test, frontend]
159
+ steps:
160
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
161
+
162
+ - name: Set up Python
163
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
164
+ with:
165
+ python-version: "3.12"
166
+
167
+ - name: Install uv
168
+ uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
169
+ with:
170
+ enable-cache: true
171
+
172
+ - name: Set up Node.js
173
+ uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
174
+ with:
175
+ node-version: "22"
176
+ cache: "npm"
177
+ cache-dependency-path: src/stemtrace/server/ui/frontend/package-lock.json
178
+
179
+ - name: Install frontend dependencies
180
+ run: npm ci --ignore-scripts
181
+ working-directory: src/stemtrace/server/ui/frontend
182
+
183
+ - name: Install build tools
184
+ run: uv sync --locked --no-build --all-extras --no-install-project
185
+
186
+ - name: Build package
187
+ run: uv run --locked --no-build --no-sync pyproject-build --no-isolation
188
+
189
+ - name: Verify package
190
+ run: uv run --locked --no-build --no-sync twine check dist/*
191
+
192
+ - name: Upload dist artifacts
193
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
194
+ with:
195
+ name: dist
196
+ path: dist/
197
+
198
+ coverage-main:
199
+ # Keep PR checks as the main gate, but ensure Codecov gets updated for the
200
+ # actual default-branch commit after merges (or direct pushes / releases).
201
+ if: github.ref == 'refs/heads/main' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch')
202
+ runs-on: ubuntu-latest
203
+ env:
204
+ UV_PYTHON: "3.12"
205
+ STEMTRACE_SKIP_UI_BUILD: "1"
206
+ steps:
207
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
208
+
209
+ - name: Set up Python
210
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
211
+ with:
212
+ python-version: "3.12"
213
+
214
+ - name: Install uv
215
+ uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
216
+ with:
217
+ enable-cache: true
218
+
219
+ - name: Install dependencies
220
+ run: uv sync --locked --no-build --all-extras
221
+
222
+ - name: Run tests (coverage only)
223
+ run: uv run --locked --no-build pytest --cov=stemtrace --cov-branch --cov-report=xml --cov-fail-under=95
224
+
225
+ - name: Upload coverage (main)
226
+ uses: codecov/codecov-action@303a32d7a59b442fa8d48b6a1cc6825c09c847a5 # v7.1.1
227
+ with:
228
+ token: ${{ secrets.CODECOV_TOKEN }}
229
+ files: ./coverage.xml
230
+ fail_ci_if_error: false
@@ -12,6 +12,10 @@ jobs:
12
12
  api-e2e:
13
13
  name: API E2E Tests
14
14
  runs-on: ubuntu-latest
15
+ env:
16
+ UV_PYTHON: "3.12"
17
+ # The Docker images build their own UI; skip the host-side build.
18
+ STEMTRACE_SKIP_UI_BUILD: "1"
15
19
  timeout-minutes: 15
16
20
  strategy:
17
21
  fail-fast: false
@@ -21,10 +25,10 @@ jobs:
21
25
  - rabbitmq
22
26
 
23
27
  steps:
24
- - uses: actions/checkout@v6
28
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
25
29
 
26
30
  - name: Set up Docker Buildx
27
- uses: docker/setup-buildx-action@v4
31
+ uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
28
32
 
29
33
  - name: Select compose file and Celery env
30
34
  run: |
@@ -51,20 +55,20 @@ jobs:
51
55
  echo "Services ready!"
52
56
 
53
57
  - name: Set up Python
54
- uses: actions/setup-python@v6
58
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
55
59
  with:
56
60
  python-version: "3.12"
57
61
 
58
62
  - name: Install uv
59
- uses: astral-sh/setup-uv@v7
63
+ uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
60
64
  with:
61
65
  enable-cache: true
62
66
 
63
67
  - name: Install dependencies
64
- run: uv sync --all-extras
68
+ run: uv sync --locked --no-build --all-extras
65
69
 
66
70
  - name: Run API E2E tests
67
- run: uv run pytest tests/e2e/ -m e2e -v --tb=short
71
+ run: uv run --locked --no-build pytest tests/e2e/ -m e2e -v --tb=short
68
72
 
69
73
  - name: Show logs on failure
70
74
  if: failure()
@@ -79,6 +83,10 @@ jobs:
79
83
  playwright:
80
84
  name: Playwright E2E Tests
81
85
  runs-on: ubuntu-latest
86
+ env:
87
+ UV_PYTHON: "3.12"
88
+ # The Docker images build their own UI; skip the host-side build.
89
+ STEMTRACE_SKIP_UI_BUILD: "1"
82
90
  timeout-minutes: 20
83
91
  strategy:
84
92
  fail-fast: false
@@ -88,10 +96,10 @@ jobs:
88
96
  - rabbitmq
89
97
 
90
98
  steps:
91
- - uses: actions/checkout@v6
99
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
92
100
 
93
101
  - name: Set up Docker Buildx
94
- uses: docker/setup-buildx-action@v4
102
+ uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
95
103
 
96
104
  - name: Select compose file and Celery env
97
105
  run: |
@@ -117,22 +125,22 @@ jobs:
117
125
  echo "Services ready!"
118
126
 
119
127
  - name: Set up Python
120
- uses: actions/setup-python@v6
128
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
121
129
  with:
122
130
  python-version: "3.12"
123
131
 
124
132
  - name: Install uv
125
- uses: astral-sh/setup-uv@v7
133
+ uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
126
134
  with:
127
135
  enable-cache: true
128
136
 
129
137
  - name: Install Python dependencies
130
- run: uv sync --all-extras
138
+ run: uv sync --locked --no-build --all-extras
131
139
 
132
140
  - name: Submit test tasks
133
141
  run: |
134
142
  # Submit some tasks to populate the UI for testing
135
- uv run python -c "
143
+ uv run --locked --no-build python -c "
136
144
  from tests.e2e.tasks import add, create_workflow, always_fails
137
145
  # Submit a few tasks
138
146
  add.delay(1, 2)
@@ -145,19 +153,19 @@ jobs:
145
153
  sleep 5
146
154
 
147
155
  - name: Set up Node.js
148
- uses: actions/setup-node@v6
156
+ uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
149
157
  with:
150
- node-version: "20"
158
+ node-version: "22"
151
159
  cache: "npm"
152
160
  cache-dependency-path: src/stemtrace/server/ui/frontend/package-lock.json
153
161
 
154
162
  - name: Install frontend dependencies
155
163
  working-directory: src/stemtrace/server/ui/frontend
156
- run: npm ci
164
+ run: npm ci --ignore-scripts
157
165
 
158
166
  - name: Install Playwright browsers
159
167
  working-directory: src/stemtrace/server/ui/frontend
160
- run: npx playwright install chromium --with-deps
168
+ run: ./node_modules/.bin/playwright install chromium --with-deps
161
169
 
162
170
  - name: Run Playwright tests
163
171
  working-directory: src/stemtrace/server/ui/frontend
@@ -167,7 +175,7 @@ jobs:
167
175
  PLAYWRIGHT_BASE_URL: http://localhost:8000
168
176
 
169
177
  - name: Upload Playwright report
170
- uses: actions/upload-artifact@v7
178
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
171
179
  if: always()
172
180
  with:
173
181
  name: playwright-report-${{ matrix.broker }}
@@ -175,7 +183,7 @@ jobs:
175
183
  retention-days: 7
176
184
 
177
185
  - name: Upload test results
178
- uses: actions/upload-artifact@v7
186
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
179
187
  if: failure()
180
188
  with:
181
189
  name: playwright-test-results-${{ matrix.broker }}
@@ -18,11 +18,13 @@ env:
18
18
  jobs:
19
19
  build:
20
20
  runs-on: ubuntu-latest
21
+ env:
22
+ UV_PYTHON: "3.12"
21
23
  outputs:
22
24
  version: ${{ steps.version.outputs.version }}
23
25
  tag: ${{ steps.version.outputs.tag }}
24
26
  steps:
25
- - uses: actions/checkout@v6
27
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
26
28
 
27
29
  - name: Determine version
28
30
  id: version
@@ -49,32 +51,37 @@ jobs:
49
51
  echo "✅ Version $PYPROJECT_VERSION matches"
50
52
 
51
53
  - name: Set up Python
52
- uses: actions/setup-python@v6
54
+ uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
53
55
  with:
54
56
  python-version: "3.12"
55
57
 
56
58
  - name: Set up Node.js
57
- uses: actions/setup-node@v6
59
+ uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6.5.0
58
60
  with:
59
- node-version: "20"
61
+ node-version: "22"
60
62
  cache: "npm"
61
63
  cache-dependency-path: src/stemtrace/server/ui/frontend/package-lock.json
62
64
 
65
+ - name: Install uv
66
+ uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0
67
+ with:
68
+ enable-cache: false
69
+
63
70
  - name: Install frontend dependencies
64
- run: npm ci
71
+ run: npm ci --ignore-scripts
65
72
  working-directory: src/stemtrace/server/ui/frontend
66
73
 
67
74
  - name: Install build tools
68
- run: pip install build twine
75
+ run: uv sync --locked --no-build --all-extras --no-install-project
69
76
 
70
77
  - name: Build package
71
- run: python -m build
78
+ run: uv run --locked --no-build --no-sync pyproject-build --no-isolation
72
79
 
73
80
  - name: Verify package
74
- run: twine check dist/*
81
+ run: uv run --locked --no-build --no-sync twine check dist/*
75
82
 
76
83
  - name: Upload dist artifacts
77
- uses: actions/upload-artifact@v7
84
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
78
85
  with:
79
86
  name: dist
80
87
  path: dist/
@@ -87,13 +94,13 @@ jobs:
87
94
  id-token: write
88
95
  steps:
89
96
  - name: Download dist artifacts
90
- uses: actions/download-artifact@v8
97
+ uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
91
98
  with:
92
99
  name: dist
93
100
  path: dist/
94
101
 
95
102
  - name: Publish to PyPI
96
- uses: pypa/gh-action-pypi-publish@release/v1
103
+ uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
97
104
 
98
105
  docker:
99
106
  needs: build
@@ -102,16 +109,16 @@ jobs:
102
109
  contents: read
103
110
  packages: write
104
111
  steps:
105
- - uses: actions/checkout@v6
112
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
106
113
 
107
114
  - name: Set up QEMU
108
- uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3
115
+ uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0
109
116
 
110
117
  - name: Set up Docker Buildx
111
- uses: docker/setup-buildx-action@v4
118
+ uses: docker/setup-buildx-action@f87e5991a6d7451dcb8d9637bfbc97413f497069 # v4.4.1
112
119
 
113
120
  - name: Log in to GitHub Container Registry
114
- uses: docker/login-action@v3
121
+ uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0
115
122
  with:
116
123
  registry: ghcr.io
117
124
  username: ${{ github.actor }}
@@ -119,7 +126,7 @@ jobs:
119
126
 
120
127
  - name: Extract metadata
121
128
  id: meta
122
- uses: docker/metadata-action@v6
129
+ uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
123
130
  with:
124
131
  images: ghcr.io/${{ github.repository }}
125
132
  tags: |
@@ -127,7 +134,7 @@ jobs:
127
134
  type=raw,value=latest
128
135
 
129
136
  - name: Build and push Docker image
130
- uses: docker/build-push-action@v7
137
+ uses: docker/build-push-action@c3c9e263c25d99ce0380d002d59b67737d91b0dc # v7.4.0
131
138
  with:
132
139
  context: .
133
140
  push: true
@@ -143,10 +150,10 @@ jobs:
143
150
  permissions:
144
151
  contents: write
145
152
  steps:
146
- - uses: actions/checkout@v6
153
+ - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6.1.0
147
154
 
148
155
  - name: Download dist artifacts
149
- uses: actions/download-artifact@v8
156
+ uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
150
157
  with:
151
158
  name: dist
152
159
  path: dist/
@@ -160,7 +167,7 @@ jobs:
160
167
  git push origin "${{ needs.build.outputs.tag }}"
161
168
 
162
169
  - name: Create GitHub Release
163
- uses: softprops/action-gh-release@v2
170
+ uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3
164
171
  with:
165
172
  tag_name: ${{ needs.build.outputs.tag }}
166
173
  generate_release_notes: true