Skip to content

docs: cut the version badge cache to the shortest shields allows - #162

Merged
aditeyabaral merged 2 commits into
pesu-dev:devfrom
aditeyabaral:docs/badge-cache-floor
Sep 15, 2026
Merged

aditeyabaral merged 2 commits into
pesu-dev:devfrom
aditeyabaral:docs/badge-cache-floor

Conversation

@aditeyabaral

Copy link
Copy Markdown
Member

📌 Description

The live version badges added in #161 lag a deploy by much longer than intended. Diagnosed rather
than guessed:

Two caches compound, each at the 600 seconds #161 set. shields.io serves
cache-control: max-age=600 from a CDN that caches per edge, and GitHub's camo proxy then
mirrors that max-age on top of it. A badge can therefore be up to ~20 minutes stale, and two
people can see different versions at the same moment depending on which shields edge they reach.

Measured, not inferred. camo fetched fresh — x-cache: MISS, age: 0 — and shields handed it
production: v4.4.0, two releases behind, at a moment a direct request to shields returned
v4.6.0.

120 seconds is the floor. shields clamps anything lower: a requested cacheSeconds of 30 or 60
both come back as max-age=120. Worst case goes from roughly twenty minutes to roughly four.

cacheSeconds requested Cache-Control served
30 max-age=120
60 max-age=120
120 max-age=120
300 max-age=300
600 max-age=600 (before this change)

It cannot be real time, and that is worth stating plainly: GitHub serves every external image
through a caching proxy, so a README badge is always a cached copy of a cached copy. Anyone needing
the exact deployed version should read /openapi.json, which the badge links to.

ℹ️ Fixes / Related Issues
Follows #161, which added the badges.

🧱 Type of Change

  • 🐛 Bug fix – Non-breaking fix for a functional/logic error
  • ✨ New feature – Adds functionality without breaking existing APIs
  • ⚠️ Breaking change – Introduces backward-incompatible changes (API, schema, etc.)
  • 📝 Documentation update – README, docstrings, OpenAPI tags, etc.
  • 🧪 Test suite change – Adds/updates unit, functional, or integration tests
  • ⚙️ CI/CD pipeline update – Modifies GitHub Actions, pre-commit, or Docker build
  • 🧹 Code quality / Refactor – Improves structure, readability, or style (no functional changes)
  • 🐢 Performance improvement – Speeds up auth, scraping, or reduces I/O
  • 🕵️ Debug/logging enhancement – Adds or improves logging/debug support
  • 🔧 Developer tooling – Scripts, benchmarks, local testing improvements
  • 🔒 Security fix – Addresses auth/session/data validation vulnerabilities
  • 🧰 Dependency update – Updates libraries in requirements.txt, pyproject.toml

Marked as a bug fix as well as a docs change: the badges were showing a version the service had not
run for two releases.

🧪 How Has This Been Tested?

  • Unit Tests (tests/unit/)
  • Functional Tests (tests/functional/)
  • Integration Tests (tests/integration/)
  • Manual Testing

276 tests, 100.00% coverage, unchanged — no code is touched. pre-commit run --all-files
passes 12/12 hooks.

Manual: requested cacheSeconds of 30, 60, 120, 300 and 600 against shields and recorded the
Cache-Control each returned (table above); pulled the camo URL out of GitHub's rendered README and
read its cache headers and rendered value; and confirmed both environments' /openapi.json report
4.6.0, so the badge source is correct and the staleness was entirely caching.

⚙️ Test Configuration:

  • OS: Linux
  • Python: 3.14.4 via uv
  • Docker build tested

Unchecked: nothing in the image or its behaviour changes.

✅ Checklist

  • My code follows the CONTRIBUTING.md guidelines
  • I've performed a self-review of my changes
  • I've added/updated necessary comments and docstrings
  • I've updated relevant docs (README or endpoint docs)
  • No new warnings introduced
  • I've added tests to cover my changes
  • All tests pass locally (scripts/run_tests.py)
  • I've run linting and formatting (pre-commit run --all-files)
  • Docker image builds and runs correctly
  • Changes are backwards compatible (if applicable)
  • Feature flags or .env vars updated (if applicable)
  • I've tested across multiple environments (if applicable)
  • Benchmarks still meet expected performance (scripts/benchmark/benchmark_requests.py)

Unchecked items carry no work: no code, no image change, no new variables, nothing a benchmark
measures.

🛠️ Affected API Behaviour

  • app/app.py – Modified /authenticate route logic
  • app/pesu.py – Updated scraping or authentication handling

Only README.md — two query parameters.

🧩 Models

  • app/models/request.py – Input validation or request schema changes
  • app/models/response.py – Authentication response formatting
  • app/models/profile.py – Profile extraction logic

🐳 DevOps & Config

  • Dockerfile – Changes to base image or build process
  • .github/workflows/*.yaml – CI/CD pipeline or deployment updates
  • pyproject.toml / requirements.txt – Dependency version changes
  • .pre-commit-config.yaml – Linting or formatting hook changes

Project version only, 4.6.0 → 4.7.0, plus the matching uv.lock.

📊 Benchmarks & Analysis

  • scripts/benchmark/benchmark_requests.py – Performance or latency measurement changes
  • scripts/benchmark/analyze_benchmark.py – Benchmark result analysis changes
  • scripts/run_tests.py – Custom test runner logic or behavior updates

🧠 Additional Notes

A shorter cache means shields re-fetches /openapi.json more often, which is 18 KB from a public
endpoint and also keeps the service awake — neither a cost worth avoiding here.

If a badge that is never stale is wanted, the only way is for the value to come from something
GitHub does not proxy — which no README badge can be. The realistic alternative is the Grafana
dashboard, which queries live.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VU7YUhP71KSsotWQ1H7CRH

aditeyabaral and others added 2 commits September 14, 2026 22:08
The badges lag a deploy by far longer than intended. Two caches compound, each at the 600 seconds
this set: shields serves `max-age=600` from a CDN that caches per edge, and GitHub's camo proxy
then mirrors that max-age on top. So a badge can be up to twenty minutes stale, and two people can
see different versions at the same moment depending on which shields edge they reach.

Measured while diagnosing: camo fetched fresh (`x-cache: MISS`, `age: 0`) and was handed `v4.4.0`
by shields, two releases behind, at a moment a direct request returned `v4.6.0`.

120 is the floor — shields clamps anything lower, serving `max-age=120` for a requested 30 or 60
alike. That takes the worst case from roughly twenty minutes to roughly four.

It cannot be real time. GitHub serves every external image through a caching proxy, so a README
badge is always a cached copy of a cached copy.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VU7YUhP71KSsotWQ1H7CRH
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VU7YUhP71KSsotWQ1H7CRH
@aditeyabaral
aditeyabaral requested a review from a team as a code owner September 15, 2026 03:08
@aditeyabaral
aditeyabaral merged commit bcdc2fb into pesu-dev:dev Sep 15, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant