Skip to content

Feature proposal: codecarbon ci-report to summarise and diff emissions.csv in CI #1351

Description

@davidberenstein1957

Feature proposal.

The problem

CI is the one workload nearly every project runs continuously, on someone else's hardware, without anybody ever looking at its energy cost. Running codecarbon monitor -- pytest in a pipeline already works today, but it leaves an emissions.csv behind that nobody reads: there is no supported way to turn that file into something a pipeline can print, gate on, or compare against the target branch.

What developers actually want in a pipeline is one line of output attached to a diff — "this branch burns 12.4 g CO2eq per test run, +18% vs master" — and, optionally, a hard failure when a change blows past a budget. Today that means every user writes their own pandas snippet.

Proposed design

A single new CLI command, deliberately CI-agnostic so GitLab, Jenkins, Buildkite and GitHub all get it:

$ codecarbon ci-report --csv emissions.csv --baseline base/emissions.csv --format markdown

Surface:

  • --csv PATH (default emissions.csv) — the run to summarise.
  • --baseline PATH (optional) — a second CSV to diff against; absent or unreadable means the report is rendered without a comparison rather than failing.
  • --format markdown|json — markdown for job summaries and PR comments, JSON for anything that wants to post-process.
  • --label TEXT — free-text label for the measured workload, shown in the header.
  • --threshold-kg FLOAT (optional) — exit non-zero when total emissions exceed it; unset means never fail.

Aggregation follows the file format rather than guessing: rows written during a run are per-flush deltas sharing a run_id, so the report sums the rows of the most recent run_id and reports total emissions, energy and duration.

Why it fits existing extension points

Nothing here is new measurement code. codecarbon monitor (codecarbon/cli/main.py) already wraps an arbitrary command under a process-scoped tracker and preserves the child exit code, and FileOutput already writes the EmissionsData schema to emissions.csv. ci-report is a reader over that existing output, registered next to monitor and detect on the existing Typer app. No new dependency, no new extra, no configuration surface: the tracker side is still driven by .codecarbon.config and CODECARBON_* env vars as it is today.

Putting the logic in the CLI rather than in pipeline shell means it is unit-testable and portable across CI systems.

Scope boundary

In scope: the ci-report command, its rendering, the baseline diff, the threshold exit code, tests and docs.

Explicitly out of scope for now: a published composite GitHub Action, PR-comment posting, artifact download of the base-branch baseline, and any marketplace packaging. Those are thin wrappers over this command and can follow once the command itself has settled; they carry CI-specific maintenance that shouldn't gate the portable half.

Also worth documenting rather than hiding: on virtualised hosted runners RAPL is unavailable and CPU energy falls back to the TDP model, so numbers are comparable between runs on identical runner types, not absolute.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions