5.3 KiB
Versioning in status-go
status-go follows a modified versioning strategy, influenced by the needs of both our project and the Go ecosystem.
Why This Approach?
status-go serves a very specific purpose as a core library for Status apps (desktop and mobile), not as a general-purpose Go module. This influences our versioning decisions in several ways:
-
Clarity over Convention: While we respect semantic versioning principles, we've adapted them to better communicate what matters most to our apps - distinguishing between main releases and hotfixes.
-
Go Module Compatibility Challenges: Go's module system requires path changes for major version increments (v2+), which adds unnecessary complexity for our use case since we're primarily building a library for our own applications.
-
Release Coordination: Our versioning system is designed to facilitate coordination between status-go and the apps that depend on it, prioritizing clear communication about changes over strict semantic versioning rules.
-
Simplicity: By keeping the MAJOR version fixed and focusing on MINOR for main releases and PATCH for hotfixes, we maintain a simpler, more predictable versioning system for our teams.
Current Versioning Approach
We use a simplified versioning approach based on Semantic Versioning:
- We keep the MAJOR version fixed (we no longer bump it for breaking changes)
- We bump MINOR version for releases from the main branch
- We bump PATCH version for hotfixes on release branches
Version numbers are formatted as vX.Y.Z (e.g., v10.26.0).
💡 Yes, we may end up with versions like
v10.250.0eventually. This is by design and works well for our use case.
Tagging Versions
- We use
gittags to track the version of the library - Run
./scripts/version.shto get the current version - To create a new version tag:
- Run
make tag-versionto create a tag forHEAD, or - Run
make tag-version TARGET_COMMIT={hash}to create a tag for a specific hash
- Run
- Don't forget to
git push origin {tag_created}to publish the tag - The created tag can be used to link mobile client to the new version
Release Branches
- Release branches follow the format
release/vX.Y.x(e.g.,release/v10.26.x) - We create these branches as needed for desktop/mobile releases
- Tags on
developbranch (with PATCH=0) are made as needed - this is used by mobile team who reference status-go by version tag - Tags on
release/*branches (with PATCH>0) are created manually when a patch release is needed for desktop/mobile
Context & History
Originally, we used semantic versioning with MAJOR version 1, incrementing the MAJOR version for every breaking change (PR #5829). However, Go modules require that packages with a MAJOR version greater than 1 include a /v{MAJOR} suffix in their import paths. We decided against this approach because status-go is not intended to be used as an importable Go package, but rather as a shared library for status-desktop and status-mobile. (Issue #6049)
Though we considered updating import paths (PR #6557), we ultimately chose not to, since this would add unnecessary complexity with few benefits.
Additionally, we have removed generated files from the main repository (PR #5878), making the default branch not directly go-gettable. This is acceptable for our workflow, as status-go is not designed for direct third-party go get usage.
Final Decisions
- No
/v{MAJOR}Suffix: We do not add the/v{MAJOR}module path suffix, even for versions > 1. - Fixed MAJOR Version: We no longer bump the MAJOR version for breaking changes.
- Generated Files Not Committed: The main branches do not include generated files.
- Intended Usage: status-go is to be used as a shared library of Status apps, not as a general Go module.
Using status-go as a Go Dependency (Workaround)
For rare cases where status-go needs to be used as an importable Go module (e.g., by projects such as matterbridge), we provide a workaround:
-
Create a
generated/{version}branch:- Use the script
scripts/branch_version_generated.shto automate the process of creating a branch with generated files - This script:
- Checks out a branch named
generated/{version}based on the latest tag - Un-gitignores generated files
- Runs code generation
- Fixes up the version file
- Commits and pushes the result
- Checks out a branch named
- Use the script
-
Go Get from Commit Hash:
- To import status-go, use:
go get github.com/status-im/status-go@<commit-sha> - Use the commit hash from the generated branch, not the semantic release tag (e.g., not
v10.26.0). This avoids Go's requirement for the/v{MAJOR}import path suffix.
- To import status-go, use:
Future Changes
This solution is intended as the simplest for now. In the future, we may:
- Add
/v{MAJOR}suffix support - Commit generated files to the primary branches
But for the moment, given our goals and usage patterns, we see no compelling reason to pursue this.