tooling: Add version bump target to Makefile.#237
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a release helper to standardize semantic version bumps via make bump, aligning repo tooling and documentation around a simple tagging workflow.
Changes:
- Introduce
make bumptarget that computes the next semver, updatespyproject.toml, commits, tags, and pushes. - Add safety checks (must be on
main, working tree must be clean). - Document the release workflow in
CONTRIBUTING.md.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| Makefile | Adds a bump target to automate version updates, tagging, and pushing with safety checks. |
| CONTRIBUTING.md | Documents how to run make bump and what it does. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| git tag "$$NEXT"; \ | ||
| git push origin main "$$NEXT"; \ |
There was a problem hiding this comment.
This creates a lightweight tag (git tag "$NEXT"), but the linked issue’s desired behavior calls for an annotated tag. If annotated tags are required for releases, switch to creating an annotated tag (and include a message), so metadata is preserved and git describe behaves as expected.
| @LAST=$$(git tag --sort=-v:refname | head -1); \ | ||
| if [ -z "$$LAST" ]; then \ | ||
| NEXT="v1.0.0"; \ | ||
| else \ | ||
| MAJOR=$$(echo "$$LAST" | sed 's/^v//' | cut -d. -f1); \ | ||
| MINOR=$$(echo "$$LAST" | sed 's/^v//' | cut -d. -f2); \ | ||
| PATCH=$$(echo "$$LAST" | sed 's/^v//' | cut -d. -f3); \ | ||
| case "$(PART)" in \ | ||
| major) MAJOR=$$((MAJOR + 1)); MINOR=0; PATCH=0 ;; \ | ||
| minor) MINOR=$$((MINOR + 1)); PATCH=0 ;; \ | ||
| patch) PATCH=$$((PATCH + 1)) ;; \ | ||
| *) echo "Error: PART must be patch, minor or major."; exit 1 ;; \ | ||
| esac; \ | ||
| NEXT="v$$MAJOR.$$MINOR.$$PATCH"; \ | ||
| fi; \ | ||
| echo "$$LAST → $$NEXT"; \ | ||
| sed -i "s/^version = \".*\"/version = \"$${NEXT#v}\"/" pyproject.toml; \ | ||
| git add pyproject.toml; \ | ||
| git commit -m "chore: Bump version to $$NEXT."; \ | ||
| git tag "$$NEXT"; \ | ||
| git push origin main "$$NEXT"; \ | ||
| echo "Tag $$NEXT pushed to origin." |
There was a problem hiding this comment.
Because this Makefile uses .ONESHELL, the long command chain starting here uses ; separators, so failures from sed, git commit, git tag, or git push may not stop the target (the final echo will still exit 0). Consider enabling fail-fast for this recipe (e.g., set -e at the start of the bump recipe or chaining critical commands with &&) so make bump reliably fails on errors and doesn't leave the repo in a partially-updated state.
| NEXT="v$$MAJOR.$$MINOR.$$PATCH"; \ | ||
| fi; \ | ||
| echo "$$LAST → $$NEXT"; \ | ||
| sed -i "s/^version = \".*\"/version = \"$${NEXT#v}\"/" pyproject.toml; \ |
There was a problem hiding this comment.
sed -i is not portable across GNU/BSD sed (e.g., macOS requires sed -i '' ...). Since this target is intended for contributors’ local environments, consider switching to a cross-platform edit approach (e.g., a small Python one-liner) or handling GNU vs BSD sed explicitly.
| sed -i "s/^version = \".*\"/version = \"$${NEXT#v}\"/" pyproject.toml; \ | |
| VERSION=$${NEXT#v}; \ | |
| python - "$$VERSION" << 'PY'; \ | |
| import sys | |
| import pathlib | |
| import re | |
| path = pathlib.Path("pyproject.toml") | |
| text = path.read_text() | |
| version = sys.argv[1] | |
| text = re.sub(r'^version = ".*"$', f'version = "{version}"', text, count=1, flags=re.MULTILINE) | |
| path.write_text(text) | |
| PY |
| MAJOR=$$(echo "$$LAST" | sed 's/^v//' | cut -d. -f1); \ | ||
| MINOR=$$(echo "$$LAST" | sed 's/^v//' | cut -d. -f2); \ | ||
| PATCH=$$(echo "$$LAST" | sed 's/^v//' | cut -d. -f3); \ | ||
| case "$(PART)" in \ | ||
| major) MAJOR=$$((MAJOR + 1)); MINOR=0; PATCH=0 ;; \ | ||
| minor) MINOR=$$((MINOR + 1)); PATCH=0 ;; \ | ||
| patch) PATCH=$$((PATCH + 1)) ;; \ | ||
| *) echo "Error: PART must be patch, minor or major."; exit 1 ;; \ | ||
| esac; \ | ||
| NEXT="v$$MAJOR.$$MINOR.$$PATCH"; \ |
There was a problem hiding this comment.
The bump logic assumes the latest tag is exactly v<major>.<minor>.<patch>. If the repo ever has non-semver tags (e.g., v1.2.3-rc1) or tags without a leading v, MAJOR/MINOR/PATCH parsing and arithmetic can fail. Add a validation step (regex match) and error out with a clear message when LAST isn't a supported format.
| MAJOR=$$(echo "$$LAST" | sed 's/^v//' | cut -d. -f1); \ | |
| MINOR=$$(echo "$$LAST" | sed 's/^v//' | cut -d. -f2); \ | |
| PATCH=$$(echo "$$LAST" | sed 's/^v//' | cut -d. -f3); \ | |
| case "$(PART)" in \ | |
| major) MAJOR=$$((MAJOR + 1)); MINOR=0; PATCH=0 ;; \ | |
| minor) MINOR=$$((MINOR + 1)); PATCH=0 ;; \ | |
| patch) PATCH=$$((PATCH + 1)) ;; \ | |
| *) echo "Error: PART must be patch, minor or major."; exit 1 ;; \ | |
| esac; \ | |
| NEXT="v$$MAJOR.$$MINOR.$$PATCH"; \ | |
| if echo "$$LAST" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+$$'; then \ | |
| MAJOR=$$(echo "$$LAST" | sed 's/^v//' | cut -d. -f1); \ | |
| MINOR=$$(echo "$$LAST" | sed 's/^v//' | cut -d. -f2); \ | |
| PATCH=$$(echo "$$LAST" | sed 's/^v//' | cut -d. -f3); \ | |
| case "$(PART)" in \ | |
| major) MAJOR=$$((MAJOR + 1)); MINOR=0; PATCH=0 ;; \ | |
| minor) MINOR=$$((MINOR + 1)); PATCH=0 ;; \ | |
| patch) PATCH=$$((PATCH + 1)) ;; \ | |
| *) echo "Error: PART must be patch, minor or major."; exit 1 ;; \ | |
| esac; \ | |
| NEXT="v$$MAJOR.$$MINOR.$$PATCH"; \ | |
| else \ | |
| echo "Error: latest tag '$$LAST' is not in supported format v<major>.<minor>.<patch>."; exit 1; \ | |
| fi; \ |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 161cf42d89
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| git push origin main "$$NEXT"; \ | ||
| echo "Tag $$NEXT pushed to origin." |
There was a problem hiding this comment.
Fail bump target when git push errors
The bump recipe runs all release steps in one .ONESHELL block and ends with echo, so a failed git push (e.g., auth issue, network problem, or non-fast-forward) is masked and make bump still exits successfully. This can leave a local commit/tag that was never published while printing a success message, which is risky for release automation.
Useful? React with 👍 / 👎.
|
All 5 review comments addressed in b7d1ba1:
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b7d1ba1337
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| git add pyproject.toml; \ | ||
| git commit -m "chore: Bump version to $$NEXT."; \ | ||
| git tag -a "$$NEXT" -m "Release $$NEXT"; \ | ||
| git push origin main "$$NEXT"; \ |
There was a problem hiding this comment.
Push branch and tag atomically in bump target
The git push origin main "$$NEXT" call can partially update the remote: if main is accepted but the tag is rejected (for example because the tag already exists remotely or tag creation is restricted), the bump commit is published without its release tag. git push only guarantees all-or-nothing behavior when --atomic is used, so this target can leave the repository in an inconsistent release state even though it reports failure.
Useful? React with 👍 / 👎.
* tooling: Add version bump target to Makefile. * tooling: Configure semantic-release for automated versioning. * tooling: Address PR review comments on bump target.
Summary
feat:→ minor,fix:/perf:/refactor:/tooling:→ patch,BREAKING CHANGE:→ majordocs:/style:/test:/ci:/chore:commits do not trigger a releasemake bumpas manual override with safety checks (main branch + clean tree)New files
.releaserc.json— semantic-release configuration.github/workflows/release.yml— CI workflow triggered on push to mainModified files
Makefile— addbumptarget with warning to prefer semantic-releaseCONTRIBUTING.md— document automated and manual release workflowspackage.json/package-lock.json— add@semantic-release/execdependencyCloses #236