Skip to content

Conversation

@fatih-acar
Copy link
Contributor

@fatih-acar fatih-acar commented Oct 16, 2025

When bumping X.Y.9 to X.Y.10, the Helm chart version would not get bumped since the comparison was done on plain strings (it would not detect a new version).
Make use of the Python packaging Version type to compare versions instead and solve this issue.

Summary by CodeRabbit

  • Bug Fixes

    • Improved version comparison and parsing logic to properly handle prerelease versions and various edge cases in release version calculations
  • Refactor

    • Enhanced internal version management system with more robust version comparisons and accurate version increment calculations
    • Optimized dependency handling in release tooling to reduce unnecessary imports

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 16, 2025

Walkthrough

The pull request modifies tasks/release.py to use packaging.version.Version objects for version comparisons and manipulations within the update_helm_chart function. The implementation compares appVersion and Helm chart versions using Version objects instead of string parsing, handles prerelease scenarios, and increments version components via Version attributes. Version objects are converted back to strings before writing to YAML files. The function includes try/except error handling for Version-based comparisons with fallback printing for non-standard formats. A scoped import of packaging.version.Version is introduced to minimize dependency requirements.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "fix(tasks): version bump for helm charts" is directly aligned with the main objective described in the PR context. The PR addresses a specific issue where Helm chart version bumping from X.Y.9 to X.Y.10 was failing due to string-based comparison, and the fix implements proper semantic version comparison using Python's packaging.version.Version type. The title clearly communicates that this is a bug fix in the tasks module related to Helm chart versioning, which allows a teammate reviewing history to immediately understand the primary purpose of the change without requiring implementation details.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fac-fix-helm-version-bumper

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.

When bumping X.Y.9 to X.Y.10, the Helm chart version would not get
bumped since the comparison was done on plain strings (it would not
detect a new version).
Make use of the Python packaging Version type to compare versions
instead and solve this issue.

Signed-off-by: Fatih Acar <[email protected]>
@fatih-acar fatih-acar force-pushed the fac-fix-helm-version-bumper branch from d4e9d5f to 9a5559d Compare October 16, 2025 12:33
@fatih-acar fatih-acar marked this pull request as ready for review October 16, 2025 12:38
Copy link
Contributor

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tasks/release.py (1)

99-101: Enhance type hints and docstring per coding guidelines.

The function is missing a return type annotation and the docstring doesn't follow the required Google-style format with Args/Returns sections.

As per coding guidelines.

Apply this diff to add the return type hint:

-def update_helm_chart(context: Context, chart_repo: str | None = "helm/") -> None:  # noqa: ARG001
+def update_helm_chart(context: Context, chart_repo: str | None = "helm/") -> None:  # noqa: ARG001

Actually, the return type -> None is already present. Apply this diff to enhance the docstring:

-    """Update helm/Chart.yaml with the current version from pyproject.toml."""
+    """Update helm/Chart.yaml with the current version from pyproject.toml.
+
+    Compares the current app version from pyproject.toml with the version in Chart.yaml
+    and updates both the appVersion and chart version fields using semantic versioning.
+
+    Args:
+        context: Invoke context (unused but required by task decorator)
+        chart_repo: Path to the helm chart repository directory
+
+    Raises:
+        ValueError: If appVersion or version fields are missing from Chart.yaml
+    """
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7c944cd and 9a5559d.

📒 Files selected for processing (1)
  • tasks/release.py (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.py

📄 CodeRabbit inference engine (.github/instructions/python-docstring.instructions.md)

**/*.py: Use triple double quotes (""") for all Python docstrings
Write docstrings in Google-style format
Include a brief one-line description at the top of each docstring
Add a detailed description section when additional context is needed
Document function/method parameters under an Args/Parameters section without typing information
Include a Returns section describing the return value
Include a Raises section listing possible exceptions
Provide an Examples section demonstrating usage when helpful

Use ruff and mypy to validate and lint Python files

**/*.py: Use type hints for all Python function parameters and return values
Prefer asynchronous code in Python when feasible
Define asynchronous Python functions with async def
Use await for asynchronous calls in Python
Use Pydantic models instead of standard dataclasses
Use ruff and mypy for linting and type checking

**/*.py: Use type hints for all Python function parameters and return values
Use async/await whenever possible in Python code
Define asynchronous functions with async def
Await asynchronous calls with await
Use Pydantic models instead of standard dataclasses for data modeling
Use triple quotes (""") for all Python docstrings
Write docstrings in Google-style format
Include docstring sections when applicable: one-line summary, optional details, Args (without types), Returns, Raises, Examples
Validate and lint Python with ruff and mypy

Files:

  • tasks/release.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: E2E-testing-invoke-demo-start
  • GitHub Check: backend-docker-integration
  • GitHub Check: backend-tests-functional
  • GitHub Check: backend-tests-unit
  • GitHub Check: backend-tests-integration
🔇 Additional comments (3)
tasks/release.py (3)

103-104: LGTM! Scoped import is appropriate.

The local import with clear rationale avoids forcing the packaging dependency on all invoke users. This is a good pattern for optional tooling dependencies.


134-145: Narrow the exception handling and verify downgrade behavior.

The version comparison logic correctly addresses the PR objective of using semantic versioning instead of string comparison. However:

  1. The bare except Exception: on line 143 is too broad and could mask unexpected errors. Consider catching specific exceptions like InvalidVersion or AttributeError.

  2. The logic doesn't explicitly handle version downgrades (when app_version < old_app_version). Verify this is intentional behavior.

Apply this diff to narrow exception handling:

-        except Exception:
+        except (ValueError, AttributeError) as e:
             # Fallback in case app_version has non-standard format for Helm comparison
-            print(f"Warning: Unable to strictly compare versions, using default Helm chart version: {new_helm_version}")
+            print(f"Warning: Unable to strictly compare versions ({e}), using default Helm chart version: {new_helm_version}")

148-149: LGTM! String conversion timing is correct.

Converting Version objects to strings immediately before YAML serialization ensures proper formatting in the output files while maintaining semantic version comparisons in the logic.


# Get the app version directly from pyproject.toml
app_version = get_version_from_pyproject() # Returns a string like '1.1.0a1'
app_version = Version(get_version_from_pyproject()) # Returns a string like '1.1.0a1'
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add exception handling for malformed version strings.

If get_version_from_pyproject() returns a non-PEP 440 compliant version string, Version() will raise InvalidVersion, crashing the task. Consider wrapping in a try-except block to provide a clearer error message.

Apply this diff to add error handling:

-    app_version = Version(get_version_from_pyproject())  # Returns a string like '1.1.0a1'
+    try:
+        app_version = Version(get_version_from_pyproject())  # Returns a string like '1.1.0a1'
+    except Exception as e:
+        raise ValueError(f"Invalid version in pyproject.toml: {e}") from e
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
app_version = Version(get_version_from_pyproject()) # Returns a string like '1.1.0a1'
try:
app_version = Version(get_version_from_pyproject()) # Returns a string like '1.1.0a1'
except Exception as e:
raise ValueError(f"Invalid version in pyproject.toml: {e}") from e
🤖 Prompt for AI Agents
In tasks/release.py around line 107, the call creating
Version(get_version_from_pyproject()) can raise packaging.version.InvalidVersion
for malformed/non-PEP440 strings; wrap that call in a try-except that catches
InvalidVersion, include the offending version string in a clear error message,
and exit or re-raise a more descriptive exception so the task fails with
actionable output; also ensure packaging.version.InvalidVersion is imported or
referenced correctly.

Comment on lines +118 to 123
old_app_version = Version(chart_yaml.get("appVersion", ""))
if old_app_version == app_version:
print(
f"{str(chart_path)} updates not required, `appVersion` of {old_app_version} matches current from `pyproject.toml`"
)
return
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify early return doesn't skip remaining charts.

Line 123 uses return within a loop over multiple charts. If the first chart doesn't need updating, the function exits without processing remaining charts. Verify this is intentional, or consider using continue instead.

Run the following script to check how charts are processed:


🏁 Script executed:

#!/bin/bash
# Description: Verify behavior when first chart doesn't need updates

# Check the loop structure and return/continue usage
ast-grep --pattern $'for chart in $$$:
  $$$
  if $COND:
    $$$
    return
  $$$'

Length of output: 0


🏁 Script executed:

#!/bin/bash
sed -n '90,140p' tasks/release.py

Length of output: 2231


Replace return with continue to process all charts. The return inside the loop at tasks/release.py (around line 123) exits the function after the first matching chart, skipping the rest; use continue instead.

🤖 Prompt for AI Agents
In tasks/release.py around lines 118 to 123, the loop currently uses return when
a chart's appVersion already matches the pyproject version, which exits the
entire function and skips remaining charts; change that return to continue so
the loop proceeds to the next chart and all charts are processed. Ensure no
other control flow relies on the function exiting at that point and preserve the
existing print message before continuing.

@codspeed-hq
Copy link

codspeed-hq bot commented Oct 16, 2025

CodSpeed Performance Report

Merging #7419 will not alter performance

Comparing fac-fix-helm-version-bumper (9a5559d) with stable (09e3dea)1

Summary

✅ 10 untouched

Footnotes

  1. No successful run was found on stable (7c944cd) during the generation of this report, so 09e3dea was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants