butlerpd / mysandbox

testing sandbox for various github services
GNU Lesser General Public License v2.1
0 stars 0 forks source link

Proposal for a new SasView release process #1

Open butlerpd opened 2 months ago

butlerpd commented 2 months ago

A hierarchical workflow to enable a professional release cycle in an amateur development environment: Proposal for a new SasView release process.

Problem statement

CURRENT: The SasView release cycle is slow, irregular and almost always buggy on release. There have been lots of discussions about "release early release often." While this sounds reasonable in the abstract, it never ends up being practical when the rubber hits the road.

DESIRED: A method that allows for rapid bug fix releases and a regular cadence of feature releases which are relatively robust and bug free that accounts for the way the project is actually resourced rather than how it wishes it were resourced.

CONSTRAINTS: The way the project is resourced is quite lean, opportunistic and, most importantly, very sporadic. This is not likely to change significantly in the foreseeable future.

The number of volunteer developers for SasView remains small with the appropriate expertise often dispersed among several different people, most or all of whom can only work on SasView issues when their regular jobs allow. This can sometimes mean weeks or even a month hiatus of a critical person. This is a very different environment than most open source projects of note (python, numpy, scipy ... even Mantid for that matter) which have a cadre of people committed to the project (or with at least part of their week dedicated to the project). Thus what works best in those environments may not be appropriate in this case.

Analysis

Looking at "best practices" in version control workflows for software projects suggests that a single, continuously releasable main branch, with possibly a very long running parallel "next major release" branch ( e.g. developing version 4 while still releasing new features in 3), provides the minimum wasted overhead effort. As more permanent parallel branches are added (patch branch, feature branch etc.) the more tedious the maintenance of all those branches simultaneously becomes.

The current SasView workflow is essentially the single permanent branch approach but has proven to create very long release cycles with a lack of agility for small bug fixes etc. Moreover, code freezes often stymie the ability of the very few contributors who have time to work on major projects. However, this is not that surprising given that the requirements for this "best practice" approach seem to be:

The SasView project does not meet any of these, nor will it realistically be able to anytime in the foreseeable future. In fact it would be difficult to claim that main is "continuously releasable."

Furthermore, The complexity of the overhead will be high in large projects because commits are coming into the various permanent branches at a steady clip making it hard to keep the up with synching the permanent branches, with the attendant conflict resolutions, which themselves could introduce new bugs. Again, this is not the case with the SasView project where the pace of commits is much slower.

Proposal

Here we propose a different optimization choice by going with a more hierarchical approach that increases the branch maintenance overhead in favor of simplifying the release process by minimizing the interference between changes of different levels of complexity (there is no free lunch). The extra overhead to regularly merge branches back up the hierarchy tree, resolving possible merge conflicts, and the extra maintenance issues, particularly for the refactoring branch should payoff by allowing for rapid bug fix releases and for a simple feature release cycle on a regular schedule without slowing down major refactoring/breaking change efforts.

The model consists of 4 permanent locked branches. We could do it with 3 but conceptually 4 seems cleaner to me:

To avoid confusion in the process, if a "simpler branch" is ready for release at the same time as a higher level branch (more complex) then the simpler branch should be released first. The resulting main should then be merged back into all branches, including the other release branches being worked.

This should allow for the following release cadence almost independently of resources or timing thereof:

---
title: sasview development and release process
---
    %%{init: { 'logLevel': 'debug', 'theme': 'default' , 'themeVariables': {
              'commitLabelFontSize': '30px'
       } } }%%
   gitGraph
   commit id:"start"
   branch Patch order: 1
   branch Features order: 10
   branch Major_version_change order: 20
   checkout Patch
   branch bugfixA order: 2
   commit id:"bugfix 1"
   checkout Features
   branch Feature1 order: 11
   commit id:"New Feature 1"
   checkout Features
   merge Feature1
   checkout Patch
   branch bugfixB order: 3
   checkout bugfixA
   commit id:"bugfix 2"
   checkout Patch
   merge bugfixA
   checkout bugfixB
   commit id:"bugfix 3"
   checkout Patch
   merge bugfixB
   checkout main
   merge Patch id:"release 1.0.1"
   checkout Features
   merge main
   checkout Major_version_change
   merge main
   checkout Features
   branch Feature2 order: 11
   commit id:"New Feature 2"
   checkout Patch
   branch bugfixC order: 2
   commit id:"bugfix 4"
   commit id:"bufgix 5"
   checkout Patch
   merge bugfixC
   checkout Feature2
   commit id:"minor tweak"
   checkout Features
   merge Feature2
   checkout Major_version_change
   branch Breaking1 order:21
   commit id:"Breaking Change 1"
   checkout Major_version_change
   merge Breaking1
   checkout main
   merge Patch id:"release 1.0.2"
   checkout Features
   merge main
   checkout Major_version_change
   merge main
   checkout Features
   branch Feature3 order: 11
   commit id:"New Feature 3"
   checkout Features
   merge Feature3
   branch FeatureRelease1 order: 9
   commit id:"fix bug again"
   commit id:"oopsy"
   commit id:"oops again"
   checkout main
   merge  FeatureRelease1 id:"release 1.1.0"
   checkout Patch
   merge main
   checkout Features
   merge  main
   checkout Major_version_change
   merge main
   checkout Patch
   branch bugfixD order: 2
   commit id:"bugfix 6"
   checkout Patch
   merge bugfixD
   checkout Features
   branch Feature4 order: 11
   commit id:"New Feature 4"
   commit id:"New Feature 5"
   checkout Features
   merge Feature4
   branch FeatureRelease2 order: 9
   commit id:"fix bug"
   checkout bugfixD
   commit id:"bugfix 7"
   checkout Patch
   merge bugfixD
   checkout main
   merge Patch id:"release 1.1.1"
   checkout FeatureRelease2
   merge main
   checkout main
   merge  FeatureRelease2 id:"release 1.2.0"
   checkout Patch
   merge main
   checkout Features
   merge  main
   checkout Major_version_change
   merge main
   branch Refactor1 order: 21
   commit id: "Major refactoring"
   checkout Major_version_change
   merge Refactor1
   branch MajorRelease1 order:19
   commit id:"some changes"
   commit id:"some more fixes"
   checkout main
   merge MajorRelease1 id:"release 2.0.0"
   checkout Patch
   merge main
   checkout Features
   merge main
   checkout Major_version_change
   merge main
   checkout Patch
   branch bugfixE order: 2
   commit id:"bugfix 8"
   checkout Features
   branch Feature5 order: 11
   commit id: "New Feature 6"

NOTE: information on mermaid commands can be found in the mermaid documentation at: https://mermaid.js.org/syntax/gitgraph.html)

krzywon commented 1 month ago

Here is a simplified version of what Paul has with a top-to-bottom view of the history instead of left-to-right view.

---
title: SasView development and release process
---
    %%{init: { 'logLevel': 'debug', 'theme': 'default' , 'themeVariables': {
              'commitLabelFontSize': '30px'
       } } }%%
   gitGraph TB:
   commit id:"start"
   branch Patch
   branch Features
   branch Major_version_change
   checkout Patch
   branch bugfixA
   commit id:"bugfix 1"
   checkout Features
   branch Feature1 order: 11
   commit id:"New Feature 1"
   checkout Features
   merge Feature1
   checkout Patch
   merge bugfixA
   checkout main
   merge Patch id:"release 1.0.1"
   checkout Features
   merge main
   checkout Major_version_change
   merge main
   checkout Major_version_change
   branch Breaking1
   commit id:"Breaking Change 1"
   checkout Major_version_change
   merge Breaking1
   checkout Features
   branch FeatureRelease1
   commit id:"fix bug again"
   commit id:"oopsy"
   commit id:"oops again"
   checkout Features
   merge FeatureRelease1
   checkout main
   merge  Features id:"release 1.1.0"
   checkout Patch
   merge main
   checkout Features
   merge  main
   checkout Major_version_change
   merge main
   checkout Patch
   branch FeatureRelease2
   commit id:"fix bug"
   checkout main
   merge Patch id:"release 1.1.1"
   checkout FeatureRelease2
   merge main
   checkout main
   merge  FeatureRelease2 id:"release 1.2.0"
   checkout Patch
   merge main
   checkout Features
   merge  main
   checkout Major_version_change
   merge main
   branch MajorRelease1
   commit id:"some changes"
   commit id:"some more fixes"
   checkout main
   merge MajorRelease1 id:"release 2.0.0"
krzywon commented 1 month ago

Notes and comments:

wpotrzebowski commented 1 month ago

I think the proposal is good and indeed addresses many issues we've been struggling with. Here are some points

lucas-wilkins commented 1 month ago

I don't see how this solves the main issues.

I can see the advantage of having a stable branch for the purposes of getting people to test while others are developing things. One can just make an alpha release from main every so often for this.

We already dynamically create the major, feature and patch branches, they're just not called that. Pigeonholing work into the semantic versioning system might not really help with anything other than, well, keeping a version number.

The cause of the slow releases is much more about people being overly precious about what goes into an alpha release than anything else. It's self re-enforcing because the longer you take, the more significant the changes are between, and the longer it takes to fix all the bugs/issues. To release more often, all you have to do is release more often.

A completely different strategy that doesn't involve specific branches would be to decide at the end of every biweekly meeting whether or not to make a release from whatever we have merged over the past couple of weeks (default being yes), and decide how we increment the version number. If its a bigish change we release a minor version alpha. If something is found to be terribly wrong during testing, we can always delete the releases that have it.

I would add that githubs automatic issue linking stuff doesn't work with any branch other than main, so we'd have to loose that if we went down the route of multiple locked branches.

rozyczko commented 1 month ago

Having 4 permanent (-ly closed) branches is, I think, an overkill. For small teams, having master <- develop <- feature branch is usually OK. For larger teams, having a dedicated release branch inbetween develop and master is also common. As Lucas say, we could decide every 2-4 weeks on whether the current snapshot of develop is releasable (Any new features? Any important bugs fixed?), then create a release branch in preparation for the (quick) release. This would leave develop open for further contributions.

Having master and pre-release branches "closed" would probably be easier than managing a big tree as @butlerpd is proposing.

I also agree with Lucas, that the main (?) problem with slow releases for SasView is constant release scope creep. It is nice to have just one more thing packed in. We really need to say - this content of develop is what we release and nothing else (barred egregious bugs which crept in).