📡 OTel Instrumentation Improvement: Add github.actions.run_url to all spans
Analysis Date: 2026-04-05
Priority: High
Effort: Small (< 2h)
Problem
Both sendJobSetupSpan and sendJobConclusionSpan include github.repository and github.run_id as resource attributes but never add a precomputed github.actions.run_url. Engineers debugging a failed workflow in Honeycomb, Grafana Tempo, or Datadog must mentally assemble https://<server>/<repo>/actions/runs/<id> from three separate fields — a manual step that is slow during incidents and completely breaks on GitHub Enterprise Server where the server origin is not https://github.com.
The URL pattern is already first-class in the rest of the codebase: workflow_metadata_helpers.cjs exports buildWorkflowRunUrl (which correctly reads GITHUB_SERVER_URL) and it is wired into message footers, PR comments, and missing-issue helpers — but it is never called from the OTLP instrumentation path.
Why This Matters (DevOps Perspective)
- MTTR: A clickable
github.actions.run_url attribute in the trace backend lets an on-call engineer jump directly from a failing span to the GitHub Actions log in one click, shaving minutes off incident response.
- Dashboards: Both Grafana and Honeycomb support rendering attribute values as hyperlinks. Without a pre-built URL attribute, this is impossible to configure.
- GHES compatibility: On GitHub Enterprise Server,
GITHUB_SERVER_URL is not https://github.com. Hardcoding the domain (or requiring engineers to do so in dashboards) makes the telemetry wrong for every GHES installation.
- OTel alignment: The emerging [OTel CI/CD semantic conventions]((opentelemetry.io/redacted) name this attribute
cicd.pipeline.run.url_full. Adding github.actions.run_url now is a low-risk step toward that standard.
Current Behavior
Neither span sender reads GITHUB_SERVER_URL, and neither adds a run URL attribute:
// Current: actions/setup/js/send_otlp_span.cjs (lines 388–391)
const resourceAttributes = [
buildAttr("github.repository", repository),
buildAttr("github.run_id", runId),
];
// github.event_name added conditionally — but no run URL ever.
The same pattern repeats in the conclusion path (lines 550–553). workflow_metadata_helpers.cjs already has the right helper:
// actions/setup/js/workflow_metadata_helpers.cjs (lines 39–44) — NOT called from OTLP path
function buildWorkflowRunUrl(ctx, workflowRepo) {
const server = ctx.serverUrl || process.env.GITHUB_SERVER_URL || "https://github.com";
const { owner, repo } = workflowRepo;
return `${server}/${owner}/${repo}/actions/runs/${ctx.runId}`;
}
Proposed Change
Add github.actions.run_url to the resource attributes in both sendJobSetupSpan and sendJobConclusionSpan, using the same GITHUB_SERVER_URL fallback pattern already established in the codebase:
// Proposed addition to actions/setup/js/send_otlp_span.cjs
// Applied in BOTH sendJobSetupSpan (around line 388) and sendJobConclusionSpan (around line 550)
const serverUrl = process.env.GITHUB_SERVER_URL || "https://github.com";
const resourceAttributes = [
buildAttr("github.repository", repository),
buildAttr("github.run_id", runId),
];
if (repository && runId) {
resourceAttributes.push(
buildAttr("github.actions.run_url", `${serverUrl}/${repository}/actions/runs/${runId}`)
);
}
if (eventName) {
resourceAttributes.push(buildAttr("github.event_name", eventName));
}
No new dependency is needed — GITHUB_SERVER_URL is a standard GitHub Actions environment variable available in every job.
Expected Outcome
After this change:
- In Grafana / Honeycomb / Datadog: Spans will carry a
github.actions.run_url attribute that can be rendered as a clickable hyperlink in trace detail panels and configured as a column in trace list views — enabling 1-click navigation from a failed span to the GitHub Actions log.
- In the JSONL mirror (
/tmp/gh-aw/otel.jsonl): Every mirrored span entry will contain the full run URL, making post-hoc artifact inspection self-contained (no need to reconstruct the URL from other fields).
- For on-call engineers: Incident response time decreases because the first action ("open the failed run") no longer requires mental URL assembly or dashboard pivoting.
- For GHES installations: The URL will correctly use the enterprise server hostname instead of
https://github.com.
Implementation Steps
Evidence from Live Sentry Data
⚠️ The Sentry MCP tool was not available in this workflow run, so live span payload inspection could not be performed. The gap is confirmed via static code analysis: neither sendJobSetupSpan nor sendJobConclusionSpan reads GITHUB_SERVER_URL or constructs a run URL, and neither passes a URL-shaped attribute into buildOTLPPayload. The presence of github.repository and github.run_id in live spans (confirmed in code at lines 388 and 550) makes the absence of github.actions.run_url a confirmed gap that can be reconstructed by any reader of the OTLP payload — but only at the cost of manual effort and with incorrect results on GHES.
Related Files
actions/setup/js/send_otlp_span.cjs — primary change location (both sendJobSetupSpan and sendJobConclusionSpan)
actions/setup/js/send_otlp_span.test.cjs — test assertions to add
actions/setup/js/workflow_metadata_helpers.cjs — reference implementation of buildWorkflowRunUrl (same GITHUB_SERVER_URL pattern to follow)
actions/setup/js/action_setup_otlp.cjs — no change needed (delegates to sendJobSetupSpan)
actions/setup/js/action_conclusion_otlp.cjs — no change needed (delegates to sendJobConclusionSpan)
Generated by the Daily OTel Instrumentation Advisor workflow
Generated by Daily OTel Instrumentation Advisor · ● 145.7K · ◷
📡 OTel Instrumentation Improvement: Add
github.actions.run_urlto all spansAnalysis Date: 2026-04-05
Priority: High
Effort: Small (< 2h)
Problem
Both
sendJobSetupSpanandsendJobConclusionSpanincludegithub.repositoryandgithub.run_idas resource attributes but never add a precomputedgithub.actions.run_url. Engineers debugging a failed workflow in Honeycomb, Grafana Tempo, or Datadog must mentally assemblehttps://<server>/<repo>/actions/runs/<id>from three separate fields — a manual step that is slow during incidents and completely breaks on GitHub Enterprise Server where the server origin is nothttps://github.bokerqi.top.The URL pattern is already first-class in the rest of the codebase:
workflow_metadata_helpers.cjsexportsbuildWorkflowRunUrl(which correctly readsGITHUB_SERVER_URL) and it is wired into message footers, PR comments, and missing-issue helpers — but it is never called from the OTLP instrumentation path.Why This Matters (DevOps Perspective)
github.actions.run_urlattribute in the trace backend lets an on-call engineer jump directly from a failing span to the GitHub Actions log in one click, shaving minutes off incident response.GITHUB_SERVER_URLis nothttps://github.com. Hardcoding the domain (or requiring engineers to do so in dashboards) makes the telemetry wrong for every GHES installation.cicd.pipeline.run.url_full. Addinggithub.actions.run_urlnow is a low-risk step toward that standard.Current Behavior
Neither span sender reads
GITHUB_SERVER_URL, and neither adds a run URL attribute:The same pattern repeats in the conclusion path (lines 550–553).
workflow_metadata_helpers.cjsalready has the right helper:Proposed Change
Add
github.actions.run_urlto the resource attributes in bothsendJobSetupSpanandsendJobConclusionSpan, using the sameGITHUB_SERVER_URLfallback pattern already established in the codebase:No new dependency is needed —
GITHUB_SERVER_URLis a standard GitHub Actions environment variable available in every job.Expected Outcome
After this change:
github.actions.run_urlattribute that can be rendered as a clickable hyperlink in trace detail panels and configured as a column in trace list views — enabling 1-click navigation from a failed span to the GitHub Actions log./tmp/gh-aw/otel.jsonl): Every mirrored span entry will contain the full run URL, making post-hoc artifact inspection self-contained (no need to reconstruct the URL from other fields).https://github.bokerqi.top.Implementation Steps
actions/setup/js/send_otlp_span.cjs, readGITHUB_SERVER_URLinsendJobSetupSpan(around line 369) and appendgithub.actions.run_urltoresourceAttributes(around line 388) when bothrepositoryandrunIdare non-empty.sendJobConclusionSpan(around line 505 for variable reads, line 550 forresourceAttributesconstruction).actions/setup/js/send_otlp_span.test.cjs: add assertions thatgithub.actions.run_urlappears in the resource attributes of both setup and conclusion span payloads, and that it correctly usesGITHUB_SERVER_URLwhen set.make test-unit(orcd actions/setup/js && npx vitest run) to confirm tests pass.make fmtto ensure formatting.Evidence from Live Sentry Data
Related Files
actions/setup/js/send_otlp_span.cjs— primary change location (bothsendJobSetupSpanandsendJobConclusionSpan)actions/setup/js/send_otlp_span.test.cjs— test assertions to addactions/setup/js/workflow_metadata_helpers.cjs— reference implementation ofbuildWorkflowRunUrl(sameGITHUB_SERVER_URLpattern to follow)actions/setup/js/action_setup_otlp.cjs— no change needed (delegates tosendJobSetupSpan)actions/setup/js/action_conclusion_otlp.cjs— no change needed (delegates tosendJobConclusionSpan)Generated by the Daily OTel Instrumentation Advisor workflow