Last updated: July 27, 2026
Manage CI/CD Observability as Code
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.
Usage
We provide sample code for popular platforms. If you feel one is missing, please open an issue.
| Code Sample | File |
|---|---|
| Inside an existing workflow | build.yml |
| From a private repository | private.yml |
| Dash0 | dash0.yml |
On workflow_run event
workflow_run github documentation
1234567891011121314151617on:workflow_run:workflows:# The name of the workflow(s) that triggers the export- "Build"types: [completed]jobs:otel-cicd-actions:runs-on: ubuntu-lateststeps:- uses: dash0hq/otel-cicd-action@v4with:otlpEndpoint: grpc://ingress.eu-west-1.aws.dash0.com:4317otlpHeaders: ${{ secrets.OTLP_HEADERS }}githubToken: ${{ secrets.GITHUB_TOKEN }}runId: ${{ github.event.workflow_run.id }}
Inside an existing workflow
123456789101112131415jobs:build:# ... existing codeotel-cicd-action:if: always()name: OpenTelemetry Export Traceruns-on: ubuntu-latestneeds: [build] # must run when all jobs are completedsteps:- name: Export workflowuses: dash0hq/otel-cicd-action@v4with:otlpEndpoint: grpc://ingress.eu-west-1.aws.dash0.com:4317otlpHeaders: ${{ 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.
| Differences | On workflow_run event | Inside an existing workflow |
|---|---|---|
| Shows in PR page | No | Yes |
| Shows in Actions tab | Yes | Yes |
| Needs extra consideration to be run as the last job | No | Yes |
| Must be duplicated for multiple workflows | No | Yes |
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.
12345permissions:contents: read # Required. To access the private repositoryactions: read # Required. To read workflow runspull-requests: read # Optional. To read PR labelschecks: 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 =.
1234567- name: Export workflowuses: dash0hq/otel-cicd-action@v4with: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:
1234567- name: Export workflowuses: dash0hq/otel-cicd-action@v4with:otlpEndpoint: grpc://otlp.example.com:4317otlpHeaders: "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
| name | description | required | default | example |
|---|---|---|---|---|
| otlpEndpoint | The destination endpoint to export OpenTelemetry traces to. It supports https://, http:// and grpc:// endpoints. | true | https://ingress.eu-west-1.aws.dash0.com/v1/traces | |
| otlpHeaders | Headers to add to the OpenTelemetry exporter. | true | Authorization=Bearer YOUR_AUTH_TOKEN,Dash0-Dataset=YOUR_DATASET | |
| otelServiceName | OpenTelemetry service name | false | <The name of the exported workflow> | Build CI |
| githubToken | The repository token with Workflow permissions. Required for private repos | false | ${{ secrets.GITHUB_TOKEN }} | |
| runId | Workflow Run ID to Export | false | env.GITHUB_RUN_ID | ${{ github.event.workflow_run.id }} |
| extraAttributes | Extra resource attributes to add to each span | false | extra.attribute=1,key2=value2 | |
| otlpInsecureSkipVerify | Disable TLS certificate verification for the OTLP exporter. Only use this with trusted endpoints. | false | false | true |
Action Outputs
| name | description |
|---|---|
| traceId | The 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: readandpull-requests: readpermissions: annotation messages, PR numbers, branch names, and labels. service.instance.idis 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.
