Skip to content

chore: sync codecov components dynamically from overlay support levels#3463

Open
gustavolira wants to merge 6 commits into
redhat-developer:mainfrom
gustavolira:chore/dynamic-codecov-components-sync
Open

chore: sync codecov components dynamically from overlay support levels#3463
gustavolira wants to merge 6 commits into
redhat-developer:mainfrom
gustavolira:chore/dynamic-codecov-components-sync

Conversation

@gustavolira

Copy link
Copy Markdown
Member

Summary

Follow-up to #3425. Makes the Codecov support-level components self-update from rhdh-plugin-export-overlays metadata (spec.support) instead of being hand-maintained, so a plugin promoted from e.g. tech-preview → GA is moved to the right component automatically.

While wiring this up I found that #3425 hard-coded 70 component paths, but this repo only has 24 workspaces — most of those paths (workspaces/3scale/, quay/, acr/, backstage/, …) don't exist here; they're overlay workspace names sourced from backstage/community-plugins and other upstreams, so Codecov tracked nothing for them. The generated block now contains only the workspaces that actually exist in this repo.

Changes

  • scripts/generate-codecov-components.sh — rewritten:
    • Reads spec.support from overlay metadata and filters to workspaces present in this repo.
    • Three modes: print (default), --write (rewrites only the component_management block in codecov.yml, preserving flags/coverage/ignore), --check (exits 1 + diff on drift).
    • Deterministic output (no timestamps) so --check is stable; portable across GNU/BSD; shellcheck-clean; back-compatible with the old positional invocation.
  • .github/workflows/sync-codecov-components.yml — new:
    • Weekly cron + workflow_dispatch: clones the overlay, runs --write, opens a PR when a support level changed (peter-evans/create-pull-request).
    • pull_request drift check: runs --check on PRs touching codecov.yml and fails if it's out of sync.
    • Reuses the repo's pinned action SHAs, RHDH_BOT_TOKEN, harden-runner, and repo-guard conventions.
  • codecov.yml — regenerated to the filtered set (GA 6 / Tech-Preview 4 / Community 3 / Dev-Preview 5 = 18 real paths), dropping paths for non-existent workspaces.
  • docs/codecov-support-levels.md — updated for the automated flow and corrected counts/examples.

Verification

  • Print / --write / --check all exercised against a real overlay clone; --write is idempotent; negative drift test exits 1 and pinpoints the path.
  • codecov.yml remains valid YAML with all existing flags intact.
  • shellcheck clean.

Related

🤖 Generated with Claude Code

Make the Codecov support-level components self-update from the
rhdh-plugin-export-overlays `spec.support` metadata instead of being
hand-maintained.

- generate-codecov-components.sh: add --write (rewrite the
  component_management block in place) and --check (fail + diff on drift)
  modes; include only workspaces that exist in this repo; deterministic,
  portable (GNU/BSD), shellcheck-clean.
- Add sync-codecov-components.yml workflow: weekly + on-demand auto PR when
  a plugin's support level changes, plus a pull_request drift check.
- Regenerate codecov.yml to the filtered set, dropping component paths for
  overlay workspaces that don't exist in this repository.
- Update docs/codecov-support-levels.md for the automated flow and counts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gustavolira gustavolira requested review from a team as code owners June 18, 2026 20:09
@rhdh-qodo-merge

Copy link
Copy Markdown

PR Summary by Qodo

Dynamically sync Codecov components from overlay support levels
✨ Enhancement ⚙️ Configuration changes 📝 Documentation 🕐 20-40 Minutes

Grey Divider

Description

• Auto-generate Codecov components from overlay spec.support, filtering to local workspaces.
• Add scheduled + PR-check GitHub Actions workflow to prevent component drift.
• Regenerate codecov.yml block and update docs for new automation.
Diagram

graph TD
  A["Overlay metadata (spec.support)"] --> B["generate-codecov-components.sh"] --> C["codecov.yml (component_management)"]
  D["Sync workflow (schedule/dispatch)"] --> A --> B --> C --> E["create-pull-request"]
  F["Sync workflow (pull_request)"] --> A --> B --> G["--check drift (fail PR)"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Vendor a minimal support-level index into this repo
  • ➕ Eliminates cross-repo dependency during CI runs and local generation
  • ➕ Makes changes reviewable in the same PR that updates plugins/workspaces
  • ➖ Duplicates source-of-truth data and adds another sync burden
  • ➖ Still needs a process to keep vendored data aligned with overlay repo
2. Generate Codecov components from repo-local workspace metadata only
  • ➕ Avoids cloning the overlay repo in CI and reduces external coupling
  • ➕ Keeps all configuration derived from what actually exists in this repo
  • ➖ Loses the overlay as the canonical support-level source; support promotions would require manual edits here
  • ➖ Harder to keep consistent with downstream/export expectations if overlay remains authoritative
3. Replace workspace-path components with per-package paths for mixed-support workspaces
  • ➕ Improves accuracy of component coverage metrics for GA/TP/etc. (reduces skew)
  • ➕ Avoids including non-GA package coverage in GA component totals
  • ➖ Much larger component lists and higher maintenance/compute overhead
  • ➖ Requires stable, predictable per-package path conventions across workspaces

Recommendation: Current approach (overlay-driven generation + scheduled PRs + PR drift check) is the best tradeoff for correctness and maintainability because it keeps support levels sourced from the authoritative overlay metadata while ensuring codecov.yml stays in sync and only includes paths that exist in this repo. The per-package component approach is worth revisiting only if component-level enforcement needs higher precision.

Files changed (4) +346 / -204

Enhancement (1) +158 / -59
generate-codecov-components.shRewrite generator to support --write/--check and filter to local workspaces +158/-59

Rewrite generator to support --write/--check and filter to local workspaces

• Refactors the script to read 'spec.support' values from overlay metadata, group workspaces by support level, and include only workspaces that exist in this repo. Adds stable, deterministic output plus '--write' (in-place replace of 'codecov.yml' block) and '--check' (diff + exit 1 on drift) modes with portable block splicing logic.

scripts/generate-codecov-components.sh

Documentation (1) +64 / -85
codecov-support-levels.mdDocument automated Codecov component sync and updated workspace counts +64/-85

Document automated Codecov component sync and updated workspace counts

• Updates documentation to reflect that the 'component_management' block is generated from overlay metadata, describes the new workflow behaviors (weekly sync PR + PR drift check), and refreshes examples around multi-level workspaces and coverage skew. Adds a changelog entry for the dynamic sync change.

docs/codecov-support-levels.md

Other (2) +124 / -60
sync-codecov-components.ymlAdd workflow to sync and drift-check Codecov components +113/-0

Add workflow to sync and drift-check Codecov components

• Introduces a GitHub Actions workflow that (1) runs weekly/on-demand to regenerate 'codecov.yml' from overlay metadata and open a PR when changes occur, and (2) runs on pull requests touching relevant files to fail on drift using '--check'. Uses pinned action SHAs, hardened runner, sparse checkout of overlay 'workspaces', and bot token for PR creation.

.github/workflows/sync-codecov-components.yml

codecov.ymlRegenerate component_management block to only include existing workspaces +11/-60

Regenerate component_management block to only include existing workspaces

• Replaces the hand-maintained component list with a generated block that documents the new source of truth and automation flow. Drops non-existent workspace paths and updates component counts to reflect only directories present in this repository.

codecov.yml

@rhdh-qodo-merge

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Sync job concurrency key mismatch 🐞 Bug ☼ Reliability
Description
The workflow concurrency group is sync-codecov-components-${{ github.ref }}, but the sync job
always checks out main and writes to the fixed branch automation/sync-codecov-components. A
workflow_dispatch from any non-main ref creates a different concurrency group than the scheduled
run, so both can execute simultaneously and race to update the same PR branch, causing push
conflicts or duplicate PRs.
Code

.github/workflows/sync-codecov-components.yml[R26-28]

+concurrency:
+  group: sync-codecov-components-${{ github.ref }}
+  cancel-in-progress: true
Relevance

⭐⭐ Medium

No prior feedback on concurrency-key/branch mismatch; repo often uses github.ref-based concurrency
(e.g., #2202/#2389).

PR-#2202
PR-#2389

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The concurrency group uses github.ref (line 27), which varies per triggering ref. The sync job
(lines 63–113) always checks out main (line 77) and targets the fixed branch
automation/sync-codecov-components (line 98). Two concurrent runs from different refs (e.g., a
scheduled run on refs/heads/main and a manual dispatch from refs/heads/some-branch) would each
have a distinct concurrency key and would both proceed to write to the same branch, causing a race.

.github/workflows/sync-codecov-components.yml[26-28]
.github/workflows/sync-codecov-components.yml[63-99]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The workflow-level `concurrency.group` is `sync-codecov-components-${{ github.ref }}`. Because the sync job always targets `main` and writes to the fixed branch `automation/sync-codecov-components`, two runs triggered from different refs (e.g., a scheduled run on `main` and a manual `workflow_dispatch` from another branch) will have different concurrency keys and can execute simultaneously, racing to push to the same branch.

## Issue Context
The `check` job (PR drift check) is ref-specific and benefits from per-ref concurrency. The `sync` job, however, always operates on `main` and a fixed target branch, so it needs a ref-independent concurrency key.

## Fix Focus Areas
- `.github/workflows/sync-codecov-components.yml[26-28]` — change the workflow-level concurrency group, or move the concurrency key to the `sync` job level using a fixed string such as `sync-codecov-components-sync` so only one sync run can proceed at a time regardless of the triggering ref.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

@rhdh-qodo-merge rhdh-qodo-merge Bot added documentation Improvements or additions to documentation enhancement New feature or request labels Jun 18, 2026
gustavolira and others added 5 commits June 18, 2026 17:32
- generate-codecov-components.sh: pin sort to LC_ALL=C so output is
  byte-stable across locales (keeps --check from false-positiving when
  regenerated on a non-C-locale machine).
- Emit single-quoted component names to match the repo's prettier config
  (@spotify/prettier-config), so the generated block is style-conformant and
  future root-level formatting can't desync it from --check.
- Make --write atomic: render into a temp file beside codecov.yml and mv it
  into place instead of cp (no half-written file on interruption).
- Replace the fragile line-range usage() with a self-contained heredoc.
- Add persist-credentials: false to the read-only checkouts in the workflow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The `case "$MODE"` dispatch only handled print/write/check. Add a `*)`
branch that errors out so a future flag that sets MODE without a matching
branch fails loudly instead of silently no-op'ing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The component list was a fixed set of four generate_component calls, so a new
support level introduced in the overlay would have been silently dropped.

Discover the distinct spec.support values from the metadata instead, deriving
component_id/name mechanically (<level>-plugins / Title-Case Plugins). Only the
GA label keeps an explicit alias, since "ga" can't be derived from
"generally-available". SUPPORT_LEVEL_ORDER controls display order for known
levels and appends any new level rather than dropping it.

Output is byte-identical to before (codecov.yml unchanged); verified a synthetic
new level appears as its own component.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Per review, the GA component name does not need to stay "ga-plugins". Remove
the only hardcoded label alias so component_id/name are derived purely from the
support-level string for every level:

  generally-available -> generally-available-plugins / "Generally-Available Plugins"

Now nothing about which levels exist or how they're labeled is hardcoded; the
only fixed bit left is SUPPORT_LEVEL_ORDER, which is cosmetic display order and
never drops a level. Regenerated codecov.yml and updated the docs accordingly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
component_id_for/component_name_for read $1 directly while every other function
in the script assigns its positional params to a named local first. Align them
for consistency and readability. No behavior change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant