Repository navigation
Rollout: migrate S-CORE modules from @score_tooling//coverage to score_coverage 0.4.2 #3258
Description
Goal
Move every S-CORE module repository from the coverage pipeline bundled in score_tooling
(@score_tooling//coverage) to the standalone, qualified Bazel module score_coverage 0.3.1
(https://github.com/eclipse-score/coverage_tool, registry release 0.3.1; 0.3.0 added the QNX gcov backend, 0.3.1 the required --instrumentation_filter).
Why: the coverage tool is TCL LOW under the S-CORE Tool Management Plan and is qualified on its
own version, with its own requirements, tests and verification report
(https://eclipse-score.github.io/coverage_tool/main/). Consumers must pin that version, not a
score_tooling release. Interface is unchanged; only labels move.
Reference migration (merged, copy this): eclipse-score/baselibs#584, then the bump #589
(6 files, MODULE.bazel + lockfile, tools/coverage/BUILD, coverage.bazelrc, workflow, YAML comment).
Repositories
| Repo | Coverage dir | score_tooling | rules_rust | Files to touch | Status |
|---|---|---|---|---|---|
| baselibs | tools/coverage/ |
2.2.1 | 0.68.2-score | done | #584 merged (0.1.0), #589 merged (0.2.0); eclipse-score/baselibs#626 adds QNX on-target coverage (0.3.1) |
| logging | quality/coverage/ |
2.2.0 | 0.68.2-score | done | eclipse-score/logging#338 (0.3.1) |
| lifecycle | quality/coverage/ |
2.2.1 | 0.68.2-score | done | eclipse-score/lifecycle#715 (0.3.1) |
| persistency | quality/coverage/ |
2.2.0 | 0.68.2-score | done | eclipse-score/persistency#450 merged (0.3.1) |
| kyron | tools/coverage/ |
2.2.1 | 0.68.2-score | done | eclipse-score/kyron#175 (0.3.1) |
| orchestrator | tools/coverage/ |
2.2.1 | 0.68.1-score → bump | .bazelrc, MODULE.bazel, tools/coverage/{BUILD,coverage.bazelrc,coverage_justifications.yaml}, .github/workflows/coverage.yml |
todo |
| time | tools/coverage/ |
2.2.1 | none (C++ only) | done | eclipse-score/time#235 (0.3.1) |
| inc_security_crypto | tools/coverage/ |
2.2.1 | 0.68.2-score | done | eclipse-score/inc_security_crypto#267 (0.3.1) |
| inc_someip_gateway | none (on the tool since 0.2.0) | 2.1.1 | none | done | eclipse-score/inc_someip_gateway#315 (bump to 0.3.1, README label) |
Sources: gh search code 'score_tooling//coverage' --owner eclipse-score on 2026-09-14.
Out of scope of this rollout (separate issues):
communication: carried its own copy of the pipeline; real migration in quality/coverage: replace the in-repo pipeline by score_coverage (Linux LLVM + QNX gcov) communication#1171 (Linux LLVM + QNX gcov, draft pending review).reference_integration: uses the legacy Ferrocene flow (rust_coverage_reportfrom@score_tooling//:defs.bzl,--run_under=@score_tooling//coverage:llvm_profile_wrapper). Not provided byscore_coverage; migrating it means switching to the LLVM pipeline.tooling: deprecation aliases / removal ofcoverage/after all consumers are moved.
Also new in 0.2.0: unmapped_files.txt in the archive lists in-scope files without any coverage data (no-data findings, declaration-only headers, compiled-without-code placeholders). Attach its no-data count to the PR; do not act on it in the migration PR.
Recipe per repository (manual)
- Branch off
main.git grep -n 'score_tooling//coverage'to get the exact file list. - Baseline first. Run the repo's coverage workflow command locally on a representative package and keep the LCOV:
bazel coverage --config=llvm_cov --build_tests_only -- //<package>/... bazel run @score_tooling//coverage:generate_coverage_html -- --yaml <justifications.yaml> --testlogs-subdir <dir> --archive-dir cov_before cp bazel-out/_coverage/_coverage_report.dat before.dat
- Replace labels one-to-one:
@score_tooling//coverage:defs.bzl→@score_coverage//:defs.bzl@score_tooling//coverage:merger→@score_coverage//:merger@score_tooling//coverage:generate_coverage_html→@score_coverage//:generate_coverage_html@score_tooling//coverage:enable_llvm_coverage_for_death_tests→@score_coverage//:enable_llvm_coverage_for_death_tests- doc links to
COVERAGE_GUIDE.md→ https://eclipse-score.github.io/coverage_tool/main/manual/user_manual.html
MODULE.bazel: addbazel_dep(name = "score_coverage", version = "0.2.0", dev_dependency = True)next toscore_tooling(keepscore_tooling). Bumprules_rustto0.68.2-scoreif lower.bazel mod deps --lockfile_mode=update(last step, never hand-edit the lockfile).- After run: same as step 2 with
@score_coverage//:generate_coverage_html, archivecov_after, copy toafter.dat. python3 compare_lcov.py before.dat after.dat(script attached below). Accept only if:differing: 0andonly in before:empty;only in after:is empty or contains only headers that 0.1.x/score_tooling dropped (headers behindstrip_include_prefix, reported under their source path, e.g.external/<repo>/include/...), each appearing once incov_after/index.html;- raw/effective percentages unchanged except for those added headers.
Anything else: do not commit, post the diff here.
- One commit,
git commit -s, title ≤ 72 chars, e.g.Migrate coverage pipeline to score_coverage 0.2.0; body with the comparison table. PR tomain, link this issue, paste the table. Wait for the coverage workflow + lockfile check.
Recipe with Claude Code (optional)
The same steps are packaged as a skill. Copy skill/migrate-to-score-coverage/SKILL.md (attached) to
~/.claude/skills/migrate-to-score-coverage/SKILL.md, then in the consumer repo run
claude and type:
/migrate-to-score-coverage Migrate this repo to score_coverage 0.3.1 following the skill. Baseline package: //<package>/... . Tracking issue: eclipse-score/score#3258. Stop and show me the comparison before committing.
Guardrails baked into the skill: commits authored by you with sign-off and no AI trailer, no threshold or justification changes, stop on any non-zero diff, legacy Ferrocene targets are reported instead of migrated. Review the diff and the comparison yourself before pushing.
Definition of done
- logging
- lifecycle
- persistency
- kyron
- orchestrator
- time
- inc_security_crypto
- inc_someip_gateway (README / workflow check)
- each PR carries the before/after comparison table
- follow-up issues filed for communication, reference_integration, tooling deprecation
Attachments
compare_lcov.py
#!/usr/bin/env python3
"""Compare two LCOV files record by record.
Usage: compare_lcov.py before.dat after.dat
Prints identical / differing SF records, files only present on one side,
and the totals. Exit code 1 if any common record differs.
"""
import sys
from collections import defaultdict
def parse(path):
records, cur, name = {}, None, None
for line in open(path, encoding="utf-8"):
line = line.rstrip("\n")
if line.startswith("SF:"):
name, cur = line[3:], defaultdict(list)
elif line == "end_of_record":
records[name] = {k: sorted(v) for k, v in cur.items()}
cur = None
elif cur is not None and ":" in line:
key, val = line.split(":", 1)
if key in ("DA", "BRDA", "LF", "LH", "BRF", "BRH", "FNF", "FNH"):
cur[key].append(val)
return records
def totals(records):
lf = sum(int(r.get("LF", ["0"])[0]) for r in records.values())
lh = sum(int(r.get("LH", ["0"])[0]) for r in records.values())
bf = sum(int(r.get("BRF", ["0"])[0]) for r in records.values())
bh = sum(int(r.get("BRH", ["0"])[0]) for r in records.values())
pct = lambda a, b: f"{100.0 * a / b:.2f}%" if b else "n/a"
return f"lines {lh}/{lf} = {pct(lh, lf)} branches {bh}/{bf} = {pct(bh, bf)}"
def main(before_path, after_path):
before, after = parse(before_path), parse(after_path)
common = sorted(set(before) & set(after))
differing = [f for f in common if before[f] != after[f]]
print(f"before: {len(before)} files, after: {len(after)} files, common: {len(common)}")
print(f"identical records: {len(common) - len(differing)} differing: {len(differing)}")
for f in differing:
print(f" ~ {f}")
for key in sorted(set(before[f]) | set(after[f])):
if before[f].get(key) != after[f].get(key):
print(f" {key}: {before[f].get(key)} -> {after[f].get(key)}")
print("only in after:")
for f in sorted(set(after) - set(before)):
print(f" + {f}")
print("only in before:")
for f in sorted(set(before) - set(after)):
print(f" - {f}")
print(f"before: {totals(before)}")
print(f"after: {totals(after)}")
return 1 if differing else 0
if __name__ == "__main__":
if len(sys.argv) != 3:
sys.exit(__doc__)
sys.exit(main(sys.argv[1], sys.argv[2]))skill/migrate-to-score-coverage/SKILL.md
---
name: migrate-to-score-coverage
description: Migrate an S-CORE module repository from @score_tooling//coverage to the qualified score_coverage Bazel module, validate that the reported coverage is unchanged, and open the PR.
---
# Migrate a consumer to score_coverage
You are migrating one S-CORE repository (the current working directory) from the
coverage pipeline bundled in `score_tooling` to the standalone, qualified module
`score_coverage` (https://github.com/eclipse-score/coverage_tool). The public
interface is identical; only labels change. Reference PR: eclipse-score/baselibs#584.
## Rules
- All commits authored by the human user, `git commit -s`, no AI co-author trailer.
- Commit title <= 72 characters. Run `bazel mod deps --lockfile_mode=update` as the
LAST step before committing; never hand-edit `MODULE.bazel.lock`.
- Never lower a coverage threshold or drop a justification to make CI pass. If
numbers move, stop and report with the comparison output.
- Do not touch the repo's coverage scope, justification YAML entries, or thresholds.
## Steps
1. **Inventory.** `git grep -n 'score_tooling//coverage'` and
`git grep -n 'score_tooling.*coverage'`. Expected hits: `MODULE.bazel`
(llvm toolchain `compile_flags`/features), `tools/coverage/BUILD` or
`quality/coverage/BUILD` (load of `defs.bzl`), `*/coverage.bazelrc`
(`--coverage_output_generator`), `.github/workflows/*coverage*.yml`
(`generate_coverage_html`), READMEs, justification YAML header comment.
If you find `llvm_profile_wrapper`, `combined_report` or
`rust_coverage_report`: that is the legacy Ferrocene flow, NOT covered by
score_coverage. Stop and report.
2. **Baseline run (before touching anything).** Pick the smallest package that
exercises the scope, e.g. the one named in the repo's coverage workflow, and run
(adapt config name to the repo, usually `llvm_cov`):
```
bazel coverage --config=llvm_cov --build_tests_only -- <targets>
bazel run @score_tooling//coverage:generate_coverage_html -- --yaml <justifications.yaml> --testlogs-subdir <dir> --archive-dir cov_before
cp bazel-out/_coverage/_coverage_report.dat before.dat
```
Save the raw and effective percentages printed by the tool.
3. **Edit labels** (one-to-one):
| old | new |
|---|---|
| `@score_tooling//coverage:defs.bzl` | `@score_coverage//:defs.bzl` |
| `@score_tooling//coverage:merger` | `@score_coverage//:merger` |
| `@score_tooling//coverage:generate_coverage_html` | `@score_coverage//:generate_coverage_html` |
| `@score_tooling//coverage:enable_llvm_coverage_for_death_tests` | `@score_coverage//:enable_llvm_coverage_for_death_tests` |
| `@score_tooling//coverage:justify` / `:effective_coverage` / `:coverage_summary` | `@score_coverage//:justify` / `:effective_coverage` / `:coverage_summary` |
| `@score_tooling//coverage:COVERAGE_GUIDE.md` (doc links) | https://eclipse-score.github.io/coverage_tool/main/manual/user_manual.html |
In `MODULE.bazel`, next to the `score_tooling` dep, add:
```
bazel_dep(name = "score_coverage", version = "0.2.0", dev_dependency = True)
```
Keep `score_tooling` (still needed for format/copyright/etc.). If the repo pins
`rules_rust` below `0.68.2-score`, bump it to `0.68.2-score` (score_coverage
requires it; bzlmod would select it anyway, the explicit bump keeps the file honest).
4. **Lockfile.** `bazel mod deps --lockfile_mode=update`.
5. **After run.** Same commands as step 2 with `@score_coverage//:generate_coverage_html`
and `--archive-dir cov_after`; copy the LCOV to `after.dat`.
6. **Compare.** `python3 compare_lcov.py before.dat after.dat`. Acceptance:
- `differing: 0` for common records;
- `only in before:` empty;
- `only in after:` empty, or only `_virtual_includes/` headers (these were wrongly
dropped by the old tool, see eclipse-score/baselibs#558). Each such header must
appear exactly once in the HTML archive (`grep -c '<header>.html' cov_after/index.html`).
- raw / effective percentages identical unless explained by the added headers.
Anything else: stop and report the diff. Do not commit.
7. **Commit and PR.** One commit, e.g. title `Migrate coverage pipeline to score_coverage 0.2.0`.
Body: what moved, label changes, rules_rust bump if any, and the comparison
table (files common/identical/new, totals before/after). Open the PR against
`main`, link the tracking issue, and paste the comparison table.
8. **CI.** Wait for the repo's coverage workflow and lockfile check. Report the
result, including any unrelated failure with its cause.Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsNo status
Activity
Migrate coverage pipeline to score_coverage 0.3.1 (#450)
[-]Rollout: migrate S-CORE modules from @score_tooling//coverage to score_coverage 0.2.0[/-][+]Rollout: migrate S-CORE modules from @score_tooling//coverage to score_coverage 0.3.1[/+]dcalavrezo-qorix commentedon Sep 30, 2026
Progress, 2026-09-30
Released: score_coverage 0.3.0 (2026-09-28, gcov backend for QNX on-target coverage) and 0.3.1 (2026-09-29,
--instrumentation_filter=^//<root>[/:]required in every coverage config, reporters warn when it is missing). Release notes. Target version for the rollout is 0.3.1.coverage/once the above are mergedEvery PR carries its before/after table in the description. "Headers recovered" means headers reached through include directories that the old pipeline dropped (coverage_tool#5, fixed in 0.2.0); nothing lost coverage anywhere.
Migrate coverage pipeline to score_coverage 0.3.1 (#267)
Migrate coverage pipeline to score_coverage 0.3.1 (#175)
Migrate coverage pipeline to score_coverage 0.3.0
Migrate coverage pipeline to score_coverage 0.3.0
chore(deps): update dependency score_coverage to v0.3.1 (eclipse-scor…
Migrate coverage pipeline to score_coverage 0.3.1 (#235)
dcalavrezo-qorix commentedon Oct 20, 2026
Progress update, 2026-10-20
Releases of
score_coveragesince the last update (release notes)score_coverage_scope(platform = ...). Fixes Scope is evaluated in the exec configuration: platform select()s resolve for the host, not the target coverage_tool#23: Bazel builds the coverage report generator in the exec configuration, soselect()s in the scope resolved for the host — on QNX runs the Linux variants appeared at 0 % and the QNX variants were missing. The scope rule now applies a platform transition (Evaluate the coverage scope for the run's platform coverage_tool#24); platform scopes must betags = ["manual"], and a scope root incompatible with the platform silently skips every test (documented as a known problem).-system-headers-coveragedata (reporter: read llvm-cov names displayed relative to the root coverage_tool#36) — previously all in-scope files could degrade to baseline-only.cc_binaryexecutables are collected as baseline objects, and baseline-only files are rendered correctly in the HTML report (untestedmain.cppno longer inherits another binary'smaincounts) — scope: a cc_binary executable is the baseline object of its sources coverage_tool#44. Rollout target version is now 0.4.2.Repository status
coverage_report_qnx.yml, first main run green 2026-10-12 — 278 tests, 89.27 %, 56score/os/qnxfiles measured (0 before). Gcov baseline follow-up merged (eclipse-score/baselibs#704); now fully on 0.4.2 (eclipse-score/baselibs#652 merged)coverage_scope_qnxis prepared and validated (QNX scope: 646 files vs 613 on Linux)Known blocker for the renovate bumps: score_devcontainer 1.11.1 was yanked (eclipse-score/bazel_registry#528/#529); logging pulls it via score_docs_as_code 8.3.0, so its score_coverage renovate PR stays red until the repo overrides to devcontainer 1.11.2 or a docs-as-code 8.3.1 ships (baselibs resolved this and is on 0.4.2).
Next: reference_integration migration, resume communication#1240 end of October, then deprecate
@score_tooling//coverage. A pattern-based scope (command-line aspect over//..., no per-platform deps lists) is under discussion as the 0.5.0 direction.[-]Rollout: migrate S-CORE modules from @score_tooling//coverage to score_coverage 0.3.1[/-][+]Rollout: migrate S-CORE modules from @score_tooling//coverage to score_coverage 0.4.2[/+]