SoloDB Documentation Help

Git release workflow

SoloDB uses curated release branches. The develop branch is the shared integration branch, but it is not the source from which a release is cut. A release/<major>.<minor> branch contains only the features selected for that release. This allows completed work to be tested on develop without committing it to the next production release.

Download Cheat sheet (PDF).

Branch model

Branch

Purpose

Created from

Merged into

main

The exact production history. Every production release is tagged here.

Not applicable

develop and every active release branch, to forward-sync production changes

develop

Broad integration and development-environment testing. It can contain features for different or unassigned releases.

Long-lived

Nowhere as a whole; never merge develop into main or a release branch

release/<major>.<minor>

The curated, deployable candidate for one release train, for example release/5.15.

main

main after acceptance

feature/<ticket>-<description>

One independently selectable feature, for example feature/83972-link-storage-equipment.

Normally main

develop for integration and one selected release branch for delivery

bugfix/<ticket>-<description>

A fix found while stabilising a release.

The affected release branch

The affected release branch; also apply it to develop when relevant

hotfix/<version>-<description>

An urgent fix for the production version.

main

main, followed by a forward-sync to develop and active release branches

The key rule is that develop answers “does this work with other ongoing development?”, while a release branch answers “will this ship in this version?”. A merge into develop is not a promise to release the feature.

Merge policy

  • Protect main, develop, and release/**; do not push or force-push to them directly.

  • Require a pull request, review, and successful automated checks for every merge.

  • Use merge commits for feature and release pull requests. Do not independently squash the same feature into develop and a release branch: preserving the feature commits lets Git recognise the work when histories meet again.

  • Do not rebase a branch after it has been shared or merged anywhere.

  • Never merge develop wholesale into a release branch or main.

  • Prefer forward merges from main over cherry-picks. Cherry-picks are a recovery tool, not the normal promotion mechanism.

  • Keep a feature branch available until it has either reached its assigned release or been formally cancelled.

Feature branches should stay independent. If feature B depends on feature A, record that dependency in both pull requests. A dependent feature cannot be scheduled earlier than its prerequisite. Prefer feature flags when incomplete work must coexist with released code.

Release lifecycle

1. Create and scope the release

The release manager creates the branch from the latest production main, never from develop:

git switch main git pull --ff-only origin main git switch -c release/5.15 git push -u origin release/5.15

Create a milestone or release ticket with:

  • the target version and expected date;

  • the feature pull requests selected for the release;

  • known dependencies, database changes, and rollout work;

  • the person responsible for the release decision.

Multiple release branches may be open at the same time. Each starts from main and contains only its own selected features. Release trains reach main in version order. When an earlier release reaches main, merge main forward into every later release branch before that later release is accepted.

2. Develop an independently selectable feature

Start the feature from current main so that it does not inherit unrelated work from develop:

git switch main git pull --ff-only origin main git switch -c feature/83972-link-storage-equipment git push -u origin feature/83972-link-storage-equipment

Keep the feature current by merging main into it when necessary. Open a pull request from the feature branch to develop when the feature is ready for integration testing. Leave the feature branch available after that merge.

3. Assign the feature to a release

When the feature is scheduled, open a second pull request from the same feature branch to the chosen release branch. For example:

feature/83972-link-storage-equipment -> release/5.15

The pull request must identify the target version, dependencies, release notes, tests, and any deployment or schema steps. Merge it only after the release manager confirms the scope. A feature does not have to be merged into develop before it can enter a release, although integration testing there is normally useful.

This produces release selection such as:

Feature

develop

release/5.15

release/5.16

Equipment-linking feature

Yes

Yes

Inherited through main after 5.15 is released

New recipe workflow

Yes

No

Yes

Experimental dashboard

Yes

No

No, still unassigned

To reschedule a feature whose release pull request is still open, close that pull request and open one against the new release branch. If it has already been merged, revert its merge on the original release branch through a reviewed pull request. After the original release reaches main, forward-sync main into the later release and restore the feature there with a reviewed revert-of-revert or corrective pull request. Merging the original feature branch again is not enough because its commits are already in the shared history. Do not rewrite either release branch.

4. Stabilise the release candidate

At feature freeze, accept only fixes, documentation, release notes, and required deployment changes on the release branch. Create a bugfix/... branch from that release branch for every correction and merge it back through a pull request. Apply the same correction to develop when the affected code is present there.

Deploy and test the release branch as a complete candidate. Acceptance should include, as applicable:

  • PHP linting, static analysis, and PHPUnit tests;

  • the TypeScript build and relevant user-flow tests;

  • Doctrine schema validation and review of database changes;

  • host-specific checks for the intended SOLODB_HOST profiles;

  • generated template maps, release notes, and rollback instructions.

Do not validate a release from develop: it may contain features that are outside the release scope.

5. Publish the release

  1. Open a pull request from release/5.15 to main and perform the final review.

  2. Merge with a merge commit after all required checks and acceptance steps pass.

  3. Create an annotated semantic-version tag on the resulting main commit and push it:

    git switch main git pull --ff-only origin main git tag -a v5.15.0 -m "SoloDB 5.15.0" git push origin v5.15.0
  4. Deploy the tag, publish the release notes, and verify the production deployment.

  5. Open forward-sync pull requests from main to develop and to every later active release branch.

  6. Delete release/5.15 after the deployment is verified and no release-specific follow-up remains.

  7. Delete feature branches after their release has shipped and all target pull requests are closed.

Tags are immutable. If production needs another change, publish a new patch version rather than moving an existing tag.

Production hotfixes and patch releases

Create an urgent production fix from main:

git switch main git pull --ff-only origin main git switch -c hotfix/5.15.1-login-timeout git push -u origin hotfix/5.15.1-login-timeout

Open a pull request to main, run the normal checks and focused regression tests, and tag the merge commit as the next patch version, for example v5.15.1. Then merge main forward into develop and all active release branches. Never repair production by committing only to develop or by moving the previous tag.

Pull request responsibilities

Pull request

Required decision

feature/* to develop

Is the feature complete enough for shared integration testing?

feature/* to release/*

Is the feature explicitly in this release's scope and independently deployable?

bugfix/* to release/*

Does this fix the candidate without expanding its scope?

release/* to main

Is the complete candidate accepted for production?

hotfix/* to main

Is the production risk urgent, understood, tested, and reversible?

main to develop or release/*

Are all production changes represented in future work?

The author owns implementation and test evidence. The reviewer owns code quality and risk review. The release manager owns release scope, acceptance, versioning, and the final merge to main.

Repository configuration required

For this process to be enforceable rather than conventional only:

  • configure branch rules for main, develop, and release/** with required reviews and status checks;

  • run the PHP and documentation checks for pull requests targeting all three branch classes, not only develop;

  • make release branches deployable to a release-candidate or staging environment;

  • reserve production deployments for version tags or accepted merges to main;

  • allow merge commits for promotion pull requests and disable automatic deletion of unshipped feature branches;

  • add “target release”, “dependencies”, “release notes”, and “rollout/rollback” fields to the pull request template.

Until CI and deployment triggers cover release/**, a release branch must not be treated as production-ready.

03 October 2026