-
Notifications
You must be signed in to change notification settings - Fork 26
Implement Schema Version Update Automation #276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| name: Auto Version Bump | ||
|
|
||
| on: | ||
| pull_request: | ||
| types: [labeled] | ||
|
|
||
| jobs: | ||
| bump-version: | ||
| if: > | ||
| github.event.label.name == 'patch' || | ||
| github.event.label.name == 'minor' || | ||
| github.event.label.name == 'major' || | ||
| github.event.label.name == 'release' | ||
| runs-on: ubuntu-latest | ||
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - name: Set up Python | ||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: "3.11" | ||
|
|
||
| - name: Run version bump script | ||
| run: | | ||
| python tools/bump_version.py ${{ github.event.label.name }} | ||
|
|
||
| - name: Create Pull Request | ||
| uses: peter-evans/create-pull-request@v5 | ||
| with: | ||
| commit-message: "chore: bump version (${{ github.event.label.name }})" | ||
| title: "chore: bump version (${{ github.event.label.name }})" | ||
| body: | | ||
| This version bump was triggered by PR #${{ github.event.pull_request.number }} | ||
| Label applied: **${{ github.event.label.name }}** | ||
| labels: version-bump | ||
| base: main | ||
| branch: auto-version-bump/${{ github.event.pull_request.number }} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| import sys | ||
|
|
||
| # The GitHub label passed as an argument: patch, minor, major, release | ||
| LABEL = sys.argv[1] | ||
|
|
||
| # The file that stores the current version | ||
| VERSION_FILE = "version.txt" | ||
|
|
||
| def read_version(): | ||
| """Read the current version from version.txt""" | ||
| with open(VERSION_FILE, "r") as f: | ||
| return f.read().strip() | ||
|
|
||
| def write_version(version): | ||
| """Write the new version back to version.txt""" | ||
| with open(VERSION_FILE, "w") as f: | ||
| f.write(version + "\n") | ||
|
|
||
| def parse_version(v): | ||
| """ | ||
| Parse a version string like "0.5.0-draft" into parts: | ||
| major, minor, patch, and optional suffix (e.g., "-draft"). | ||
| """ | ||
| parts = v.split(".") # Split into ['0', '5', '0-draft'] | ||
| major = int(parts[0]) | ||
| minor = int(parts[1]) | ||
|
|
||
| # Handle patch number and suffix(if exist) | ||
| if "-" in parts[2]: | ||
| patch_str, suffix = parts[2].split("-", 1) | ||
| patch = int(patch_str) | ||
| suffix = "-" + suffix # Keep the dash in the suffix | ||
| else: | ||
| patch = int(parts[2]) | ||
| suffix = "" | ||
|
|
||
| return major, minor, patch, suffix | ||
|
|
||
|
|
||
| def bump_version(major, minor, patch): | ||
| """ | ||
| Increment the version based on LABEL: | ||
| - patch: increment patch | ||
| - minor: increment minor, reset patch | ||
| - major: increment major, reset minor and patch | ||
| """ | ||
| if LABEL == "patch": | ||
| patch = patch + 1 | ||
| elif LABEL == "minor": | ||
| minor = minor + 1 | ||
| patch = 0 | ||
| elif LABEL == "major": | ||
| major = major + 1 | ||
| minor = 0 | ||
| patch = 0 | ||
| return major, minor, patch | ||
|
|
||
| def main(): | ||
| # Read current version | ||
| old_version = read_version() | ||
|
|
||
| # Parse current version | ||
| major, minor, patch, suffix = parse_version(old_version) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens to suffix?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the question! The suffix is parsed so that I can correctly separate the numeric patch value from any trailing suffix such as -draft. I designed the logic under the assumption that versions should always include -draft unless the label is release, in which case the suffix is intentionally removed. So the suffix is extracted purely so the script can reliably parse versions like 0.5.0-draft without errors, and so a release label can strip the suffix. Outside of that case, the script intentionally replaces the suffix with -draft on all non-release bumps. |
||
|
|
||
| # If label is release, remove the "-draft" suffix | ||
| if LABEL == "release": | ||
| new_version = f"{major}.{minor}.{patch}" | ||
| else: | ||
| # Otherwise, bump version according to label | ||
| new_major, new_minor, new_patch = bump_version(major, minor, patch) | ||
| new_version = f"{new_major}.{new_minor}.{new_patch}-draft" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can't we use suffix here?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As mentioned, the original assumption was that only finalized releases should omit the -draft suffix. That’s why I intentionally append -draft during version bumps, so all non-release versions are clearly marked. If the goal is to preserve existing suffixes (potentially for more complex cases in the future like -beta) the logic can certainly be updated to consistently use the parsed suffix instead of forcing -draft. The current implementation mainly ensures that non-release versions are easily distinguishable from official releases. |
||
|
|
||
| # Prevent race conditions by only writing if version changed | ||
| if new_version != old_version: | ||
| write_version(new_version) | ||
| print(f"Version updated: {old_version} -> {new_version}") | ||
| else: | ||
| print(f"No version change needed. Current version: {old_version}") | ||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: maybe instead we could have just 3 new variables, and we should probably throw an exception for unknown LABELs
Additionally, we may need a suffix or prefix potentially, e.g. "v1.0.0-beta". But I think that can come when we need it. It looks like you started some functionality for suffix, but I dont think it's done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks you for the feedback!
I understand the suggestion to use three new variables, it does make the bump logic more explicit and clear. I also see your point about throwing an exception for unknown labels. In the current setup, the GitHub workflow only passes predefined labels (patch, minor, major, release), so in practice an exception isn’t strictly necessary.
That said, adding an exception could serve as a useful safeguard if someone were to run the script manually with an invalid label. I’ll update the script to incorporate both of these suggestions.