✨ add bump-nuget script for simplified package version updates#19
✨ add bump-nuget script for simplified package version updates#19gimlichael merged 1 commit intomainfrom
Conversation
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Pull request overview
This PR adds a new Python script to automate NuGet package version updates during service updates. The script selectively bumps only packages published by a triggering source repository (like Cuemon, Savvyio, or other Codebelt packages), leaving third-party packages unchanged.
Changes:
- Added
bump-nuget.pyscript that reads environment variables to determine which packages to update - Implements source-aware package filtering using a prefix-based mapping system
- Updates
Directory.Packages.propsfile in-place with new package versions
| r"<PackageVersion\b" | ||
| r'(?=[^>]*\bInclude="([^"]+)")' | ||
| r'(?=[^>]*\bVersion="([^"]+)")' | ||
| r"[^>]*>", |
There was a problem hiding this comment.
The regex pattern uses positive lookahead assertions to capture the Include and Version attributes. However, the pattern doesn't enforce the closing /> or </PackageVersion>. While the pattern captures up to >, it should be more specific to handle self-closing tags properly. Consider using r"<PackageVersion\b(?=[^>]*\bInclude=\"([^\"]+)\")(?=[^>]*\bVersion=\"([^\"]+)\")[^>]*/>" to specifically match self-closing tags, which is the standard format in Directory.Packages.props files.
| r"[^>]*>", | |
| r"[^>]*/>", |
| with open("Directory.Packages.props", "w") as f: | ||
| f.write(new_content) |
There was a problem hiding this comment.
The script writes to Directory.Packages.props without creating a backup or using atomic write operations. If the write operation fails partway through (e.g., disk full, interrupted process), the file could be corrupted. Consider using a safer pattern: write to a temporary file first, then rename it to replace the original (atomic operation on most filesystems), or at least create a backup before writing.
| with open("Directory.Packages.props", "w") as f: | ||
| f.write(new_content) |
There was a problem hiding this comment.
The error handling for FileNotFoundError is good, but other exceptions during file operations (like PermissionError, IOError when writing) are not caught. Consider adding exception handling around the file write operation on lines 126-127 to provide a more helpful error message if the write fails.
| with open("Directory.Packages.props", "w") as f: | |
| f.write(new_content) | |
| try: | |
| with open("Directory.Packages.props", "w") as f: | |
| f.write(new_content) | |
| except (PermissionError, OSError) as exc: | |
| print(f"Error: Failed to write Directory.Packages.props: {exc}") | |
| sys.exit(1) |
| with open("Directory.Packages.props", "w") as f: | ||
| f.write(new_content) | ||
|
|
||
| return 0 if changes else 0 # Return 0 even if no changes (not an error) |
There was a problem hiding this comment.
The return statement on line 129 contains redundant logic. The expression 0 if changes else 0 always evaluates to 0 regardless of whether there are changes or not. If the intention is to return 0 in all cases (as the comment suggests), simplify this to return 0.
| return 0 if changes else 0 # Return 0 even if no changes (not an error) | |
| return 0 # Return 0 even if no changes (not an error) |
| return m.group(0).replace( | ||
| f'Version="{current}"', f'Version="{target_version}"' |
There was a problem hiding this comment.
The version replacement logic on lines 96-97 has a potential bug. It uses m.group(0).replace() which will replace ALL occurrences of the pattern within the matched string. If the old version number appears elsewhere in the matched element (e.g., in an attribute name or comment), it could be incorrectly replaced. Consider using a more targeted replacement that specifically replaces the Version attribute value, or reconstruct the entire match string with the new version.
| return m.group(0).replace( | |
| f'Version="{current}"', f'Version="{target_version}"' | |
| return re.sub( | |
| r'\bVersion="[^"]+"', | |
| f'Version="{target_version}"', | |
| m.group(0), | |
| count=1, |
| import re | ||
| import os |
There was a problem hiding this comment.
The imports should follow PEP 8 conventions by grouping standard library imports separately from third-party imports (though all imports here are standard library). However, the from typing import statement should typically come after the regular imports. Consider reordering to: import os, import re, import sys, then from typing import Dict, List for consistency with Python conventions.
| import re | |
| import os | |
| import os | |
| import re |
No description provided.