Skip to content

Fix bump-minor-version to treat version as major.minor integers#3222

Open
st3penta wants to merge 1 commit intoconforma:mainfrom
st3penta:EC-1705
Open

Fix bump-minor-version to treat version as major.minor integers#3222
st3penta wants to merge 1 commit intoconforma:mainfrom
st3penta:EC-1705

Conversation

@st3penta
Copy link
Copy Markdown
Contributor

@st3penta st3penta commented Apr 9, 2026

The previous yq expression treated VERSION as a float, causing 0.9
to bump to 1.0 instead of 0.10. Replace with string-based approach
that splits on ".", increments the minor component as an integer,
and reassembles.

Co-Authored-By: Claude Opus 4.6 noreply@anthropic.com

Ref: https://issues.redhat.com/browse/EC-1705

The previous yq expression treated VERSION as a float, causing 0.9
to bump to 1.0 instead of 0.10. Replace with string-based approach
that splits on ".", increments the minor component as an integer,
and reassembles.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

Ref: https://issues.redhat.com/browse/EC-1705
@qodo-code-review
Copy link
Copy Markdown
Contributor

Review Summary by Qodo

Fix bump-minor-version to handle version integers correctly

🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Fix version bumping to treat major.minor as integers
• Replace float-based yq expression with string manipulation
• Prevents 0.9 from incorrectly bumping to 1.0
• Now correctly bumps 0.9 to 0.10
Diagram
flowchart LR
  A["Float-based yq expression"] -->|"treats 0.9 as float"| B["Incorrect: 0.9 → 1.0"]
  C["String-based yq expression"] -->|"splits and increments minor"| D["Correct: 0.9 → 0.10"]
Loading

Grey Divider

File Changes

1. Makefile 🐞 Bug fix +1/-1

Update bump-minor-version yq expression logic

• Replaced yq expression in bump-minor-version target
• Changed from arithmetic float calculation to string manipulation
• New expression splits version on ".", increments minor component as integer, and reassembles
• Fixes version bumping logic for semantic versioning

Makefile


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown
Contributor

qodo-code-review bot commented Apr 9, 2026

Code Review by Qodo

🐞 Bugs (1)   📘 Rule violations (0)   📎 Requirement gaps (0)   🎨 UX Issues (0)
🐞\ ≡ Correctness (1)

Grey Divider


Action required

1. Minor bump breaks at .10 🐞
Description
The new bump-minor-version yq expression still depends on YAML numeric parsing, so when VERSION
becomes 0.10 it can be parsed as the number 0.1 and then bumped to 0.2 instead of 0.11. This
will break future minor bumps and the repo’s release process that assumes VERSION is a stable
major.minor string.
Code

Makefile[379]

+	@yq '(. | to_string | split(".") | .[0] + "." + (.[1] | to_number + 1 | to_string))' -i $(VERSION_FILE) && \
Evidence
VERSION is a plain unquoted scalar (0.9 today). bump-minor-version runs yq in normal YAML mode
(-i $(VERSION_FILE)), so yq type-infers numeric-looking scalars; once the file contains 0.10,
YAML numeric resolution normalizes it to 0.1 before to_string, causing the split/increment logic
to treat the minor as 1 not 10. Downstream scripts explicitly assume VERSION is major.minor
and will be used repeatedly across releases.

Makefile[378-383]
VERSION[1-1]
hack/derive-version.sh[22-36]
hack/cut-release.sh[28-34]

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

## Issue description
`make bump-minor-version` still lets yq parse VERSION as a YAML number, which can normalize `0.10` to `0.1` before `to_string`, causing `0.10` → `0.2` instead of `0.11`.

## Issue Context
The VERSION file is a plain scalar (not quoted YAML), and `bump-minor-version` edits it in-place with yq. The intent is to treat VERSION as a `major.minor` string and bump the minor as an integer.

## Fix
Update the Makefile target to force raw/string IO so yq never type-infers numbers from VERSION contents. For example:
- Use yq raw input/output modes (e.g., `-p=raw -o=raw`), then split/increment.
- Keep the file content unquoted (so scripts that do `cat VERSION` still work), but ensure yq reads it as raw text.

## Fix Focus Areas
- Makefile[378-383]

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


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 9, 2026

📝 Walkthrough

Walkthrough

Modified the bump-minor-version Make target in the Makefile to use string-based dotted component parsing instead of arithmetic operations for calculating the new version number. The target now extracts the minor version segment, increments it, and reconstructs the version string.

Changes

Cohort / File(s) Summary
Makefile version bumping logic
Makefile
Refactored bump-minor-version target: replaced arithmetic-based version increment ((((. * 10) + 1) / 10)) with string parsing that splits the version on dots, increments the minor component, and reconstructs the major.minor string.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: fixing the bump-minor-version logic to properly treat versions as major.minor integers instead of floats.
Description check ✅ Passed The description is directly related to the changeset, explaining the problem (0.9 bumping to 1.0 instead of 0.10), the solution (string-based approach), and providing context with an issue reference.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

# It's not so hard to do this by hand, but let's save some typing
bump-minor-version:
@yq '(((. * 10) + 1) / 10)' -i $(VERSION_FILE) && \
@yq '(. | to_string | split(".") | .[0] + "." + (.[1] | to_number + 1 | to_string))' -i $(VERSION_FILE) && \
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Minor bump breaks at .10 🐞 Bug ≡ Correctness

The new bump-minor-version yq expression still depends on YAML numeric parsing, so when VERSION
becomes 0.10 it can be parsed as the number 0.1 and then bumped to 0.2 instead of 0.11. This
will break future minor bumps and the repo’s release process that assumes VERSION is a stable
major.minor string.
Agent Prompt
## Issue description
`make bump-minor-version` still lets yq parse VERSION as a YAML number, which can normalize `0.10` to `0.1` before `to_string`, causing `0.10` → `0.2` instead of `0.11`.

## Issue Context
The VERSION file is a plain scalar (not quoted YAML), and `bump-minor-version` edits it in-place with yq. The intent is to treat VERSION as a `major.minor` string and bump the minor as an integer.

## Fix
Update the Makefile target to force raw/string IO so yq never type-infers numbers from VERSION contents. For example:
- Use yq raw input/output modes (e.g., `-p=raw -o=raw`), then split/increment.
- Keep the file content unquoted (so scripts that do `cat VERSION` still work), but ensure yq reads it as raw text.

## Fix Focus Areas
- Makefile[378-383]

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This concern has been empirically disproven with yq v4.47.1 (the version used by this project). While yq does parse 0.10 as !!float internally, to_string preserves the original scalar representation -- to_string on 0.10 returns "0.10", not "0.1". The full round-trip 0.9 -> 0.10 -> 0.11 was verified both via pipe and via yq -i file writes.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Makefile`:
- Line 379: The bump-minor-version target currently uses yq on $(VERSION_FILE)
which parses "0.10" as a YAML number and normalizes it to "0.1", causing
incorrect bumps; replace the yq-based expression with a plain-text string
split-and-increment implementation (e.g., use shell parameter expansion, awk, or
sed) that reads VERSION_FILE, splits on the dot, increments the minor component
as an integer while preserving any leading/trailing digits (so "0.10" ->
"0.11"), and writes the new version back to VERSION_FILE; update the line that
contains `@yq` '(. | to_string | split(".") | .[0] + "." + (.[1] | to_number + 1 |
to_string))' -i $(VERSION_FILE) to this string-safe approach.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 642e7582-22b6-4550-a069-c5f993542ed9

📥 Commits

Reviewing files that changed from the base of the PR and between ab3d427 and 46d6ba9.

📒 Files selected for processing (1)
  • Makefile

# It's not so hard to do this by hand, but let's save some typing
bump-minor-version:
@yq '(((. * 10) + 1) / 10)' -i $(VERSION_FILE) && \
@yq '(. | to_string | split(".") | .[0] + "." + (.[1] | to_number + 1 | to_string))' -i $(VERSION_FILE) && \
Copy link
Copy Markdown

@coderabbitai coderabbitai bot Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

expr='(. | to_string | split(".") | .[0] + "." + (.[1] | to_number + 1 | to_string))'
tmp="$(mktemp)"
trap 'rm -f "$tmp"' EXIT

printf '0.9\n' > "$tmp"
yq "$expr" -i "$tmp"
first="$(cat "$tmp")"

yq "$expr" -i "$tmp"
second="$(cat "$tmp")"

printf 'After first bump:  %s\n' "$first"
printf 'After second bump: %s\n' "$second"

# Expected:
# After first bump:  0.10
# After second bump: 0.11

Repository: conforma/cli

Length of output: 98


🏁 Script executed:

# First, examine the Makefile and understand the context
head -n 390 Makefile | tail -n 20

Repository: conforma/cli

Length of output: 843


🏁 Script executed:

# Find and inspect the VERSION file and related version scripts
git ls-files | grep -i version | head -20

Repository: conforma/cli

Length of output: 346


🏁 Script executed:

# Install yq and test the specific YAML behavior
pip install yq > /dev/null 2>&1

# Now run the verification test
#!/bin/bash
set -euo pipefail

expr='(. | to_string | split(".") | .[0] + "." + (.[1] | to_number + 1 | to_string))'
tmp="$(mktemp)"
trap 'rm -f "$tmp"' EXIT

printf '0.9\n' > "$tmp"
yq "$expr" -i "$tmp"
first="$(cat "$tmp")"

yq "$expr" -i "$tmp"
second="$(cat "$tmp")"

printf 'After first bump:  %s\n' "$first"
printf 'After second bump: %s\n' "$second"

Repository: conforma/cli

Length of output: 99


🏁 Script executed:

# Install yq command-line tool
apt-get update > /dev/null 2>&1 && apt-get install -y yq > /dev/null 2>&1

# Verify yq is available
which yq

# Now run the verification test
#!/bin/bash
set -euo pipefail

expr='(. | to_string | split(".") | .[0] + "." + (.[1] | to_number + 1 | to_string))'
tmp="$(mktemp)"
trap 'rm -f "$tmp"' EXIT

printf '0.9\n' > "$tmp"
echo "Initial content:"
cat "$tmp"

yq "$expr" -i "$tmp"
first="$(cat "$tmp")"
echo "After first bump:  $first"

yq "$expr" -i "$tmp"
second="$(cat "$tmp")"
echo "After second bump: $second"

echo ""
echo "Expected: 0.10, then 0.11"
echo "Actual:   $first, then $second"

# Test with more iterations to show the pattern
printf '0.9\n' > "$tmp"
for i in {1..5}; do
  yq "$expr" -i "$tmp"
  echo "Bump $i: $(cat "$tmp")"
done

Repository: conforma/cli

Length of output: 181


🏁 Script executed:

# Check the VERSION file content
cat VERSION

Repository: conforma/cli

Length of output: 59


🏁 Script executed:

# Examine the derive-version.sh script referenced in the review
cat hack/derive-version.sh

Repository: conforma/cli

Length of output: 2823


🏁 Script executed:

# Examine the version.go file that consumes the VERSION
cat internal/version/version.go

Repository: conforma/cli

Length of output: 3373


🌐 Web query:

yq YAML numeric normalization 0.10 becomes 0.1 scalar string behavior

💡 Result:

In YAML, 0.10 and 0.1 are the same numeric (float) value; the trailing zero is just presentation. When yq parses YAML and then re-emits it, the emitter will typically serialize floats in a normalized form, so 0.10 often comes back out as 0.1. This happens because the Go YAML emitter used by mikefarah/yq formats floats with strconv.FormatFloat(..., 'g', -1, ...), which drops unnecessary trailing zeros. [1]

How to keep 0.10 from becoming 0.1

You must store it as a string, not a number:

  • In YAML input: version: "0.10" (quoted)
  • When setting values with yq, force a string tag (quotes alone may not be enough in some yq versions/paths):
    • use --tag '!!str' to override type parsing and keep it as a string. [2][3]

Once it’s a string, yq will treat it as a scalar string (not a float), so it won’t be normalized to 0.1 unless you explicitly convert/cast it to a number. [2]

Bottom line: if you need to preserve trailing zeros (version numbers, IDs, fixed-precision “decimals”), encode them as strings (optionally with !!str), because YAML floats don’t preserve formatting. [1][2]

Sources:
[1] go-yaml/yaml encoder float formatting (FormatFloat with 'g') https://chromium.googlesource.com/external/github.com/go-yaml/yaml/+/refs/tags/v3.0.0/encode.go
[2] yq “Value Parsing” docs (type inference, --tag to force string) https://mikefarah.gitbook.io/yq/v3.x/usage/value-parsing
[3] yq v3 “Upgrading from V2” (--tag '!!str' examples) https://mikefarah.gitbook.io/yq/v3.x/upgrading-from-v2


Avoid YAML numeric normalization in bump-minor-version target

Line 379 applies yq to a plain text VERSION file. When 0.10 is written to the file, yq will parse it as a YAML numeric value on the next invocation and normalize it to 0.1 (YAML floats drop trailing zeros). The subsequent bump then becomes 0.2 instead of 0.11, silently regressing the version number.

Hardening the target to use plain string operations (avoiding YAML parsing) ensures consistent, predictable version incrementing:

Suggested fix
 bump-minor-version:
-	`@yq` '(. | to_string | split(".") | .[0] + "." + (.[1] | to_number + 1 | to_string))' -i $(VERSION_FILE) && \
+	`@major`=$$(cut -d. -f1 $(VERSION_FILE)); \
+	  minor=$$(cut -d. -f2 $(VERSION_FILE)); \
+	  case "$$major.$$minor" in \
+	    ''|*[^0-9.]*|*.*.*) echo "Invalid VERSION format (expected major.minor): $$(cat $(VERSION_FILE))" >&2; exit 1 ;; \
+	  esac; \
+	  tmp=$$(mktemp); \
+	  printf '%s.%s\n' "$$major" "$$((minor + 1))" > "$$tmp" && mv "$$tmp" $(VERSION_FILE) && \
 	  git add $(VERSION_FILE) && \
 	  git commit $(VERSION_FILE) \
 	    -m "Bump minor version to $$(cat $(VERSION_FILE))" \
 	    -m 'Commit generated with `make bump-minor-version`'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Makefile` at line 379, The bump-minor-version target currently uses yq on
$(VERSION_FILE) which parses "0.10" as a YAML number and normalizes it to "0.1",
causing incorrect bumps; replace the yq-based expression with a plain-text
string split-and-increment implementation (e.g., use shell parameter expansion,
awk, or sed) that reads VERSION_FILE, splits on the dot, increments the minor
component as an integer while preserving any leading/trailing digits (so "0.10"
-> "0.11"), and writes the new version back to VERSION_FILE; update the line
that contains `@yq` '(. | to_string | split(".") | .[0] + "." + (.[1] | to_number
+ 1 | to_string))' -i $(VERSION_FILE) to this string-safe approach.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This concern has been empirically disproven with yq v4.47.1 (the version used by this project). While yq does parse 0.10 as !!float internally, to_string preserves the original scalar representation -- to_string on 0.10 returns "0.10", not "0.1". The full round-trip 0.9 -> 0.10 -> 0.11 was verified both via pipe and via yq -i file writes.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@st3penta, thank you for the empirical verification — I stand corrected. The to_string function in yq v4.47.1 does preserve the original scalar representation even for floats like 0.10, making the full round-trip 0.9 → 0.10 → 0.11 work correctly. My concern was unfounded for this version.


📝 Learnings were identified and not saved (knowledge base disabled). Enable

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

Flag Coverage Δ
acceptance 55.18% <ø> (+<0.01%) ⬆️
generative 17.90% <ø> (ø)
integration 26.65% <ø> (ø)
unit 69.01% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Member

@simonbaird simonbaird left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants