Skip to content

[otel-advisor] OTel improvement: add github.actions.run_url resource attribute to all spans #24690

@github-actions

Description

@github-actions

📡 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

  • In actions/setup/js/send_otlp_span.cjs, read GITHUB_SERVER_URL in sendJobSetupSpan (around line 369) and append github.actions.run_url to resourceAttributes (around line 388) when both repository and runId are non-empty.
  • Apply the same change in sendJobConclusionSpan (around line 505 for variable reads, line 550 for resourceAttributes construction).
  • Update actions/setup/js/send_otlp_span.test.cjs: add assertions that github.actions.run_url appears in the resource attributes of both setup and conclusion span payloads, and that it correctly uses GITHUB_SERVER_URL when set.
  • Run make test-unit (or cd actions/setup/js && npx vitest run) to confirm tests pass.
  • Run make fmt to ensure formatting.
  • Open a PR referencing this issue.

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 ·

  • expires on Apr 12, 2026, 8:55 AM UTC

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions