Repository navigation
feat: add CI Golden Signals counters, billable metrics, and queryable queue spans - #6
Conversation
There was a problem hiding this comment.
Code Review
This pull request migrates OpenTelemetry metrics from Gauges to Counters to support cleaner aggregation, introduces several new workflow and job metrics (such as billable time and rounding waste), and adds structured trace attributes with a span.type discriminator. Feedback on these changes highlights a critical issue with the re-run filtering logic, where filtering single jobs in toWorkflowJob incorrectly excludes successful jobs from previous attempts; deduplicating jobs at the collection level is recommended instead. Additionally, since OpenTelemetry Counters are monotonic, job and workflow durations must be guarded with Math.max(0, ...) to prevent negative values caused by GitHub API timing anomalies.
There was a problem hiding this comment.
🟡 Changes recommended
Cross-invocation aggregation and runner billing and architecture calculations still produce inaccurate telemetry.
3 open issues
What changed in this PR
This PR expands the action’s OpenTelemetry output with attempt-scoped CI metrics, billable-time estimates, and queryable queue spans.
Changes:
- Replaces gauges with counters for workflow/job counts, durations, and billing totals.
- Adds paginated job collection and attempt filtering to avoid repeating earlier work on partial reruns.
- Enriches trace attributes and updates tests, documentation, output validation, and the packaged action.
| File | Description |
|---|---|
src/utils/calc-billable.ts |
Adds runner detection and billable-time calculations. |
src/utils/calc-billable.test.ts |
Tests runner inference, rounding, and multipliers. |
src/traces/create-trace.test.ts |
Verifies attempt timing and layered span attributes. |
src/traces/create-spans.ts |
Adds queue spans, attempt attributes, and workflow rollups. |
src/traces/create-spans.test.ts |
Covers negative queue-duration handling. |
src/metrics/create-metrics.ts |
Switches metric creation to counters. |
src/metrics/create-metrics.test.ts |
Verifies counter values and telemetry attributes. |
src/metrics/create-gauges.ts |
Removes the gauge implementation. |
src/metrics/create-counters.ts |
Implements workflow and job counters. |
src/metrics/create-counters.test.ts |
Tests counter export and duration safeguards. |
src/metrics/constants.ts |
Defines new metrics and attribute keys. |
src/main.test.ts |
Updates fixtures with attempt metadata. |
src/github/types.ts |
Preserves runner labels, attempts, events, and step numbers. |
src/github/github.ts |
Adds pagination, attempt filtering, and start-time fallback. |
src/github/github.test.ts |
Tests attempt selection and metadata conversion. |
README.md |
Documents counters, trace attributes, and rerun behavior. |
docs/specification.md |
Updates metric and trace specifications. |
dist/index.js |
Packages the updated action implementation. |
badges/coverage.svg |
Updates reported coverage to 97.84%. |
.github/workflows/validate-action-output.yml |
Normalizes counter output and new span attributes. |
Review effort: Balanced
7a53d51 to
4de6ffe
Compare
… queue spans Replace Gauges with Counters across workflow and job metrics, add billable-minute and rounding-waste calculations with OS multiplier and CPU architecture detection, filter out prior run_attempt jobs on partial re-runs, and add span.type layer separation and static job.queue spans to traces.
Update trace and metric golden outputs for the new span layers and counter schema. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Collect workflow jobs across attempts and select the latest result per job through the target attempt. Clamp negative metric and trace durations to preserve nonnegative telemetry. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
c47256c to
ba9cc36
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request transitions the telemetry metrics from Gauges to Counters and introduces structured attributes with a span.type discriminator to prevent double-counting in traces. It also implements logic to filter out reused jobs from previous attempts during workflow reruns and adds utilities to calculate billable minutes and rounding waste. Feedback on the changes highlights a logical bug where falling back to the earliest job creation time when run_started_at is missing fails to filter out reused jobs, as well as a potential TypeScript type mismatch if job.labels is null.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Materialize the current workflow event in expected output and refresh stale push-event telemetry data.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
The first-attempt fallback cutoff can discard valid completed jobs with anomalous timestamps, losing execution and billing telemetry and potentially causing collection to fail.
1 open issue
3 resolved since last review
Review effort: Balanced
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Summary
Adds OpenTelemetry metrics and traces for GitHub workflow attempts. Telemetry is scoped to work performed in each attempt: partial reruns omit jobs that succeeded earlier, while jobs actually rerun are counted again.
github.workflow.runscounts every collected attempt inworkflow_runmode, including partial reruns; current-workflow mode counts only attempts where the telemetry job runs.Metric points include
workflow.run_idandworkflow.run_attempt, so independent runs and attempts use separate metric series. The default OTLP exporter uses cumulative temporality. To calculate totals by workflow, sum per-attempt points over the desired time range byworkflow.name, dropping run, attempt, outcome, and event dimensions. Keeprepositorywhen totals should remain separate across repositories.Key Changes
1. Workflow and job metrics
-largeisamd64and-xlargeisarm64.2. Attempt-scoped collection
run_attempt, excluding jobs retained from earlier attempts while preserving all jobs in the selected attempt, including matrix jobs with duplicate names.run_started_atfor workflow duration, falling back to the earliest selected job creation time.workflow.run_idandworkflow.run_attempton metric points so independent cumulative streams do not collide; aggregate by workflow name for totals.3. Attempt-aware traces
job.id.job.queue, with wrapper spans retained for a collapsible waterfall without duplicating job cost attributes.Test Plan
npm run all— formatting, ESLint, strict TypeScript, 12 Vitest suites / 135 tests, 97.88% statement coverage, anddist/index.jspackaging.github.workflow.runsvalues sum to 2.-large/-xlargearchitecture cases are covered.main; that integration run remains unverified.