Repository navigation
feat(ci-traces): failure reasons, runner wait spans, stable step names - #1474
Confidence 9/10 · No issues found
🟢 Confidence 9/10 · safe to merge
One info-level regex edge case; the wait span, failure reason and repo-URL paths each have a test that pins them.
quality 98/100 · 1 note · tests covered · risk low · 1/1 new units observable
Reads a failed job's GitHub check-run annotations for a failure reason, adds a "Waiting for a runner" child span, and normalizes step names, following the OTel CI/CD span conventions. One narrow step-name edge case; otherwise safe to merge.
workflowJobToOtlpsets the job status message from the best annotation- A
Waiting for a runnerchild span spansqueuedAttostartedAt - Run spans are SERVER
RUN {workflow}; steps get their own task ids fetchWorkflowJobAnnotationsreads check-run annotations, bounded and timed out
Findings
🔵 Note · F4 · ciStepName strips @ + hex runs that are not action pins
correctness · packages/backend/src/services/integrations/ci-traces/otlp.ts:93
The regex removes any @ followed by 7 to 40 hex characters, so a step named Run notify ops@deadbeef.example.com becomes Run notify ops.example.com in both the span name and cicd.pipeline.task.name (verified with node on the head). Requiring whitespace, an opening paren or the end of the name after the pin keeps the intended normalization and spares such names.
const ciStepName = (name: string) => name.replace(/@[0-9a-f]{7,40}(?=[\s(]|$)/g, "")
Fixed since the last review
- ✅
F3 ·repositoryUrlOfreturns the wrong repo URL when a path segment isactions
Production impact
Production traffic of the changed files (last 7 days)
| File | Calls/day | Busiest operations |
|---|---|---|
packages/backend/src/services/integrations/vcs/VcsSyncService.ts |
7.4k | VcsSyncService.processMessage 7.3k/day, 0.0% errVcsSyncService.handleWorkflowJob 95/day, 0.0% err |
Telemetry this change adds and removes (8)
- ➕ attribute
maple.cicd.job.name·packages/backend/src/services/integrations/ci-traces/otlp.ts:270 - ➕ attribute
maple.cicd.annotation.level·packages/backend/src/services/integrations/ci-traces/otlp.ts:312 - ➕ attribute
maple.cicd.annotation.title·packages/backend/src/services/integrations/ci-traces/otlp.ts:313 - ➕ attribute
maple.cicd.annotation.message·packages/backend/src/services/integrations/ci-traces/otlp.ts:314 - ➕ attribute
vcs.workflow.annotations_error·packages/backend/src/services/integrations/vcs/VcsSyncService.ts:916 - ➕ attribute
vcs.workflow.annotation_count·packages/backend/src/services/integrations/vcs/VcsSyncService.ts:921 - ➕ span name
GithubAppClient.listCheckRunAnnotations·packages/backend/src/services/integrations/vcs/vendor/github/GithubAppClient.ts:1877 - ➕ span name
GithubProvider.fetchWorkflowJobAnnotations·packages/backend/src/services/integrations/vcs/vendor/github/GithubProvider.ts:1737
What was checked
repositoryUrlOfnow cuts at the last/actions/runs/, soocto/actionskeeps its full URL (otlp.ts:181, testCiTraceService.test.ts:295)- Annotation events cap at 20, failures first (
otlp.ts:303), matching the docs text - A job that never started gets no wait span and no length: the
startedAtMs === completedAtMsguard (otlp.ts:257, testCiTraceService.test.ts:372)
Observability coverage: 1 of 1 changes observable
| Change | Kind | Observable | Evidence |
|---|---|---|---|
| GitHub check-run annotations read, one per failed CI job | client | yes | GithubProvider.fetchWorkflowJobAnnotations span with cicd.pipeline.task.run.id (GithubProvider.ts:1737), bounded to 3 pages and a 10s budget annotated on the handler span (VcsSyncService.ts:910) |
c028fb0 · Updated on every push. Reply "won't fix" to dismiss a finding, or mention @maple-review-bot to ask about one.
Annotations
Check notice on line 93 in packages/backend/src/services/integrations/ci-traces/otlp.ts
maple-review-bot / Maple / review
correctness: `ciStepName` strips `@` + hex runs that are not action pins
The regex removes any `@` followed by 7 to 40 hex characters, so a step named `Run notify ops@deadbeef.example.com` becomes `Run notify ops.example.com` in both the span name and `cicd.pipeline.task.name` (verified with node on the head). Requiring whitespace, an opening paren or the end of the name after the pin keeps the intended normalization and spares such names.