Repository navigation
fix(auto-version): keep oSPARC metadata versions semver under dev stamps (unblocks verify-image-build; #695) - #697
Conversation
The develop-channel stamp fans the full X.Y.Z.devN into every [bumpversion:file:*] entry, including the 8 .osparc/*/metadata.yml service metadata files - whose schema (MetadataConfig, validated by 'ooil assemble-spec' in verify-image-build) requires strict semver. Every PR branched from a stamped develop therefore fails verify-image-build with string_pattern_mismatch on version '1.6.3.devN' (first surfaced on #694; systemic, tracked as #695). - .bumpversion.cfg: flag the 8 metadata entries semver-only = true - auto_version.py: semver-only entries are stamped (and gate-checked) with the .devN-stripped BASE; a dev stamp also self-heals metadata files left carrying the dev suffix by the pre-fix flow - one-time repair: metadata.yml 1.6.3.dev2 -> 1.6.3 (x8) - SPEC V5 amended: semver-only entries carry the base version Verified locally: check-pr passes on the repaired tree; injecting a dev suffix into one metadata.yml reproduces the §V5 drift rejection; simulated 'apply --to 1.6.3.dev3' keeps every metadata.yml at 1.6.3 while compose tags / pyproject / current_version take the dev version, with cmd_apply's built-in check_fanout green; self-heal from a dev-stamped metadata.yml verified.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #697 +/- ##
============================================
+ Coverage 50.63% 85.50% +34.87%
============================================
Files 107 109 +2
Lines 5350 12978 +7628
Branches 605 1353 +748
============================================
+ Hits 2709 11097 +8388
+ Misses 2563 1770 -793
- Partials 78 111 +33
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Clean human base bumps fail in both the new helper logic and the documented bump2version workflow.
Review effort: Balanced
Findings: 2
Open (2)
What changed in this PR
Keeps oSPARC metadata on strict semver while retaining .devN versions elsewhere.
Changes:
- Adds
semver-onlyfanout handling. - Repairs eight metadata versions.
- Documents the revised versioning invariant.
| File | Description |
|---|---|
SPEC.md |
Documents semver-only fanout. |
scripts/auto_version.py |
Implements base-version fanout and validation. |
.bumpversion.cfg |
Marks metadata entries semver-only. |
.osparc/flaskapi/metadata.yml |
Restores strict semver. |
.osparc/node/metadata.yml |
Restores strict semver. |
.osparc/proxy-uq-read/metadata.yml |
Restores strict semver. |
.osparc/proxy-uq-write/metadata.yml |
Restores strict semver. |
.osparc/proxy-sumo-read/metadata.yml |
Restores strict semver. |
.osparc/proxy-sumo-write/metadata.yml |
Restores strict semver. |
.osparc/proxy-moga-read/metadata.yml |
Restores strict semver. |
.osparc/proxy-moga-write/metadata.yml |
Restores strict semver. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Re-ports the frontend bits of ghost #665 (fork replay branch port/13-fixes-debt-sweep-665) onto the stacked slices 1-2: - InputVariableDist: log-flag clearing now anchors on the normal MEAN too (uniform min already covered) - the payload builders read `scale` verbatim, so a surviving flag shipped an invalid log-normal the backend V16 guard 400s (B24mk) - OutputVariableDist: manual scale toggle now merges functionally into the live per-uid map - a render-time snapshot could clobber an entry useAutoDetectQoiScale wrote for a sibling QoI (B25qr) - useAutoDetectQoiScale: the CV pair scores under the CURRENT input scales instead of an all-linear strawman (#663 audit); merged onto the slice-1 requestJson transport - SobolIndicesPlot/sobolIndices: log-flagged normal seeding checks support before proposing the mean+-3sigma box (B26st) - node SPEC: V12 amendment + T32mt row + B24mk/B25qr/B26st history Stacked on #697/#698 lineage (slices 1-2 of #70).
…Copilot #697) Both review findings share one root: after the semver-only split the fanout files no longer share a single searchable token, so the module must own every bump path. - apply: a semver-only entry's before-token is now whichever shape it legally holds - the full current version (pre-#695 dev-stamp, still self-healed) or the current BASE (the normal post-#695 state). The clean-base transition Copilot cited (cfg 1.6.3.dev2 + metadata 1.6.3, apply --to 1.6.4) no longer raises 'version drift?'. - new 'bump --part {patch|minor|major}': raises the base, drops the .devN counter, rewrites current_version + all 12 fanout entries via the same dual-shape logic, then re-checks the V5 fanout. 'make version-{patch|minor|major}' now runs it inside the same hermetic CI docker image (python 3.11, packaging 24.2, git 2.43, HOME=/tmp); bump2version retires - its single search = {current_version} cannot match split entries, which is exactly how the next required human base bump would have failed. SPEC: §I version cmd rewritten; §V5 names scripts/auto_version.py as the sole bump mutator (no bump2version). Verified in a sandboxed fixture repo (tags v1.6.1..v1.6.3): clean-base bump patch/minor/major -> 1.6.4/1.7.0/2.0.0, fanout green each time; self-heal + bot dev-bump unchanged; stale base (1.6.2 behind tag v1.6.3) refused; real drift (9.9.9) still raises, message naming both accepted shapes; the PRE-FIX script reproduces the drift failure on the clean state; the container recipe runs green end-to-end.
|
Both Copilot findings addressed in 2927066 (replies on each thread). One root, two symptoms: with the semver-only split the fanout files no longer share a single searchable token, so every bump path moved into |
Re-ports the frontend bits of ghost #665 (fork replay branch port/13-fixes-debt-sweep-665) onto the stacked slices 1-2: - InputVariableDist: log-flag clearing now anchors on the normal MEAN too (uniform min already covered) - the payload builders read `scale` verbatim, so a surviving flag shipped an invalid log-normal the backend V16 guard 400s (B24mk) - OutputVariableDist: manual scale toggle now merges functionally into the live per-uid map - a render-time snapshot could clobber an entry useAutoDetectQoiScale wrote for a sibling QoI (B25qr) - useAutoDetectQoiScale: the CV pair scores under the CURRENT input scales instead of an all-linear strawman (#663 audit); merged onto the slice-1 requestJson transport - SobolIndicesPlot/sobolIndices: log-flagged normal seeding checks support before proposing the mean+-3sigma box (B26st) - node SPEC: V12 amendment + T32mt row + B24mk/B25qr/B26st history Stacked on #697/#698 lineage (slices 1-2 of #70).
Re-ports the frontend bits of ghost #665 (fork replay branch port/13-fixes-debt-sweep-665) onto the stacked slices 1-2: - InputVariableDist: log-flag clearing now anchors on the normal MEAN too (uniform min already covered) - the payload builders read `scale` verbatim, so a surviving flag shipped an invalid log-normal the backend V16 guard 400s (B24mk) - OutputVariableDist: manual scale toggle now merges functionally into the live per-uid map - a render-time snapshot could clobber an entry useAutoDetectQoiScale wrote for a sibling QoI (B25qr) - useAutoDetectQoiScale: the CV pair scores under the CURRENT input scales instead of an all-linear strawman (#663 audit); merged onto the slice-1 requestJson transport - SobolIndicesPlot/sobolIndices: log-flagged normal seeding checks support before proposing the mean+-3sigma box (B26st) - node SPEC: V12 amendment + T32mt row + B24mk/B25qr/B26st history Stacked on #697/#698 lineage (slices 1-2 of #70).
Re-ports the frontend bits of ghost #665 (fork replay branch port/13-fixes-debt-sweep-665) onto the stacked slices 1-2: - InputVariableDist: log-flag clearing now anchors on the normal MEAN too (uniform min already covered) - the payload builders read `scale` verbatim, so a surviving flag shipped an invalid log-normal the backend V16 guard 400s (B24mk) - OutputVariableDist: manual scale toggle now merges functionally into the live per-uid map - a render-time snapshot could clobber an entry useAutoDetectQoiScale wrote for a sibling QoI (B25qr) - useAutoDetectQoiScale: the CV pair scores under the CURRENT input scales instead of an all-linear strawman (#663 audit); merged onto the slice-1 requestJson transport - SobolIndicesPlot/sobolIndices: log-flagged normal seeding checks support before proposing the mean+-3sigma box (B26st) - node SPEC: V12 amendment + T32mt row + B24mk/B25qr/B26st history Stacked on #697/#698 lineage (slices 1-2 of #70).
fix(auto-version): keep oSPARC metadata versions semver under dev stamps (unblocks verify-image-build; #695)

Why
verify-image-buildis currently broken for every PR branched fromdevelop— independent of the PR's content. TheAssemble docker compose specstep (ooil,MetadataConfig) fails with:Root cause: the auto-tag bot's dev stamp fans the full
X.Y.Z.devNversion into all[bumpversion:file:*]entries — including the 8.osparc/*/metadata.ymlservice metadata files, whose schema requires strict semver. The compose image tags legitimately carry.devN; the oSPARC metadata does not survive it. Since195632ec(bump dev version to 1.6.3.dev2 [skip ci]) is an ancestor ofdevelop's tip, every new PR branch inherits the failing combination — this is what turns #694'sverify-image-buildred (not the a11 bump itself), and the same will bite #696 and anything after. Systemic, tracked as #695.What
.bumpversion.cfg: the 8 metadata entries gainsemver-only = true.scripts/auto_version.py:semver-onlyentries are stamped — and gate-checked bycheck_fanout— with the.devN-stripped base; everything else (compose tags,Makefile,pyproject) keeps the full version. A dev stamp additionally self-heals any metadata file left carrying a dev suffix by the pre-fix flow. Since the fanout no longer shares one searchable token, every bump path now lives here: a newbump --part {patch|minor|major}raises the base (dropping.devN) through the same dual-shape rewrite.Makefile:make version-{patch|minor|major}routes toauto_version.py bump --partin the same hermetic CI docker image — bump2version is retired (its singlesearch = {current_version}cannot match split entries; Copilot caught that this would have broken the next human base bump).metadata.ymlfiles1.6.3.dev2 → 1.6.3(required so this PR's version-check gate passes; also repairsdevelopfor in-flight PRs the moment it merges).Verification (all local, this tree)
check-pr --target developon the repaired tree:develop: 1.6.3.dev2 unchanged, ok✅1.6.3.dev2back into onemetadata.ymlreproduces a §V5 drift rejection (fields: ['1.6.3.dev2'], expected '1.6.3') ✅apply --to 1.6.3.dev3: all 8 metadata files stay1.6.3while compose/pyproject/current_versionmove to1.6.3.dev3;cmd_apply's built-incheck_fanoutgreen ✅apply --to 1.6.3.dev3→ metadata normalized to1.6.3✅v1.6.1..v1.6.3): clean-statebump --part patch|minor|major→1.6.4/1.7.0/2.0.0, fanout green each;apply --to 1.6.4clean-base transition (the flagged hole — pre-fix script reproduces itsversion drift?failure) ✅; stale base behind a tag refused; genuine drift still raises, message naming both accepted shapes; the exact container recipe runs green end-to-end ✅Landing order
Merging this first unblocks the
verify-image-buildleg of #694 and #696 (both only need a re-run afterwards — no rebase required, the fix is base-side). Closes part of #695; the remaining exposure there (gen-baselines.shplainuv syncre-stampinguv.lock) is unaffected by this PR.