Currently Available: Need a skilled Software Developer for your next project?
Categories
Laravel

Managing Multiple Package Versions in One Repository

Package maintainers who support older releases need to provide fixes without stopping development of the next release. A package version identifies a published package, such as 2.4.1. A branch is a line of repository development that can keep changing, while a tag marks one specific point in that history. Together, a forward-development branch and a small number of maintained release branches let one repository serve several versions.

Decide which release lines the project will maintain. Create a branch only if you plan to test and release fixes for that line. Tag the source commit for each published release, and document when support ends. That policy gives maintainers a clear path for fixes and gives users a clear account of which versions still receive updates.

Choose support lines before creating branches

Decide which versions you will support, for how long, and what kinds of fixes each version receives before adding long-lived branches. A release line is a series of related releases, such as 2.4.1 and 2.4.2, that share a branch and receive maintenance updates. Every additional line requires maintainers to review changes and run its tests. They also have to prepare releases.

A common layout uses main for new development and adds a stable branch for each older release line that still receives fixes:

main                  → next feature release
stable/2.4.x          → maintenance releases such as 2.4.1 and 2.4.2
stable/2.3.x          → maintained only while the project commits to supporting it
v2.4.0, v2.4.1, ...  → tags for individual release commits

These names are conventions, not requirements. The useful rule is to keep only the branches that match a published support commitment. Git’s project-maintenance examples include both maintenance branches for backported patches and longer-running branches for different stability levels; neither layout is required for every project. The Python Developer Guide also illustrates that projects set their own limits on active maintenance branches.

If the project follows Semantic Versioning, state what its public API includes and what its version numbers promise. Under SemVer, a patch release contains backward-compatible bug fixes, a minor release adds backward-compatible functionality, and a major release signals backward-incompatible changes. SemVer describes compatibility between releases; it does not specify how long a release line receives fixes. Publish a separate support policy for that.

Tag each release without moving its history

A release tag should point to the exact repository commit used to produce that release. A branch can move forward as maintainers add commits; a tag records a particular release point. For example, stable/2.4.x can advance through several maintenance releases, while v2.4.1 remains associated with the commit for version 2.4.1.

For release tags, Git supports annotated tags, which include information such as the tagger and a message. Maintainers can also sign tags to support verification. The Git tagging documentation describes these options.

After publishing a tag, do not move it or reuse its name for different contents. Git warns that users who fetched the original tag can associate its name with one commit, while users who fetch it later associate the same name with a different commit. If a published release needs correction, issue a new package version and tag. Record the version and source commit in the release notes or another user-facing record, along with the release date and support status.

Backport fixes selectively

A backport applies a fix from newer development to an older supported release line. Maintainers commonly use Git’s cherry-pick operation to apply a specific commit to another branch. The older branch may need changes to account for code that has since evolved, so the backport needs its own review and tests.

Apply the fix to the branch used for forward development, then decide which supported branches should also receive it. Base the backport decision on the fix’s impact and risk. A security issue or regression in a supported release may warrant a backport; a new feature or behavior change may not. A project should specify which fix types qualify and who approves exceptions. The Django contribution policy describes branch-specific backport practices, while Python’s development-cycle guidance distinguishes lower-risk maintenance changes from changes that are not backported as a matter of course.

For each backport, identify the original change and target branch in the review record or commit message. Resolve any conflicts deliberately, then run the target branch’s tests. Once the fix passes, release a new patch version on that line. Do not replace the old package artifact or reuse its tag.

Make support boundaries clear to users

Publish a support table or policy page that names each maintained release line, its latest release, the kinds of fixes it receives, and when support ends. If the project uses a date or a rule that moves forward over time to determine when support ends, state it explicitly. Tell users what end of life means: Node.js, for example, states that an end-of-life release receives no further updates, including security patches, in its end-of-life policy.

Status What users should expect
Active maintenance Bug fixes and security fixes, as defined by the project
Security-only Security fixes; other bug fixes are outside the stated commitment
End of life No further fixes or security updates

Keep support status separate from compatibility claims. A package line can remain supported while the project tests it only with specified runtimes or related components. State those tested combinations separately so users do not mistake “supported” for “compatible with every environment.” The Kubernetes version-skew policy illustrates how a project can document compatibility limits between component versions.

Update the support page when a release line changes status, and link to it from release notes and package documentation. Users can then check whether a version still receives fixes and which upgrade path the project recommends.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

Your email address will not be published. Required fields are marked *