You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
V2.10.S10: Automatic shield.io badge updates from PR status
Status: Backlog Epic: #[github-epic-issue] Parent roadmap item: V2.10: Build System Consolidation And Qt Build Validation Labels:type/story, area/operations, type/feature
Product Outcome
PR badges on the README reflect actual CI lane status in real time — no developer
needs to run refresh-badges.py from their machine. Build, unit test, and
security badges update automatically when a PR workflow completes, and coverage
badges update after coverage jobs finish. The README becomes a live window into
branch health.
User Story
As a reviewer or visitor, I see accurate build, test, security, and coverage
badges on the README that reflect the current PR state without any manual update
from a developer's machine.
Scope
In scope: design and implement a GitHub Actions workflow (badge-update.yml
or a post-run step in existing workflows) that fires when PR workflows complete
and updates badge SVG URLs between existing marker comments in README.md and doc/execution/testing-tickoni.md.
In scope: replace the manual contrib/readme/refresh-badges.py workflow
(exit-code-driven local script) with a CI-driven badge-update approach that
reads github.event.check_runs or github.event.jobs to determine pass/fail
state for each badge type.
In scope: support badge types currently defined in refresh-badges.py: build, unit, integration, quality, security, system, e2e, cov-fd, cov-tk. Map each badge type to the corresponding CI workflow or
job name so status can be determined from PR check-run results.
In scope: use shield.io's badge API (img.shields.io) — not cached static SVGs
— so badges stay fresh on every page load and do not require storing SVG files
in the repo.
In scope: update the badge URLs using the same marker-comment approach already
in place (<!-- badge:name:start --> / <!-- badge:name:end -->); do not
change the marker format.
In scope: handle the case where a badge type has no corresponding CI job yet
(e.g. integration is planned but not yet scheduled on every PR) — default
to unknown lightgrey until coverage exists.
In scope: the workflow must commit badge changes back to the PR branch (not
main) using the peaceiris/actions-gh-pages or a git push to the PR
branch; on the first successful PR workflow, push badge state to main as a
baseline.
In scope: update doc/execution/build.md and doc/execution/development.md
to document the new badge-update mechanism and remove references to the manual refresh-badges.py as the primary update path.
In scope: the manual refresh-badges.py script remains available for
one-off local experimentation or offline use, but documentation should
clarify it is no longer the production update path.
Out of scope: switching from shield.io to a self-hosted badge server.
Out of scope: adding new badge types beyond the existing set (e.g. coverage
percentage, PR comment counts).
Out of scope: changing badge colors, styles, or the marker comment format.
Preconditions And Assumptions
V2.10.S6 (CI cutover) has wired existing CI workflows to PR triggers on main, so PR check-runs exist for build, test, and security lanes.
Shield.io's public badge API (img.shields.io/badge/...) is accepted for
rendering badge images; no self-hosted badge server is required.
GitHub Actions has permission to push commits to PR branches via the GITHUB_TOKEN (the default token scope).
Existing marker comments (<!-- badge:build:start --> / <!-- badge:build:end -->
etc.) in README.md and testing-tickoni.md are the insertion points;
their format is preserved.
Acceptance Criteria
Given a PR with all CI lanes passing, when the final PR workflow completes,
then README.md badge URLs for build, unit, security show passing/brightgreen (or equivalent pass state) via shield.io URLs.
Given a PR with any CI lane failing, when the PR workflows complete, then README.md badge URLs for the failed lane show failing/red.
Given a PR where a coverage job has not yet run, when PR workflows complete,
then the coverage badge shows unknown/lightgrey.
Given a badge type with no corresponding CI job (e.g. integration during
initial wiring), when PR workflows complete, then its badge shows unknown/lightgrey — not a stale passing badge.
Given a developer who runs refresh-badges.py locally, when they pass an
exit code, then the badge updates locally but the documentation states
this is for experimentation, not production use.
Given a new contributor reading doc/execution/build.md, when they look
for "how to update README badges", then they find the badge-update
workflow is automatic and the manual script is documented as legacy.
Conditional Acceptance
Financial capability and policy
N/A - badge update is a documentation surface change; no policy changes.
Audit and replay
N/A - badge update touches no audit schema or replay logic.
Runtime topology and tile ownership
N/A - badge update touches no tile topology or Firedancer integration.
Model, tool, adapter, or execution boundary
N/A - badge update touches no model, tool, adapter, or execution boundary.
CaseOps API or UI
N/A - badge update touches no CaseOps API or UI.
Storage role: Memory, Analytics, Ledger
N/A - badge update touches no storage roles.
Metrics, diagnostics, and operations
Applies - badge update changes the operational surface for README badge
management from manual local script to automatic CI-driven workflow.
Security and fail-closed behavior
Given the badge-update workflow runs as a GitHub Action, when it pushes
badge changes, then it uses only contents: write scope and does not
introduce any external network calls, secrets, or API keys beyond
the standard GITHUB_TOKEN.
Child Task Issues
V2.10.S10.T1 — Architecture and planning. Survey the badge-update approaches:
(1) a standalone badge-update.yml workflow triggered on workflow_run from
existing PR workflows, (2) a final step in each existing PR workflow that calls
a shared action to update badges, (3) a GitHub App or webhook-based approach.
Document the tradeoff: workflow_run listener is cleanest but requires all PR
workflows to signal completion; inline step adds boilerplate to every workflow;
webhook adds external dependency. Recommend approach and identify risks.
V2.10.S10.T2 — Domain-Driven Design and scaffolding. Design the badge-update
data model: a mapping from badge name to CI workflow/job name to PR check-run
status. Define the update function: read PR check-runs, resolve pass/fail/unknown,
construct shield.io URLs, locate marker comments, replace the img tag between
markers, commit back. Define the CI workflow structure. No production logic yet.
V2.10.S10.T3 — Test-Driven Design. Write a local test script that reads
existing CI workflow names from .github/workflows/, maps them to badge
types, verifies the marker comment format in README.md and testing-tickoni.md,
and confirms the shield.io URL construction logic. Stub the update function.
Tests must pass with hardcoded badge states.
V2.10.S10.T4 — Implementation. Implement the badge-update workflow:
(1) the CI workflow file (recommended: badge-update.yml triggered on workflow_run with types: [completed] and workflow_run.branches: [main]),
(2) the badge-update script (Python, following the existing contrib/readme/refresh-badges.py conventions), (3) the CI job logic:
fetch PR check-runs, determine badge state, update markers, commit to PR branch.
Wire the workflow to fire after each PR workflow completes.
V2.10.S10.T5 — Documentation and DevOps sweep. Update doc/execution/build.md
and doc/execution/development.md to document the new badge-update mechanism.
Update contrib/readme/refresh-badges.py comments to note it is a local
experimentation tool, not the production path. Update this story's epic file.
V2.10.S10.T6 — Security audit. Audit the badge-update workflow for:
GITHUB_TOKEN scope minimization (only contents: write), no external API
calls or secret access, no dependency on third-party GitHub Actions beyond actions/checkout@v7 and standard step runners. Confirm the workflow only
pushes to PR branches or main, never to external repos.
V2.10.S10.T7 — Telemetry and observability audit. Confirm that badge update
does not introduce unexpected logging, metrics, or diagnostic output.
V2.10.S10.T8 — Evidence and quality gate. Run the badge-update workflow against
a test PR. Verify: (1) badges update correctly for passing/failing/unknown states,
(2) badge URLs use shield.io format, (3) markers are preserved, (4) the commit
message is descriptive, (5) no unrelated files are modified.
Evidence Plan
Demo or command: open a PR, wait for CI lanes to complete, verify README badges
reflect actual lane status.
Tests: local badge-update script tests with hardcoded PR states.
Fixtures or samples: updated README.md badges from a test PR.
Audit/replay evidence: N/A - badge update touches no audit schema.
Blocked-flow evidence: N/A - badge update is a documentation surface change.
Quality Gate
README.md badges accurately reflect CI lane status on a test PR.
doc/execution/testing-tickoni.md badges update in sync with README.
Unknown states default to lightgrey, not passing or stale values.
Badge-update workflow uses only standard GitHub Actions with minimal scope.
contrib/readme/refresh-badges.py remains available but documented as
local experimentation.
Documentation updated to reflect the new badge-update mechanism.
Notes And Open Questions
Which CI workflow/job maps to which badge type when a single workflow
produces multiple test results (e.g. tests-short.yml covers unit, integration, and quality)?
Should coverage badges (cov-fd, cov-tk) update from a separate coverage.yml workflow or from the same badge-update trigger?
When should the baseline badge state be pushed to main — on the first PR
merge, or immediately on story completion?
V2.10.S10: Automatic shield.io badge updates from PR status
Status: Backlog
Epic: #[github-epic-issue]
Parent roadmap item: V2.10: Build System Consolidation And Qt Build Validation
Labels:
type/story,area/operations,type/featureProduct Outcome
PR badges on the README reflect actual CI lane status in real time — no developer
needs to run
refresh-badges.pyfrom their machine. Build, unit test, andsecurity badges update automatically when a PR workflow completes, and coverage
badges update after coverage jobs finish. The README becomes a live window into
branch health.
User Story
As a reviewer or visitor, I see accurate build, test, security, and coverage
badges on the README that reflect the current PR state without any manual update
from a developer's machine.
Scope
badge-update.ymlor a post-run step in existing workflows) that fires when PR workflows complete
and updates badge SVG URLs between existing marker comments in
README.mdanddoc/execution/testing-tickoni.md.contrib/readme/refresh-badges.pyworkflow(exit-code-driven local script) with a CI-driven badge-update approach that
reads
github.event.check_runsorgithub.event.jobsto determine pass/failstate for each badge type.
refresh-badges.py:build,unit,integration,quality,security,system,e2e,cov-fd,cov-tk. Map each badge type to the corresponding CI workflow orjob name so status can be determined from PR check-run results.
— so badges stay fresh on every page load and do not require storing SVG files
in the repo.
in place (
<!-- badge:name:start -->/<!-- badge:name:end -->); do notchange the marker format.
(e.g.
integrationis planned but not yet scheduled on every PR) — defaultto
unknownlightgrey until coverage exists.main) using the
peaceiris/actions-gh-pagesor agit pushto the PRbranch; on the first successful PR workflow, push badge state to main as a
baseline.
doc/execution/build.mdanddoc/execution/development.mdto document the new badge-update mechanism and remove references to the manual
refresh-badges.pyas the primary update path.refresh-badges.pyscript remains available forone-off local experimentation or offline use, but documentation should
clarify it is no longer the production update path.
percentage, PR comment counts).
Preconditions And Assumptions
main, so PR check-runs exist for build, test, and security lanes.img.shields.io/badge/...) is accepted forrendering badge images; no self-hosted badge server is required.
GITHUB_TOKEN(the default token scope).<!-- badge:build:start -->/<!-- badge:build:end -->etc.) in
README.mdandtesting-tickoni.mdare the insertion points;their format is preserved.
Acceptance Criteria
then
README.mdbadge URLs forbuild,unit,securityshowpassing/brightgreen(or equivalent pass state) via shield.io URLs.README.mdbadge URLs for the failed lane showfailing/red.then the coverage badge shows
unknown/lightgrey.integrationduringinitial wiring), when PR workflows complete, then its badge shows
unknown/lightgrey— not a stale passing badge.refresh-badges.pylocally, when they pass anexit code, then the badge updates locally but the documentation states
this is for experimentation, not production use.
doc/execution/build.md, when they lookfor "how to update README badges", then they find the badge-update
workflow is automatic and the manual script is documented as legacy.
Conditional Acceptance
Financial capability and policy
Audit and replay
Runtime topology and tile ownership
Model, tool, adapter, or execution boundary
CaseOps API or UI
Storage role: Memory, Analytics, Ledger
Metrics, diagnostics, and operations
management from manual local script to automatic CI-driven workflow.
Security and fail-closed behavior
badge changes, then it uses only
contents: writescope and does notintroduce any external network calls, secrets, or API keys beyond
the standard
GITHUB_TOKEN.Child Task Issues
V2.10.S10.T1 — Architecture and planning. Survey the badge-update approaches:
(1) a standalone
badge-update.ymlworkflow triggered onworkflow_runfromexisting PR workflows, (2) a final step in each existing PR workflow that calls
a shared action to update badges, (3) a GitHub App or webhook-based approach.
Document the tradeoff:
workflow_runlistener is cleanest but requires all PRworkflows to signal completion; inline step adds boilerplate to every workflow;
webhook adds external dependency. Recommend approach and identify risks.
V2.10.S10.T2 — Domain-Driven Design and scaffolding. Design the badge-update
data model: a mapping from badge name to CI workflow/job name to PR check-run
status. Define the update function: read PR check-runs, resolve pass/fail/unknown,
construct shield.io URLs, locate marker comments, replace the img tag between
markers, commit back. Define the CI workflow structure. No production logic yet.
V2.10.S10.T3 — Test-Driven Design. Write a local test script that reads
existing CI workflow names from
.github/workflows/, maps them to badgetypes, verifies the marker comment format in
README.mdandtesting-tickoni.md,and confirms the shield.io URL construction logic. Stub the update function.
Tests must pass with hardcoded badge states.
V2.10.S10.T4 — Implementation. Implement the badge-update workflow:
(1) the CI workflow file (recommended:
badge-update.ymltriggered onworkflow_runwithtypes: [completed]andworkflow_run.branches: [main]),(2) the badge-update script (Python, following the existing
contrib/readme/refresh-badges.pyconventions), (3) the CI job logic:fetch PR check-runs, determine badge state, update markers, commit to PR branch.
Wire the workflow to fire after each PR workflow completes.
V2.10.S10.T5 — Documentation and DevOps sweep. Update
doc/execution/build.mdand
doc/execution/development.mdto document the new badge-update mechanism.Update
contrib/readme/refresh-badges.pycomments to note it is a localexperimentation tool, not the production path. Update this story's epic file.
V2.10.S10.T6 — Security audit. Audit the badge-update workflow for:
GITHUB_TOKEN scope minimization (only
contents: write), no external APIcalls or secret access, no dependency on third-party GitHub Actions beyond
actions/checkout@v7and standard step runners. Confirm the workflow onlypushes to PR branches or main, never to external repos.
V2.10.S10.T7 — Telemetry and observability audit. Confirm that badge update
does not introduce unexpected logging, metrics, or diagnostic output.
V2.10.S10.T8 — Evidence and quality gate. Run the badge-update workflow against
a test PR. Verify: (1) badges update correctly for passing/failing/unknown states,
(2) badge URLs use shield.io format, (3) markers are preserved, (4) the commit
message is descriptive, (5) no unrelated files are modified.
Evidence Plan
reflect actual lane status.
README.mdbadges from a test PR.Quality Gate
README.mdbadges accurately reflect CI lane status on a test PR.doc/execution/testing-tickoni.mdbadges update in sync with README.contrib/readme/refresh-badges.pyremains available but documented aslocal experimentation.
Notes And Open Questions
produces multiple test results (e.g.
tests-short.ymlcoversunit,integration, andquality)?cov-fd,cov-tk) update from a separatecoverage.ymlworkflow or from the same badge-update trigger?merge, or immediately on story completion?