Dash0 Raises $110M Series B at $1B Valuation

Last updated: July 27, 2026

Manage CI/CD Observability as Code

Add OpenTelemetry observability to your CI/CD pipelines with the Dash0 GitHub Action.

This GitHub Action automatically instruments your CI/CD pipelines with OpenTelemetry, sending traces and metrics to Dash0.

For other "as code" approaches, see the Manage as Code overview.

This action exports Github CI/CD workflows to any endpoint compatible with OpenTelemetry.

This is a fork of otel-export-trace-action with more features and better support. Originally created and maintained by Corentin Musard, now maintained by Dash0.

Compliant with OpenTelemetry CICD semconv. Look at Sample OpenTelemetry Output for the list of attributes and their values.

Example trace in Dash0 showing CI/CD workflow execution

Usage

We provide sample code for popular platforms. If you feel one is missing, please open an issue.

Code SampleFile
Inside an existing workflowbuild.yml
From a private repositoryprivate.yml
Dash0dash0.yml

On workflow_run event

workflow_run github documentation

yaml
1234567891011121314151617
on:
workflow_run:
workflows:
# The name of the workflow(s) that triggers the export
- "Build"
types: [completed]
jobs:
otel-cicd-actions:
runs-on: ubuntu-latest
steps:
- uses: dash0hq/otel-cicd-action@v4
with:
otlpEndpoint: grpc://ingress.eu-west-1.aws.dash0.com:4317
otlpHeaders: ${{ secrets.OTLP_HEADERS }}
githubToken: ${{ secrets.GITHUB_TOKEN }}
runId: ${{ github.event.workflow_run.id }}

Inside an existing workflow

yaml
123456789101112131415
jobs:
build:
# ... existing code
otel-cicd-action:
if: always()
name: OpenTelemetry Export Trace
runs-on: ubuntu-latest
needs: [build] # must run when all jobs are completed
steps:
- name: Export workflow
uses: dash0hq/otel-cicd-action@v4
with:
otlpEndpoint: grpc://ingress.eu-west-1.aws.dash0.com:4317
otlpHeaders: ${{ secrets.OTLP_HEADERS }}
githubToken: ${{ secrets.GITHUB_TOKEN }}

On workflow_run event vs Inside an existing workflow

Both methods must be run when the workflow is completed, otherwise, the trace will be incomplete.

DifferencesOn workflow_run eventInside an existing workflow
Shows in PR pageNoYes
Shows in Actions tabYesYes
Needs extra consideration to be run as the last jobNoYes
Must be duplicated for multiple workflowsNoYes

Private Repository

If you are using a private repository, you need to set the following permissions in your workflow file. It can be done at the global level or at the job level.

yaml
12345
permissions:
contents: read # Required. To access the private repository
actions: read # Required. To read workflow runs
pull-requests: read # Optional. To read PR labels
checks: read # Optional. To read run annotations

Adding arbitrary resource attributes

You can use extraAttributes to set any additional string resource attributes. Attributes are splitted on , and then each key/value are splitted on the first =.

yaml
1234567
- name: Export workflow
uses: dash0hq/otel-cicd-action@v4
with:
otlpEndpoint: "CHANGE ME"
otlpHeaders: "CHANGE ME"
githubToken: ${{ secrets.GITHUB_TOKEN }}
extraAttributes: "extra.attribute=1,key2=value2"

Using a self-signed certificate

When an internal OTLP endpoint uses a self-signed certificate and its certificate authority cannot be added to the runner's trust store, set otlpInsecureSkipVerify to true:

yaml
1234567
- name: Export workflow
uses: dash0hq/otel-cicd-action@v4
with:
otlpEndpoint: grpc://otlp.example.com:4317
otlpHeaders: "CHANGE ME"
githubToken: ${{ secrets.GITHUB_TOKEN }}
otlpInsecureSkipVerify: true

This disables certificate verification for the OTLP exporter connection and makes it vulnerable to man-in-the-middle attacks. Only use it with a trusted internal endpoint.

Action Inputs

namedescriptionrequireddefaultexample
otlpEndpointThe destination endpoint to export OpenTelemetry traces to. It supports https://, http:// and grpc:// endpoints.truehttps://ingress.eu-west-1.aws.dash0.com/v1/traces
otlpHeadersHeaders to add to the OpenTelemetry exporter.trueAuthorization=Bearer YOUR_AUTH_TOKEN,Dash0-Dataset=YOUR_DATASET
otelServiceNameOpenTelemetry service namefalse<The name of the exported workflow>Build CI
githubTokenThe repository token with Workflow permissions. Required for private reposfalse${{ secrets.GITHUB_TOKEN }}
runIdWorkflow Run ID to Exportfalseenv.GITHUB_RUN_ID${{ github.event.workflow_run.id }}
extraAttributesExtra resource attributes to add to each spanfalseextra.attribute=1,key2=value2
otlpInsecureSkipVerifyDisable TLS certificate verification for the OTLP exporter. Only use this with trusted endpoints.falsefalsetrue

Action Outputs

namedescription
traceIdThe OpenTelemetry Trace ID of the root span

What data is exported

The action exports the workflow run metadata returned by the GitHub API as span attributes, without redaction. There is currently no way to opt out of individual attributes, so make sure your telemetry backend is an acceptable place for this data. In particular, be aware that:

  • Commit metadata is included: the full commit message, plus author and committer names and email addresses (github.head_commit.*).
  • Job annotations and PR metadata are included when the token has the optional checks: read and pull-requests: read permissions: annotation messages, PR numbers, branch names, and labels.
  • service.instance.id is unique per run attempt (<repo>/<workflow id>/<run id>/<attempt>), so each workflow run appears as its own service instance. Backends that bill or aggregate by service instance will see one instance per run.

See the Sample OpenTelemetry Output for the full list of exported attributes and example values.