To expand on what I said in a previous message, I suggest the following structure for the superproject: - branch "latest": automatically tracks "develop" of submodules (scripted). - branch "develop": automatically tracks "master" of submodules (scripted). - branch "master": contains either the last release or the current release candidate. (This naming reflects a gitflow model. An alternative would be to use the more traditional unstable/stable for latest/develop.) Test runners test all three, in sequence. Release preparation starts with a gitflow release branch from boostorg:develop. The release manager then runs local tests and, if necessary, applies fixes on the branch by downgrading submodules to an earlier version or asking the submodule maintainer to resolve a problem and then upgrading the submodule to the later version. Ideally, this release branch should be tested non-locally. However, in the past switching branches for testing has proved a problem. Therefore, the procedure continues instead with: When the release manager is satisfied with the local test results for the release branch, he merges it to master. This becomes a release candidate. If tests prove satisfactory, the release candidate is tagged as an official release and the release branch is deleted. If not, work continues on the release branch.