pola-rs/polars GitHub Actions scorecard

Public GitHub Actions data, last 30 days. Updated .

Data sourced from public GitHub. GitSpider is not affiliated with or endorsed by this repository's owners. Request removal.

136 min/mo
recoverable (~2% of CI time) · across 30 patterns · ≈$1/mo
Estimated from wall-clock time · public repos pay $0, $ = private-repo equivalent
See all 30 fixes, each with the exact YAML ↓
3.0%
failure rate, 30d
0m
avg time to recover from a failure
Since : findings 30 → 30 · recoverable ~116 → ~136 min/mo
29 workflows · 500 runs (16.7/day) · 5,880 CI-min (wall-clock) · ≈$35 at private-repo rates (30d)

Where the minutes go (30d)

Code coverage~2,110 min · 50 runs
Test Python~1,533 min · 50 runs
Benchmark~920 min · 24 runs
or track on every push →

Waste detected

Biggest wins first, each with the exact config fix.

Missing dependency cache · Build Python documentation

~84 min/mo · ≈$1/mo

Set `cache: 'pip'` on your `actions/setup-python` step, or add an `actions/cache@v4` step keyed on your requirements/lock file.

- uses: actions/setup-python@v5
  with:
    python-version: '3.12'
    cache: 'pip'

Full guide: how to fix this →

Concurrency without cancel-in-progress · Build Python documentation

~28 min/mo

Concurrency group has no `cancel-in-progress: true`, so superseded runs queue instead of cancelling. Add it to supersede stale runs.

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

Full guide: how to fix this →

Concurrency without cancel-in-progress · Build Rust documentation

~12 min/mo

Concurrency group has no `cancel-in-progress: true`, so superseded runs queue instead of cancelling. Add it to supersede stale runs.

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

Full guide: how to fix this →

Missing dependency cache · Lint Python

~9 min/mo

Set `cache: 'pip'` on your `actions/setup-python` step, or add an `actions/cache@v4` step keyed on your requirements/lock file.

- uses: actions/setup-python@v5
  with:
    python-version: '3.12'
    cache: 'pip'

Full guide: how to fix this →

No concurrency control · changes-dsl labeler

~2 min/mo

Add a `concurrency:` block keyed on branch to cancel superseded runs when devs push twice quickly.

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

Full guide: how to fix this →

No concurrency control · Pull request labeler

~1 min/mo

Add a `concurrency:` block keyed on branch to cancel superseded runs when devs push twice quickly.

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

Full guide: how to fix this →

Also found: 24 more config fixes with negligible recoverable minutes: timeouts, retention, path filters

No job timeout · Pull request labeler

~0 min/mo

No job sets `timeout-minutes`, so a hung step can run to GitHub's 6-hour default. Add `timeout-minutes` to each job.

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 15

Full guide: how to fix this →

No job timeout · Update draft releases

~0 min/mo

No job sets `timeout-minutes`, so a hung step can run to GitHub's 6-hour default. Add `timeout-minutes` to each job.

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 15

Full guide: how to fix this →

No job timeout · Test Python

~0 min/mo

No job sets `timeout-minutes`, so a hung step can run to GitHub's 6-hour default. Add `timeout-minutes` to each job.

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 15

Full guide: how to fix this →

Premium runners (macOS / Windows) · Test Python

~0 min/mo

macOS bills ~10x and Windows ~2x a Linux minute. The cost estimate above assumes Linux, so your real spend is higher. Move any job that doesn't need them to `ubuntu-latest`.

jobs:
  build:
    runs-on: ubuntu-latest  # ~10x cheaper than macos-latest

Full guide: how to fix this →

No job timeout · Lint Python

~0 min/mo

No job sets `timeout-minutes`, so a hung step can run to GitHub's 6-hour default. Add `timeout-minutes` to each job.

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 15

Full guide: how to fix this →

No job timeout · Lint global

~0 min/mo

No job sets `timeout-minutes`, so a hung step can run to GitHub's 6-hour default. Add `timeout-minutes` to each job.

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 15

Full guide: how to fix this →

No path filters on triggers · Lint global

~0 min/mo

Runs on every push/PR with no `paths:` filter, so docs-only changes still trigger full CI. Add a `paths:` filter if that's common.

on:
  pull_request:
    paths:
      - 'src/**'
      - 'package.json'

Full guide: how to fix this →

System packages reinstalled every run · Lint global

~0 min/mo

System packages install from the network on every run with no cache. Cache them (cache-apt-pkgs-action) or check whether the runner image already has the tool.

- uses: awalsh128/cache-apt-pkgs-action@latest
  with:
    packages: <your packages>
    version: 1.0

Full guide: how to fix this →

No job timeout · Benchmark

~0 min/mo

No job sets `timeout-minutes`, so a hung step can run to GitHub's 6-hour default. Add `timeout-minutes` to each job.

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 15

Full guide: how to fix this →

No job timeout · Build Python documentation

~0 min/mo

No job sets `timeout-minutes`, so a hung step can run to GitHub's 6-hour default. Add `timeout-minutes` to each job.

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 15

Full guide: how to fix this →

No job timeout · Build Rust documentation

~0 min/mo

No job sets `timeout-minutes`, so a hung step can run to GitHub's 6-hour default. Add `timeout-minutes` to each job.

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 15

Full guide: how to fix this →

No job timeout · Lint Rust

~0 min/mo

No job sets `timeout-minutes`, so a hung step can run to GitHub's 6-hour default. Add `timeout-minutes` to each job.

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 15

Full guide: how to fix this →

Third-party actions pinned to a mutable ref · Lint Rust

~0 min/mo

1 third-party action pinned to a branch or other mutable ref, which can change under you (supply-chain risk, non-reproducible builds). Pin to a full commit SHA instead. (3 more on a major-version tag like @v4; consider full-SHA pinning there too.)

uses: taiki-e/install-action@<full-sha>  # was @cargo-deny

No job timeout · Test Rust

~0 min/mo

No job sets `timeout-minutes`, so a hung step can run to GitHub's 6-hour default. Add `timeout-minutes` to each job.

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 15

Full guide: how to fix this →

Premium runners (macOS / Windows) · Test Rust

~0 min/mo

macOS bills ~10x and Windows ~2x a Linux minute. The cost estimate above assumes Linux, so your real spend is higher. Move any job that doesn't need them to `ubuntu-latest`.

jobs:
  build:
    runs-on: ubuntu-latest  # ~10x cheaper than macos-latest

Full guide: how to fix this →

No job timeout · Test Bytecode Parser

~0 min/mo

No job sets `timeout-minutes`, so a hung step can run to GitHub's 6-hour default. Add `timeout-minutes` to each job.

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 15

Full guide: how to fix this →

No job timeout · Code coverage

~0 min/mo

No job sets `timeout-minutes`, so a hung step can run to GitHub's 6-hour default. Add `timeout-minutes` to each job.

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 15

Full guide: how to fix this →

Artifacts at default retention · Code coverage

~0 min/mo

`upload-artifact` has no `retention-days`, so artifacts keep up to 90 days (storage cost). Set e.g. `retention-days: 7`.

- uses: actions/upload-artifact@v4
  with:
    name: build
    path: dist/
    retention-days: 7

Full guide: how to fix this →

Premium runners (macOS / Windows) · Code coverage

~0 min/mo

macOS bills ~10x and Windows ~2x a Linux minute. The cost estimate above assumes Linux, so your real spend is higher. Move any job that doesn't need them to `ubuntu-latest`.

jobs:
  build:
    runs-on: ubuntu-latest  # ~10x cheaper than macos-latest

Full guide: how to fix this →

System packages reinstalled every run · Code coverage

~0 min/mo

System packages install from the network on every run with no cache. Cache them (cache-apt-pkgs-action) or check whether the runner image already has the tool.

- uses: awalsh128/cache-apt-pkgs-action@latest
  with:
    packages: <your packages>
    version: 1.0

Full guide: how to fix this →

Third-party actions pinned to a mutable ref · Code coverage

~0 min/mo

2 third-party actions pinned to a branch or other mutable ref, which can change under you (supply-chain risk, non-reproducible builds). Pin to a full commit SHA instead. (3 more on a major-version tag like @v4; consider full-SHA pinning there too.)

uses: taiki-e/install-action@<full-sha>  # was @cargo-llvm-cov

No job timeout · Remote Benchmark

~0 min/mo

No job sets `timeout-minutes`, so a hung step can run to GitHub's 6-hour default. Add `timeout-minutes` to each job.

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 15

Full guide: how to fix this →

No job timeout · changes-dsl labeler

~0 min/mo

No job sets `timeout-minutes`, so a hung step can run to GitHub's 6-hour default. Add `timeout-minutes` to each job.

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 15

Full guide: how to fix this →

No job timeout · Issue labeler

~0 min/mo

No job sets `timeout-minutes`, so a hung step can run to GitHub's 6-hour default. Add `timeout-minutes` to each job.

jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 15

Full guide: how to fix this →

Copy every fix as one block (10 snippets, annotated per workflow)
# Missing dependency cache (pip) (applies to: Build Python documentation, Lint Python)
- uses: actions/setup-python@v5
  with:
    python-version: '3.12'
    cache: 'pip'

# Concurrency without cancel-in-progress (applies to: Build Python documentation, Build Rust documentation)
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

# No concurrency control (applies to: changes-dsl labeler, Pull request labeler)
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

# No job timeout (applies to: Pull request labeler, Update draft releases, Test Python, Lint Python, Lint global, Benchmark, Build Python documentation, Build Rust documentation, Lint Rust, Test Rust, Test Bytecode Parser, Code coverage, Remote Benchmark, changes-dsl labeler, Issue labeler)
jobs:
  build:
    runs-on: ubuntu-latest
    timeout-minutes: 15

# Premium runners (macOS / Windows) (applies to: Test Python, Test Rust, Code coverage)
jobs:
  build:
    runs-on: ubuntu-latest  # ~10x cheaper than macos-latest

# No path filters on triggers (applies to: Lint global)
on:
  pull_request:
    paths:
      - 'src/**'
      - 'package.json'

# System packages reinstalled every run (applies to: Lint global, Code coverage)
- uses: awalsh128/cache-apt-pkgs-action@latest
  with:
    packages: <your packages>
    version: 1.0

# Third-party actions pinned to a mutable ref (applies to: Lint Rust)
uses: taiki-e/install-action@<full-sha>  # was @cargo-deny

# Artifacts at default retention (applies to: Code coverage)
- uses: actions/upload-artifact@v4
  with:
    name: build
    path: dist/
    retention-days: 7

# Third-party actions pinned to a mutable ref (applies to: Code coverage)
uses: taiki-e/install-action@<full-sha>  # was @cargo-llvm-cov

Each snippet is representative. Merge into the named workflow files rather than pasting wholesale.

Add the badge to your README

Live CI-health badge → GitSpider badge

[![GitSpider](https://gitspider.com/badge/pola-rs/polars.svg)](https://gitspider.com/scan/pola-rs/polars)

Want this on every push?

This scorecard is a one-time snapshot. Install the free GitHub App to track this repo continuously: new regressions caught as they land, trends over time, on your public and private repos. Team adds the offending commit on the PR + Slack alerts.

Install & monitor this repo →

💬 On Team, this same analysis posts automatically to every PR: the regression, and the exact commit that caused it, right where your team already looks. See plans →

Not ready to install? Get this report by email. No spam, unsubscribe anytime.

Share this scorecard: https://gitspider.com/scan/pola-rs/polars