This guide outlines the complete release process for the repos project, from
development and pull requests to creating a new versioned release. Our strategy
is built on semantic versioning, conventional commits, and a release branch
workflow to ensure releases are intentional and well-documented.
- Main Branch (
main): Themainbranch is the primary development branch. All new features and fixes are merged here. No releases are created directly frommain. - Release Branches (
release/**): Releases are created by pushing a branch with therelease/prefix (e.g.,release/2025.09). This triggers the release workflow. - Semantic Versioning: The release workflow automatically determines the new version number based on the commit messages since the last release.
- Squash Merges: We use squash merges for pull requests to maintain a clean,
meaningful commit history on the
mainbranch, which is essential for accurate semantic versioning.
The process is designed to be simple and automated, with clear quality gates.
All development happens on feature branches. When a feature or fix is ready,
open a Pull Request (PR) against the main branch.
When merging a PR, always use the "Squash and merge" option.
Why?
Squash merging combines all of a PR's commits into a single commit on the main
branch. This is critical for our release process because:
- Clean History: It keeps the
mainbranch history clean and readable. - Accurate Versioning: It allows us to craft a single, precise conventional
commit message that the semantic versioning tool can parse to determine the
correct version bump. Merge commits often hide the original
feat:orfix:prefixes.
How to Squash Merge:
-
From the GitHub UI:
- In the PR, select "Squash and merge" from the merge dropdown.
- Crucially, edit the commit title to follow the
Conventional Commits format (e.g.,
feat: add new command). - Confirm the merge.
-
From the GitHub CLI:
# Example for PR #42 gh pr merge 42 \ --squash \ --subject "feat: add a new feature" \ --body "Detailed description of the feature."
When you are ready to release the features and fixes that have been merged into
main, you create a release branch.
-
Ensure your
mainbranch is up-to-date:git checkout main git pull origin main
-
Create and push a release branch: The branch name can be anything, but it must start with
release/. A good practice is to name it after the expected version or date.# Create a release branch (e.g., release/2025.10) git checkout -b release/prepare-release # Push the branch to GitHub git push -u origin release/prepare-release
Pushing the release/ branch automatically triggers the release.yml GitHub
Actions workflow, which performs the following steps:
- Compute Version: Analyzes commit messages on
mainsince the last tag and determines the new semantic version (e.g.,v1.3.0). - Run Quality Gates: Runs the full test suite, linter (
clippy), and format checks. The release fails if any of these checks do not pass. - Update
Cargo.toml: Bumps theversioninCargo.tomland pushes the change to the release branch. - Create GitHub Release:
- Creates a new Git tag (e.g.,
v1.3.0). - Generates a new GitHub Release with a "What's Changed" section populated from the conventional commit messages.
- Creates a new Git tag (e.g.,
- Build Release Assets: Compiles the application and creates binaries for Linux and macOS (x86_64, aarch64, and universal). These are attached to the GitHub Release.
- Sync
mainBranch: After the release is successfully created, the version bump inCargo.tomlis automatically merged back into themainbranch to keep it in sync.
To ensure the automation works correctly, all commits merged into main must
follow the Conventional Commits specification.
<type>[optional scope]: <description>
<type>: Must be one of the following.<description>: A short, imperative-tense description of the change.
-
feat: A new feature. Triggers a minor version bump (e.g.,1.2.3→1.3.0).feat: add a new 'run' command
-
fix: A bug fix. Triggers a patch version bump (e.g.,1.2.3→1.2.4).fix: correct an issue with path resolution
-
BREAKING CHANGE: A commit that introduces a breaking API change. This can be added to the footer of any commit type and triggers a major version bump (e.g.,1.2.3→2.0.0).feat: change CLI argument structure BREAKING CHANGE: The '--repo' argument has been renamed to '--repository'. -
Other Types: These trigger a patch version bump and are great for organizing your work.
docs:: Documentation changes.style:: Code style changes (formatting, etc.).refactor:: Code changes that neither fix a bug nor add a feature.perf:: A code change that improves performance.test:: Adding or correcting tests.ci:: Changes to CI configuration files and scripts.chore:: Other changes that don't modifysrcortestfiles.
This strategy allows for creating a release that includes only specific,
hand-picked features or fixes. It is the recommended approach for creating patch
releases or when you need to control the exact contents of a new version, rather
than releasing everything that has been merged to main.
Instead of creating a release branch from main, you will create it from the
most recent release tag. This gives you a clean starting point. You then
cherry-pick the specific commits you want to include in the release onto this
new branch.
The automated release workflow will then calculate the new version and changelog based only on the commits you cherry-picked.
First, ensure your local repository is up-to-date and find the latest release tag.
# Fetch all the latest tags and branches from the remote
git fetch --all --tags
# Find the latest tag (e.g., v0.0.8)
LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`)
echo "Latest tag is: $LATEST_TAG"
# Create a new release branch from that tag.
# Name it something descriptive, like 'release/v0.0.9' or 'release/patch-for-x'
git checkout -b release/v0.0.9 $LATEST_TAGYou are now on a new branch that is an exact copy of your last release.
Identify the commits you want to include in the release. You can find the commit
SHAs from the main branch's log or from a pull request.
# Example: Cherry-pick two specific commits
git cherry-pick <commit-sha-for-feature-A>
git cherry-pick <commit-sha-for-fix-B>Tip for pull requests: If a PR was squash-merged, it will be a single commit
*on main. You can simply cherry-pick that one merge commit.
If you encounter any merge conflicts during cherry-picking, resolve them, and then continue:
# After resolving conflicts...
git add .
git cherry-pick --continueOnce you have cherry-picked all the desired commits, push the release branch to GitHub. This will trigger the automated release workflow.
git push -u origin release/v0.0.9The workflow will now:
- Analyze only the cherry-picked commits.
- Calculate the correct semantic version (e.g.,
v0.0.9if you picked afix, orv0.1.0if you picked afeat). - Run tests, build the binaries, and publish the new GitHub Release with a changelog containing only the changes you selected.