Scores the observability of your entry points with evlog map and puts the findings where the review happens: a check run with annotations on the diff, a job summary, and one comment that stays up to date.
name: observability
on: pull_request
permissions:
contents: read
checks: write
pull-requests: write
jobs:
map:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: evloghq/action@v1
with:
min-score: 80That is the whole setup. On a pull request the action scans the base branch too, so a check that used to pass and no longer does fails the job, is named in the comment with the score it cost, and is drawn on the entry point that lost it. Nothing has to be committed, no token has to be created: the check run and the comment use the workflow's own token.
- Runs
evlog mapon each package with the pinned@evlog/cli. - On a pull request, checks the base out next to the workspace, scans it, and compares.
- Creates a check run named
evlog mapon the commit, with the report as its summary and one annotation per finding: regressions, as failures, when there is a base; the report's FIX FIRST list, as warnings, when there is not. Withoutchecks: writethe same findings go out as workflow commands, capped atlimitper package. - Writes the report to the job summary, with every entry point and the result of each check per package.
- Posts the report as a pull request comment and edits it on every run: the score in the title, what moved in a GitHub alert block, the table only for a monorepo, and a
min-scoreto adopt when none is set. - Sets outputs (
score,delta,regressions,passed,results) for whatever comes next. - Fails the step when a package regressed or scored under
min-score, unlessgate: false.
The judgment is the CLI's. The action adds no rule of its own, so npx evlog map on your machine and the action on your pull request agree.
| Input | Default | What it does |
|---|---|---|
version |
0.8.0 |
@evlog/cli version to run, or a full spec. Defaults to the release this action was tested with; latest follows npm. |
working-directory |
. |
Project to scan, relative to the workspace. |
packages |
One directory or glob per line (apps/*), each scanned as its own package. |
|
baseline |
auto |
auto scans the pull request base and compares against it. A path or git:<ref> is passed to the CLI. none disables the comparison. |
min-score |
Fail when a package scores below this number. | |
limit |
10 |
Most annotations per package when findings fall back to workflow commands; GitHub keeps ten per level per step. A check run has no cap. |
gate |
true |
false reports and sets outputs without failing the step. |
annotations |
true |
Draw findings on the diff through a check run named evlog map. Needs checks: write; falls back to workflow commands without it. |
summary |
true |
Write the report to the job summary. |
comment |
true |
true posts one comment and keeps it updated; on-failure only posts when the gate failed, and updates an existing comment either way; false posts nothing. Needs pull-requests: write; skipped with a notice when the token cannot write (forks). |
comment-key |
default |
Keeps separate comments when the action runs more than once on a pull request. |
telemetry |
true |
Send action health and scan counters. false disables telemetry for both the action and its CLI scans. |
token |
${{ github.token }} |
Token for the check run and the comment. |
| Output | What it is |
|---|---|
score |
Lowest package score, 0 to 100. |
delta |
Lowest score movement against the baseline; empty without one. |
regressions |
Checks that passed on the base and no longer do, every package together. |
instrumented, partial, dark |
Entry point counts, every package together. |
passed |
true when every package met the gate, whatever gate is set to. |
results |
JSON, one entry per package: name, framework, score, status, reasons, summary, delta, regressions, fixed. |
- uses: evloghq/action@v1
with:
packages: |
apps/*
packages/api
min-score: 70Each package gets its own row in the report and its own annotations, with paths that resolve from the repository root. A package that does not exist on the base branch is new and has nothing to regress from.
- uses: evloghq/action@v1
with:
gate: falseThe step stays green; passed and results say what a gate would have done. Set min-score to today's score once the team has seen a few reports, then raise it as things get fixed.
Each action release pins the @evlog/cli it was tested with, so @v1 is deterministic: a CLI release on npm never moves a verdict under your gate. Upgrading the action upgrades the CLI, in a pull request where a moved score is the point. To run ahead of that:
- uses: evloghq/action@v1
with:
version: latestOn a push there is no base to compare against, so baseline: auto turns the comparison off and the run reports. Pass baseline: git:origin/main to compare against a committed evlog.map.json instead.
- uses: evloghq/action@v1
with:
comment: on-failureA clean pull request gets annotations and a job summary, nothing in the conversation. The comment appears when a check regressed or the score missed min-score, and it is updated to the passing state once that is fixed rather than left behind.
The comment is posted with the workflow's token, so it shows as github-actions. To post as an app of your own (an "evlog" bot with its avatar), mint a token in the workflow and pass it in:
- uses: actions/create-github-app-token@v2
id: app
with:
app-id: ${{ vars.EVLOG_APP_ID }}
private-key: ${{ secrets.EVLOG_APP_KEY }}
- uses: evloghq/action@v1
with:
token: ${{ steps.app.outputs.token }}Everything evlog map scans: Nuxt, Nitro, Next.js App Router, TanStack Start, Hono, Express, and Fastify. Detection reads package.json; nothing is installed.
contents: read to check out. checks: write for the check run and pull-requests: write for the comment; without either the action says so in a notice and everything else still works. Pull requests from forks get a read-only token, so they get annotations as workflow commands and a summary, but no check run and no comment.
GitHub's current pull request diff folds annotations into the alerts counter at the top of the page rather than drawing them on the hunk; the Checks tab and the old diff experience draw them inline. The comment names the entry point either way.
The action emits one evlog-action event with duration, execution outcome, aggregate scan counts, gate result, and check/comment delivery outcomes. Its CLI scans also emit their own evlog-cli events with scan-specific counters. A gate that rejects a scan is recorded as gatePassed: false, not an action execution error.
Set telemetry: false to disable both:
- uses: evloghq/action@v1
with:
telemetry: falseBoth also honour DO_NOT_TRACK=1 and EVLOG_TELEMETRY=0 from the workflow environment. DO_NOT_TRACK takes precedence over EVLOG_TELEMETRY=1. Leaving the input enabled never overrides either opt-out.
Events go to https://telemetry.evlog.cloud/api/telemetry/ingest. Set EVLOG_TELEMETRY_ENDPOINT to redirect both the action and CLI events to an endpoint that accepts the @evlog/telemetry ingest format.
The action payload includes the action revision and triggering event type. It does not include repository names, run IDs, SHAs, package names, file paths, source, tokens, or raw error messages. Custom string fields use fixed allowlists. The SDK also attaches runtime information and an anonymous machine identifier.
When enabled, the action installs a pinned @evlog/telemetry release in a temporary runner directory with package scripts disabled. Installation has a 15-second timeout. A telemetry installation or recording failure prints a notice and leaves the scan result unchanged. Delivery is best effort: the SDK buffers undelivered events on disk, but an ephemeral runner does not preserve them for another job.