Difference between revisions of "Development and Release Process"

From D Wiki
Jump to: navigation, search
(Release Schedule: Follow up from forums)
(Rewrite page. The proposed model is 95% identical, except there is a clear differentiation between regression/bug. This is admittedly more important for dmd than for druntime/phobos. druntime/phobos could get softer rules later.)
Line 1: Line 1:
This page is intended to serve as a working paper to capture the essential aspects of a current discussion on the D forum concerning an improved D development and release process. As such, it should not be taken as official (until approved by Andrei), but it is to serve as a centralized location for the current proposal, so that the details won't be scattered throughout multiple disjoint forum messages and ultimately lost in the mists of time.
+
<!--
 +
Copy/Paste colored markup for branch names:
  
To keep things civil, the convention is that if something on this page doesn't match how you understand it should be, you should start a discussion on the [[Talk:Release Process|talk page]] before making the change.
+
<span style="color:#EEAD0E">feature</span>
 +
<span style="color:#458B00">master</span>
 +
<span style="color:#CD2626">version</span>
 +
<span style="color:#00008B">staging</span>
  
==Goals==
 
  
* To provide D users with a stable version of D that receives only critical bugfixes, that they can build on
+
#FIXME headline numbering?
* To provide a place for adequate testing of new features before they are officially included in D
+
-->
* To allow the D developers to continue to develop the language without being hampered by the fear of breaking large amounts of existing code
 
* To allow a better integration on the DMD frontend (and phobos? druntime?) between the DMD, LDC and GDC developers.
 
  
==Issues==
+
If you're an experienced git user, skip to the summary.
  
Here are some higher-level issues that need to be considered:
+
==Definitions==
* What branches should there be, and how they should be used
+
===Version numbers===
* How long each branch should be maintained, etc.
+
We follow the traditional dmd versioning: ''2.061''. Tags have a ''v'' prepended, so the tag for version ''2.061.1'' is ''v2.061.1''. Versions where the third part is bigger than zero are called ''Minor Releases''. Versions where the third part is equal zero are ''Major Releases''. ''Minor Releases'' will only contain regression fixes, ''Major Releases'' will contain bug fixes and new features.
** How many release branches should be maintained (i.e. receive bugfixes) at one time?
+
 
** How long should a release branch be maintained?
+
The third digit can be omitted for ''Major Releases'': ''2.061'' is the same as ''2.061.0''.
** Should there be overlap between two maintained release branches to allow users to upgrade their codebases?
+
 
** How long should a staging branch take to be deemed sufficiently-stable?
+
Meta: The dmd contributors should choose one style for all offical statements: Tags, packages, Notes on the download page. Either '''always''' write out the ''.0'' part or '''always''' omit it.
* How the chosen branching model satisfies the above mentioned goals.
+
 
 +
===Regression fix vs. Bug fix===
 +
A regression fix for release '''X''' is a fix for a bug which was newly introduced in release '''X'''. We distinguish between regression fixes and bug fixes to avoid introducing more regressions in minor releases. A regression fix especially should not make code invalid which was valid before the regression occurred. As an example: If we have releases 2.061 and 2.061.1 then 2.061.1 should always be "better" than 2.061. It should be tried heavily not to introduce new regressions in minor releases. Code which compiled with 2.061 should still compile in 2.061.1 (there's one rare exception: If a regression allowed code to work in 2.061 which did not work in 2.060 and which is not supposed to work, it can be disabled again in 2.061.1).
 +
 
 +
So a regression fix is a bug fix which should not have side-effects, doesn't introduce new features and fixes a bug which only recently appeared.
 +
 
 +
Long standing bugs are especially not regressions! (Or technically probably a regression in a very old release, but as we support only 1 major release we can treat those like bugs. We only care about new regressions)
 +
 
 +
===Small enhancement vs. Big feature===
 +
We later suggest different workflows for those two enhancements. Those are easily distinguishable: If you implement the feature by yourself and don't need help / someone to participate / extended review and the code changes are ''reasonably'' small, it's a small enhancement. Otherwise it's a big feature.
 +
 
 +
The workflow for big features allows other contributors to participate in that feature, make special test releases for that feature, etc. If you want / need those, use the Big Feature workflow.
 +
 
 +
===Stable===
 +
When is a release stable and therefore ready to be released?
 +
 
 +
The workflow already guarantees that when a release can be made there has been a feature freeze for a long time. So only bug fixes and regression fixes where allowed for some time which should already stabilize the release.  But we should add some more criteria:
 +
 
 +
* All bugs marked as critical in bugzilla have been fixed
 +
** For practical reasons we allow exceptions from this rule for the first releases after this workflow has been established
 +
* There are no newly introduced (known) regressions
 +
** This is a hard rule, there are no exceptions to it. Have a regression? Don't release!
 +
* Later a yet to be determined percentage of non-critical bug will need to be fixed (or new features introduced)
 +
** This is to make sure a new release actually provides something new and prevent us from releasing too often. Currently this is not an issue.
 +
 
 +
Apart from these criteria, the final decision is made by the release manager.
  
 
==Release Schedule==
 
==Release Schedule==
 +
<pre>
 +
<x> = time in weeks
 +
vxxx = Tag for version xxx (Marks the release)
 +
rest = branches
 +
\ = merge (merges from version to staging/master not shown)
 +
------------------------------------------------------------------------------------ master branch. development is never stopped
 +
                            \                  <8>                \
 +
------------------------------------------------------------------------------------ staging branch
 +
            |              |                              |        |
 +
        v2.062.0-b1        |                        2.063.0-b1    |
 +
                            |                                      |
 +
                            |                    <8>                ---------------- 2.063 release branch
 +
                            |                                      |  <2>  |
 +
                            |                                  v2.063.0  v2.063.1
 +
                            |
 +
                            -------------------------------------------------------- 2.062 release branch
 +
                            |  <2>    |    <2>  |
 +
                        v2.062.0 v2.062.1  v2.062.2
 +
</pre>
  
Approximately every month a release is considered from the staging branch. These release include bug fixes and new/deprecated/removed features. Staging is then prepared to receive bug fixes for the next release.
+
A new release is made approximately every 2 months. Releases are stabilized in the <span style="color:#00008B">staging</span> branch and beta releases are tagged as part of <span style="color:#00008B">staging</span>. When a release is ready a new <span style="color:#CD2626">version</span> branch is created from <span style="color:#00008B">staging</span>. The first commit of this <span style="color:#CD2626">version</span> branch is tagged as the release (v2.0xx). Immediately after creating the <span style="color:#CD2626">version</span> branch <span style="color:#458B00">master</span> is merged into <span style="color:#00008B">staging</span>. Note: <span style="color:#458B00">master</span> is only ever merged into <span style="color:#00008B">staging</span> immediately after a major release. Then the <span style="color:#00008B">staging</span> branch is stabilizing again until the next release is made.
 +
 +
Once the initial release of the <span style="color:#CD2626">version</span> branch is done, only regression fixes will be pushed to the <span style="color:#CD2626">version</span> branch, then a regression fix update is published every 2 weeks from that <span style="color:#CD2626">version</span> branch as long as it's supported (see [[#Preparing a new minor release]]).  
  
Feature Previews: New features may need their own beta release before approved for a monthly release. These are unplanned, announce on the NG, and highly volatile.
 
  
''To change history, we would see these releases for things like 64bit support and User Defined Attributes. Their development would not have been merged into master until the major flaws were worked out.''
+
Feature Previews: A <span style="color:#EEAD0E">feature</span> branch may need it's own beta release before being merged into <span style="color:#458B00">master</span>. These are unplanned, announced on the NG, and highly volatile.
 +
 
 +
''As an example we would see these releases for things like 64bit support and User Defined Attributes.''
 +
 
 +
===Support times===
 +
Currently only the most recent major release is supported. (This might change in the future)
 +
 
 +
As an example:
 +
version <span style="color:#CD2626">2.061</span> is released. <span style="color:#CD2626">2.061</span> will get updates until <span style="color:#CD2626">2.062</span> is released. Then <span style="color:#CD2626">2.062</span> will get updates until <span style="color:#CD2626">2.063</span> is released etc.
 +
 
 +
Only supported <span style="color:#CD2626">releases</span> receive minor update releases.
  
 
==Branching model==
 
==Branching model==
  
The following branches are proposed:
+
=== Official branches ===
 +
The following branches will be available on the official (upstream) [https://github.com/D-Programming-Language/dmd dmd], [https://github.com/D-Programming-Language/druntime druntime] and [https://github.com/D-Programming-Language/phobos phobos] repositories:
 +
 
 +
* '''<span style="color:#EEAD0E">feature branches</span>''': New features, in general, are '''not''' developed directly on the <span style="color:#458B00">master</span> branch, but in a dedicated <span style="color:#EEAD0E">feature</span> branch. An example for such a branch would be an ''UDA'' branch for user defined attributes. Contributors can collaborate on the feature by opening pull request targeting that <span style="color:#EEAD0E">feature</span> branch. When the feature's implementation is more-or-less complete, the <span style="color:#EEAD0E">feature</span> branch will be merged into the <span style="color:#458B00">master</span> branch. The <span style="color:#458B00">master</span>  branch is also sporadically merged into the '''<span style="color:#EEAD0E">feature</span>''' branches to get regression fixes, bug fixes and to make sure the '''<span style="color:#EEAD0E">feature</span>''' branch can be merged into <span style="color:#458B00">master</span> later on without problems.
 +
<pre>
 +
 
 +
--------------------------------------------------------\ feature64BitWindows
 +
  /                          /            /            \
 +
  /                          /            /              \
 +
/                          /            /                \
 +
------------------------------------------------------------------------------------ master branch. development is never stopped
 +
                                      /
 +
                                    /
 +
------------------------------------------------------------------------------------ staging branch
 +
                                /
 +
                            fix123
 +
</pre>
  
* '''master''': Development takes place on the master branch. The master branch can add new features and may have breaking changes.
+
* '''<span style="color:#458B00">master</span>''': The <span style="color:#EEAD0E">feature</span> branches are merged into this branch if they are considered complete. So the <span style="color:#458B00">master</span>  branch will contain new features and may have breaking changes. Regression fixes  and bug fixes will be merged from <span style="color:#00008B">staging</span> into <span style="color:#458B00">master</span>.
 +
<pre>
  
* '''feature branches''': New features, in general, are '''not''' developed directly on the master branch, but in a dedicated feature branch. Only when the feature's implementation is more-or-less complete, it will be merged into the master branch.
+
--------------------------------------------------------\ feature64BitWindows
 +
                                                        \
 +
-------------------\  featureUDA                          \
 +
                    \                                      \
 +
------------------------------------------------------------------------------------ master branch. development is never stopped
 +
                            \        /        <8>                \
 +
                              \      /                              \
 +
------------------------------------------------------------------------------------ staging branch
 +
                                /
 +
                            fix123
 +
</pre>
  
* '''staging''': Once development has stabilized enough for a wider audience, it is merged into the staging branch. The staging branch will receive mostly bugfixes. No more new features are allowed. The purpose of the staging branch is to test new features extensively before releasing them. In order to do so, snapshots of the staging branch are released on a regular basis.
+
* '''<span style="color:#00008B">staging</span>''': Bug fixes will be pushed directly into <span style="color:#00008B">staging</span> if they are not regression fixes. To determine where a regression fix should go, see [[#Regression fix]]. <span style="color:#00008B">staging</span> usually only gets bugfix updates, but after every major release, new features are merged from master. Regression fixes will be merged from version branches into <span style="color:#00008B">staging</span>.
 +
<pre>
 +
------------------------------------------------------------------------------------ master branch. development is never stopped
 +
                            \                  <8>                \
 +
------------------------------------------------------------------------------------ staging branch
 +
  /        /                      /    /          /
 +
fix123  fix234                fix987  /        fix999
 +
                                      /
 +
                              ------------------------------------------------------ 2.0.62 version branch
 +
                                /
 +
                            regression1
 +
</pre>
  
* '''version branches''': Once the staging branch is deemed sufficiently-tested, a version is made by branching from the staging branch and tagging. A version branch will not receive any new features, only non-breaking, critical bugfixes. Version branches are used to support the version for an extended period of time.
+
* '''<span style="color:#CD2626">version branches</span>''': Once we determine it's time to do a new release, a <span style="color:#CD2626">version</span>  branch is made by branching from the <span style="color:#00008B">staging</span>  branch. A version branch will not receive any new features, only regression fixes. To determine to which <span style="color:#CD2626">version</span>  branch regression fixes should go, see [[#Regression fix]]. <span style="color:#CD2626">Version</span>  branches are used to support the version for an extended period of time to enable updated minor releases which fix regressions.
 +
 
 +
===Suggested local branches===
 +
How user repositories are managed is up to the end user, but we propose this branches:
 +
* '''<span style="color:#EEAD0E">feature branches</span>''': Tracking upstream <span style="color:#EEAD0E">feature</span> branches. You only need a <span style="color:#EEAD0E">feature</span> branch if you want to work on that feature. To work on a feature, make changes to the <span style="color:#EEAD0E">feature</span> branch, push to your repository and file a pull request on github '''targeting the <span style="color:#EEAD0E">feature</span> branch'''
 +
 
 +
* '''<span style="color:#458B00">master</span>''': Tracking the upstream <span style="color:#458B00">master</span>  branch. New feature branches should be branched from this branch.
 +
 
 +
* '''<span style="color:#CD2626">version branches</span>''': Tracking the upstream <span style="color:#CD2626">version</span>  branches. If you want to push a regression  fix to an older release. (See [[#Regression fix]])
 +
 
 +
* '''bugfix branches''': based on <span style="color:#00008B">staging</span>. Used to develop bugfixes (see [[#Bug fix (not a regression!)|Bug fix]])
  
 
==Git workflow==
 
==Git workflow==
  
=== Release a new version of D ===
+
===Working on code updates===
  
The staging branch in git contains a version in stabilization. This version will be the next release of D. When it is judged stabilized enough to be released, a branch is created for this new release. The name of the branch is D2.N+1, where N is the previous version of D2 .
+
====What type of update?====
 +
To determine to which branch an update should be made, we have to consider the type of the change:
  
<source lang="bash">git checkout staging
+
* It's a new, big feature: This will need to get a <span style="color:#EEAD0E">feature</span> branch. See [[#New feature / Big enhancement]]
git checkout -b 2.N+1</source>
+
* It's a small enhancement: This will go to <span style="color:#458B00">master</span>. See [[#Small enhancement]]
 +
* It's a bug fix: This will go straight to <span style="color:#00008B">staging</span>. See [[#Bug fix (not a regression!) | Bug fix]]
 +
* It's a regression fix: This will need to go to the oldest '''supported''' <span style="color:#CD2626">version</span> branch which is affected by the regression. See [[#Regression fix]]
  
Then, a tag is created.
+
====New feature / Big enhancement====
 +
We need to create a new branch based on <span style="color:#458B00">master</span>. As a normal user you can't create <span style="color:#EEAD0E">feature</span> branches on the official repository though.
  
<source lang="bash">git tag 2.N+1.0</source>
+
Step-By-Step:
 +
The one implementing the feature has to do this:
 +
<source lang="bash">
 +
#We use your own fork repository, not the official one!!!!
 +
git clone git://github.com/yourname/dmd.git
 +
git checkout master #This is the branch we base feature
 +
git branch coolFeature
 +
#Make your changes
 +
git commit -m "Implement cool feature"
 +
#Push to your fork on github
 +
git push origin coolFeature
  
Packaging is done as usual based on the content of the tag.
+
#Now request in the digitalmars.D newsgroup that someone creates a coolFeature feature branch on the official repository.
  
Now that the release is done, we must prepare for the next release ! The current dev version, which is in master branch will be merged into staging to be stabilized.
+
#Now go to github and file a pull request for coolFeature. The pull request must target the new official feature branch (here also called coolFeature)!
 +
</source>
  
<source lang="bash">git checkout staging
+
If someone requests a new <span style="color:#EEAD0E">feature</span> branch the dmd staff has to do this:
git merge master</source>
+
<source lang="bash">
 +
#This time we need access to the official repository. We clone our user fork and add a remote
 +
git clone git://github.com/yourname/dmd.git
 +
git remote add upstream git://github.com/D-Programming-Language/dmd.git
  
At this point, staging receive bug fixes and the cycle start again.
+
git checkout master #This is the branch we base features on
 +
git pull upstream master #Fetch changes from upstream
  
=== Release a revision of a released version of D ===
+
git branch coolFeature #Use a useful name
 +
git push upstream coolFeature
 +
</source>
  
A revision can be published on an already released version of D. Revision include bug fixes, but no new feature. We supposed bug fixes has been included into branch 2.N where N is the released version of D we want to update. M is the last revision number that have been published.
+
====Small enhancement====
 +
We merge directly into <span style="color:#458B00">master</span>.
  
<source lang="bash">git checkout 2.N
+
Step-By-Step:
git tag 2.N.M+1</source>
+
The one implementing the feature has to do this:
 +
<source lang="bash">
 +
#We use your own fork repository, not the official one!!!!
 +
git clone git://github.com/yourname/dmd.git
 +
git checkout master #This is the branch we base feature
 +
git branch coolFeature
 +
#Make your changes
 +
git commit -m "Implement cool feature"
 +
#Push to your fork on github
 +
git push origin coolFeature
  
Packaging is done as usual based on the content of the tag.
+
#Now go to github and file a pull request for coolFeature. The pull request must target the master branch!
 +
</source>
  
=== Working on a Bug fix ===
+
====Bug fix (not a regression!)====
 +
We need to create a local branch based on <span style="color:#00008B">staging</span>. Then file a pull request on github targeting <span style="color:#00008B">staging</span>.
  
Bug fix is based on the lower version where the bug exists. Let's assume that this version is N. The development is done in it's own branch.
+
Step-By-Step:
 +
<source lang="bash">
 +
#We use your own fork repository, not the official one!!!!
 +
git clone git://github.com/yourname/dmd.git
 +
git checkout staging #This is the branch we base bugfix on
 +
git branch bugFixNNN
 +
#Make your changes
 +
git commit -m "Implement bugfix #NNN"
 +
#Push to your fork on github
 +
git push origin bugFixNNN
  
<source lang="bash">git checkout 2.N
+
#Now go to github and file a pull request for bugFixNNN. The pull request must target the staging branch!
git checkout -b bugXXXXXX</source>
+
</source>
  
Now you are ready to work hard to fix that nasty bug. The branch you are based on shouldn't change a lot (it only receive bug fixes), but make sure you keep in sync with the branch :
+
====Regression fix====
 +
The regression fix must be pushed to the oldest, still supported <span style="color:#CD2626">version</span> branch affected by the regression. To determine if a <span style="color:#CD2626">version</span> is still supported, see [[#Support times]].
  
<source lang="bash">git checkout bugXXXXXX
+
As an example (this doesn't match with 1.1 as we need a more complicated setup to describe the concept):
git rebase 2.N</source>
+
<span style="color:#CD2626">2.063</span> is the most recent release and supported.
 +
<span style="color:#CD2626">2.062</span> is the previous release and supported.
 +
<span style="color:#CD2626">2.061</span> is no longer supported.
 +
An regression is found that affects 2.061, 2.062, 2.063, <span style="color:#00008B">staging</span> and <span style="color:#458B00">master</span>.
  
At this point, conflict may happen, this is up to you to solve them. Hopefully, this type of branch is stable and this should not occur often.
+
2.061 is no longer supported, so the oldest supported and affected release is 2.062. Therefore the regression fix has to be made on the <span style="color:#CD2626">2.062</span> release branch.
  
When the fix is ready, push ! Then go on github and propose a pull request.
+
'''Note''': Regression fixes are always based on an <span style="color:#CD2626">version</span> branch, never on <span style="color:#00008B">staging</span> / <span style="color:#458B00">master</span>!
  
=== Merging bug fixes ===
+
Step-By-Step:
 +
The one fixing the regression has to do this:
 +
<source lang="bash">
 +
#We use your own fork repository, not the official one!!!!
 +
git clone git://github.com/yourname/dmd.git
 +
git checkout 2.062 #This is the branch we base our fix on
 +
git branch fixRegressionNNN
 +
#Edit and fix the regression
 +
git commit -m "Fix regression #nnn"
 +
#Push to your fork on github
 +
git push origin fixRegressionNNN
 +
#Now go to github and file a pull request for fixRegressionNNN. The pull request must target our base branch, e.g. 2.062!
 +
</source>
  
Bug fixes are based on the smaller relevant version. The merging process is a little complex, but can be automated. Here is how it is done :
+
The dmd staff now has to merge that pull request. The regression fix will be applied to the <span style="color:#CD2626">2.062</span> branch. The dmd staff now also has to make sure this fix is also applied to all newer release branches (<span style="color:#CD2626">2.063</span> in our example) and to <span style="color:#00008B">staging</span> and <span style="color:#458B00">master</span>.
  
<source lang="bash">git checkout 2.N
+
<source lang="bash">
git merge bugXXXXXX
+
#This time we need access to the official repository. We clone our user fork and add a remote
git checkout 2.N+1 # When N is the the previous stable release
+
git clone git://github.com/yourname/dmd.git
git merge bugXXXXXX # ditto
+
git remote add upstream git://github.com/D-Programming-Language/dmd.git
#...
+
 
 +
git checkout 2.062 #This is the branch the fix was based on
 +
git pull upstream 2.062 #Fetch changes from upstream
 +
 
 +
#Repeat for all newer release branches
 +
git checkout 2.063
 +
git pull upstream 2.063 #Fetch remote changes from upstream first
 +
git merge 2.062 #Now merge 2.062 branch into newer branch
 +
git push upstream 2.063 #Now publish those changes
 +
 
 +
#We have to repeat that for staging
 
git checkout staging
 
git checkout staging
git merge bugXXXXXX
+
git pull upstream staging #Fetch remote changes from upstream first
 +
git merge 2.062 #Now merge 2.062 branch into staging branch
 +
git push upstream staging #Now publish those changes
 +
 
 +
#We have to repeat that for master
 +
git checkout master
 +
git pull upstream master #Fetch remote changes from upstream first
 +
git merge staging #Now merge staging branch into master branch
 +
git push upstream master #Now publish those changes
 +
</source>
 +
 
 +
===Preparing a new major release===
 +
As described in 1 every 2 months a new major <span style="color:#CD2626">release</span> will be made based on <span style="color:#00008B">staging</span>.
 +
 
 +
To start the release process (This is always done after a major release has been made) merge master into <span style="color:#00008B">staging</span>:
 +
<source lang="bash">
 +
#This time we need access to the official repository. We clone our user fork and add a remote
 +
git clone git://github.com/yourname/dmd.git
 +
git remote add upstream git://github.com/D-Programming-Language/dmd.git
 +
 
 
git checkout master
 
git checkout master
git merge bugXXXXXX</source>
+
git pull upstream master
 +
 
 +
git checkout staging
 +
git pull upstream staging
 +
 
 +
git merge master
 +
git push upstream staging
 +
</source>
 +
 
 +
Once a beta release is made, the dmd staff adds a tag on <span style="color:#00008B">staging</span>!
 +
<source lang="bash">
 +
#This time we need access to the official repository. We clone our user fork and add a remote
 +
git clone git://github.com/yourname/dmd.git
 +
git remote add upstream git://github.com/D-Programming-Language/dmd.git
 +
 
 +
git checkout staging
 +
git pull upstream staging
 +
 
 +
git tag v2.063-b1 #b1=>first beta
 +
git push upstream v2.063-b1
 +
</source>
 +
 
 +
For the final release, a new version branch is created:
 +
<source lang="bash">
 +
#This time we need access to the official repository. We clone our user fork and add a remote
 +
git clone git://github.com/yourname/dmd.git
 +
git remote add upstream git://github.com/D-Programming-Language/dmd.git
  
It is up to the bug fixer to solve conflict that may occur in merging up to staging. It is up to the developer that created the conflicting feature to resolve the conflict in staging or master.
+
git checkout staging
 +
git pull upstream staging
  
=== Working on a new feature ===
+
git branch 2.063 #replace 2.063 with the new release number
 +
git push upstream 2.063
  
New feature are based on master. You will do your own branch to develop the feature, and propose it to be merged into master. In order to make the merge easy, it is your responsibility to ensure that your feature is rebased on master and that conflict are solved.
+
#And make a tag
 +
git tag v2.063
 +
git push upstream v2.063
 +
</source>
  
<source lang="bash">git checkout master
+
===Preparing a new minor release===
git checkout -b myfeature</source>
+
As described in 1 every 2 weeks  a new minor release will be prepared for all supported releases.
  
Now you are ready to work on the wonderful feature you have in mind. During your development, you have to keep in sync with master. This is how it is done :
+
To put further regression fixes into this release <span style="color:#CD2626">version</span> follow the descriptions in 3.1.5
  
<source lang="bash">git checkout myfeature
+
Once the release is made, the dmd staff adds a tag!
git rebase master</source>
+
<source lang="bash">
 +
#This time we need access to the official repository. We clone our user fork and add a remote
 +
git clone git://github.com/yourname/dmd.git
 +
git remote add upstream git://github.com/D-Programming-Language/dmd.git
  
At this point, conflict may happen, this is up to you to solve them (Note, we should write something on that).
+
git checkout 2.063 #checkout the base branch where a new release is made
 +
git pull upstream 2.063
  
When the feature is ready, push ! Then go on github and propose a pull request.
+
git tag v2.063.1 #.1=>first minor update
 +
git push upstream v2.063.1
 +
</source>
  
=== How synchronise your local git repo with the upstream DPL repo ===
+
===Merging a feature branch===
 +
If a features implementation is ''sufficiently'' complete and has been tested ''well enough'', the <span style="color:#EEAD0E">feature</span> branch can be merged into <span style="color:#458B00">master</span>.
  
''The following commands all use the '''phobos''' repo. In order to use any of the other repos, simply change "'''phobos'''" to "'''dmd'''" or whichever else.''
+
DMD staff:
 +
<source lang="bash">
 +
#This time we need access to the official repository. We clone our user fork and add a remote
 +
git clone git://github.com/yourname/dmd.git
 +
git remote add upstream git://github.com/D-Programming-Language/dmd.git
 +
 
 +
git checkout featureXXX #checkout the feature branch
 +
git pull upstream featureXXX
 +
 
 +
git checkout master
 +
git pull upstream master
 +
git merge featureXXX #if merge fails, do not fix it yourself. contact the maintainer of the feature branch
 +
git push upstream master
 +
</source>
  
We are also assuming that your local repo was created using the following command or similar.
+
==Short Summary==
 +
===Contributors===
 +
* Regression fixes go into <span style="color:#CD2626">version</span> branches
 +
* Bug fixes go into the <span style="color:#00008B">staging</span> branch
 +
* Big new features are developed in <span style="color:#EEAD0E">feature</span> branches and merged into <span style="color:#458B00">master</span>
 +
* Small enhancements can go directly into <span style="color:#458B00">master</span>
  
<source lang="bash">git clone git@github.com:YourUsername/phobos.git</source>
+
===DMD staff===
 +
* Merge regression fixes into <span style="color:#CD2626">version</span> branch asap.
 +
* Merge regressions fixes from <span style="color:#CD2626">version</span> to other <span style="color:#CD2626">version</span> and to <span style="color:#00008B">staging</span> branch immediately.
 +
* Merge <span style="color:#00008B">staging</span> branch into <span style="color:#458B00">master</span> regularly
 +
* Merge bug fixes into <span style="color:#00008B">staging</span> regularly.
 +
* Merge <span style="color:#EEAD0E">feature</span> branches into <span style="color:#458B00">master</span> on demand.
 +
* Merge <span style="color:#458B00">master</span> into <span style="color:#00008B">staging</span> '''after''' every release
  
In order to keep your local git repo synchronised with the official DPL repo, you first need to add the DPL repo as a remote. To do this, enter this command:
+
==Rationale==
 +
=== <span style="color:#00008B">Staging</span> ===
 +
This setup has the advantage that <span style="color:#00008B">staging</span> stabilizes over a long time. <span style="color:#00008B">staging</span> get's a feature updates only after every major release is made. After that <span style="color:#00008B">staging</span> only recieves bug fixes. It also has the advance that bug fixes also have a clear target branch: With <span style="color:#00008B">staging</span> we can always target <span style="color:#00008B">staging</span>. Without <span style="color:#00008B">staging</span> we'd have to target the version branch of the currently stabilizing <span style="color:#CD2626">version</span> branch. But that branch changes over time, so we'd have to update github pull requests, etc.
  
<source lang="bash">git remote add upstream git://github.com/D-Programming-Language/phobos.git</source>
+
=== Regression vs bug fix===
 +
<blockquote style="background-color: lightgrey; border: solid thin grey;">
 +
we need to differentiate between bug fixes
 +
that do not introduce new bugs vs bug fixes that may introduce
 +
new bugs *or* break existing code for the current release
 +
version. We also *have* to prevent new features and structural
 +
changes (destabilizers) from leaking into a stable release.
 +
</blockquote>
 +
http://forum.dlang.org/post/dticrdtkkqdatdnhtzrc@forum.dlang.org
  
This will add tracking to the official repo for phobos, under the name 'upstream'.
+
*The regression/bug differentiation is therefore a very strict model. It's needed for dmd as every bug fix has a probability of breaking user code and therefore we should keep the changes as few as possible. In dmd we also have the issue that we have long-standing bugs: Bugs that were not introduced, but are differences between dmd and the specification. We don't want to get any of these fixed in minor releases. For druntime and phobos there are few such bugs: Every bug has been introduced in some version. The risk of a bug fix causing regressions also seems to be lower for phobos and druntime, so we could allow bug fixes in release branches for phobos/druntime after the process has been well established.
  
Now, to fetch the latest official commits and changes, it is a simple matter of doing a fetch on that repo.
+
=== Stable ===
 +
* http://forum.dlang.org/post/fbtxyjvpqqrxskptcvgk@forum.dlang.org
 +
* http://forum.dlang.org/post/noycjddhpobnnxkqsytx@forum.dlang.org
  
<source lang="bash">git fetch upstream</source>
+
==Possible optimization==
 +
===Time spans===
 +
* If it turns out that <span style="color:#00008B">staging</span> does not get reasonably stable to create the release immediately from <span style="color:#00008B">staging</span> we could introduce a time span (e.g 3 weeks) between branching the new <span style="color:#CD2626">version</span> branch and releasing the version / setting the tag. In this timespan only regression fixes would be merged into the <span style="color:#CD2626">version</span> branch. After that time span the release will be tagged on the <span style="color:#CD2626">version</span> branch
 +
** additional betas can be released from the version branch during that time span
 +
<pre>
 +
<x> = time in weeks
 +
vxxx = Tag for version xxx (Marks the release)
 +
rest = branches
 +
\ = merge (merges from version to staging/master not shown)
 +
---------------------------------------------------------------------------------------------- master branch. development is never stopped
 +
                            \                  <8>                \
 +
---------------------------------------------------------------------------------------------- staging branch
 +
            |              |                              |        |
 +
      v2.062.0-b1          |                        v2.063.0-b1  |
 +
                            |                                      |    <3>      .
 +
                            |                    <8>                -------------------------- 2.063 release branch
 +
                            |                                          |        |  <2>  |
 +
                            |                                          rc1    v2.063.0  v2.063.1
 +
                            |    <3>      .
 +
                            ------------------------------------------------------------------ 2.062 release branch
 +
                                |        |  <2>    |    <2>  |
 +
                          v2.062.0-rc1 v2.062.0 v2.062.1  v2.062.2
 +
</pre>
  
This will fetch all the commits, branches, and reachable tags. The difficult part is then keeping your branches in sync with the upstream ones.  This can be accomplished using a rebase, solving any conflicts as you go.
+
===Release version numbering===
 +
* When we start shipping shared libraries of druntime and phobos we might have to adjust our versioning scheme as those dictate special rules. (Think of ABI compatibility between minor releases, max 3 numbers for a version, etc)
  
<source lang="bash"># First hop onto your branch
+
===rebasing===
git checkout yourbranch
+
I guess we should have a hard stance on not rebasing any of the official branches. (this especially includes feature branches where this might seem to be useful, but probably is still a bad idea)
# then rebase onto the upstream master
 
git rebase -i upstream/master</source>
 

Revision as of 10:36, 5 January 2013


If you're an experienced git user, skip to the summary.

Definitions

Version numbers

We follow the traditional dmd versioning: 2.061. Tags have a v prepended, so the tag for version 2.061.1 is v2.061.1. Versions where the third part is bigger than zero are called Minor Releases. Versions where the third part is equal zero are Major Releases. Minor Releases will only contain regression fixes, Major Releases will contain bug fixes and new features.

The third digit can be omitted for Major Releases: 2.061 is the same as 2.061.0.

Meta: The dmd contributors should choose one style for all offical statements: Tags, packages, Notes on the download page. Either always write out the .0 part or always omit it.

Regression fix vs. Bug fix

A regression fix for release X is a fix for a bug which was newly introduced in release X. We distinguish between regression fixes and bug fixes to avoid introducing more regressions in minor releases. A regression fix especially should not make code invalid which was valid before the regression occurred. As an example: If we have releases 2.061 and 2.061.1 then 2.061.1 should always be "better" than 2.061. It should be tried heavily not to introduce new regressions in minor releases. Code which compiled with 2.061 should still compile in 2.061.1 (there's one rare exception: If a regression allowed code to work in 2.061 which did not work in 2.060 and which is not supposed to work, it can be disabled again in 2.061.1).

So a regression fix is a bug fix which should not have side-effects, doesn't introduce new features and fixes a bug which only recently appeared.

Long standing bugs are especially not regressions! (Or technically probably a regression in a very old release, but as we support only 1 major release we can treat those like bugs. We only care about new regressions)

Small enhancement vs. Big feature

We later suggest different workflows for those two enhancements. Those are easily distinguishable: If you implement the feature by yourself and don't need help / someone to participate / extended review and the code changes are reasonably small, it's a small enhancement. Otherwise it's a big feature.

The workflow for big features allows other contributors to participate in that feature, make special test releases for that feature, etc. If you want / need those, use the Big Feature workflow.

Stable

When is a release stable and therefore ready to be released?

The workflow already guarantees that when a release can be made there has been a feature freeze for a long time. So only bug fixes and regression fixes where allowed for some time which should already stabilize the release. But we should add some more criteria:

  • All bugs marked as critical in bugzilla have been fixed
    • For practical reasons we allow exceptions from this rule for the first releases after this workflow has been established
  • There are no newly introduced (known) regressions
    • This is a hard rule, there are no exceptions to it. Have a regression? Don't release!
  • Later a yet to be determined percentage of non-critical bug will need to be fixed (or new features introduced)
    • This is to make sure a new release actually provides something new and prevent us from releasing too often. Currently this is not an issue.

Apart from these criteria, the final decision is made by the release manager.

Release Schedule

<x> = time in weeks
vxxx = Tag for version xxx (Marks the release)
rest = branches
\ = merge (merges from version to staging/master not shown)
------------------------------------------------------------------------------------ master branch. development is never stopped
                             \                   <8>                 \
------------------------------------------------------------------------------------ staging branch
            |               |                              |        |
        v2.062.0-b1         |                         2.063.0-b1    |
                            |                                       |
                            |                    <8>                ---------------- 2.063 release branch
                            |                                       |   <2>  |
                            |                                   v2.063.0   v2.063.1
                            |
                            -------------------------------------------------------- 2.062 release branch
                            |  <2>    |    <2>   |
                         v2.062.0 v2.062.1   v2.062.2

A new release is made approximately every 2 months. Releases are stabilized in the staging branch and beta releases are tagged as part of staging. When a release is ready a new version branch is created from staging. The first commit of this version branch is tagged as the release (v2.0xx). Immediately after creating the version branch master is merged into staging. Note: master is only ever merged into staging immediately after a major release. Then the staging branch is stabilizing again until the next release is made.

Once the initial release of the version branch is done, only regression fixes will be pushed to the version branch, then a regression fix update is published every 2 weeks from that version branch as long as it's supported (see #Preparing a new minor release).


Feature Previews: A feature branch may need it's own beta release before being merged into master. These are unplanned, announced on the NG, and highly volatile.

As an example we would see these releases for things like 64bit support and User Defined Attributes.

Support times

Currently only the most recent major release is supported. (This might change in the future)

As an example: version 2.061 is released. 2.061 will get updates until 2.062 is released. Then 2.062 will get updates until 2.063 is released etc.

Only supported releases receive minor update releases.

Branching model

Official branches

The following branches will be available on the official (upstream) dmd, druntime and phobos repositories:

  • feature branches: New features, in general, are not developed directly on the master branch, but in a dedicated feature branch. An example for such a branch would be an UDA branch for user defined attributes. Contributors can collaborate on the feature by opening pull request targeting that feature branch. When the feature's implementation is more-or-less complete, the feature branch will be merged into the master branch. The master branch is also sporadically merged into the feature branches to get regression fixes, bug fixes and to make sure the feature branch can be merged into master later on without problems.

--------------------------------------------------------\ feature64BitWindows
   /                          /            /             \
  /                          /            /               \
 /                          /            /                 \
------------------------------------------------------------------------------------ master branch. development is never stopped
                                      /
                                     /
------------------------------------------------------------------------------------ staging branch
                                /
                             fix123
  • master: The feature branches are merged into this branch if they are considered complete. So the master branch will contain new features and may have breaking changes. Regression fixes and bug fixes will be merged from staging into master.

--------------------------------------------------------\ feature64BitWindows
                                                         \
-------------------\  featureUDA                          \
                    \                                      \
------------------------------------------------------------------------------------ master branch. development is never stopped
                             \         /         <8>                 \
                              \       /                               \
------------------------------------------------------------------------------------ staging branch
                                /
                             fix123
  • staging: Bug fixes will be pushed directly into staging if they are not regression fixes. To determine where a regression fix should go, see #Regression fix. staging usually only gets bugfix updates, but after every major release, new features are merged from master. Regression fixes will be merged from version branches into staging.
------------------------------------------------------------------------------------ master branch. development is never stopped
                             \                   <8>                 \
------------------------------------------------------------------------------------ staging branch
   /        /                      /     /           /
fix123   fix234                fix987   /         fix999
                                       /
                              ------------------------------------------------------ 2.0.62 version branch
                                /
                             regression1
  • version branches: Once we determine it's time to do a new release, a version branch is made by branching from the staging branch. A version branch will not receive any new features, only regression fixes. To determine to which version branch regression fixes should go, see #Regression fix. Version branches are used to support the version for an extended period of time to enable updated minor releases which fix regressions.

Suggested local branches

How user repositories are managed is up to the end user, but we propose this branches:

  • feature branches: Tracking upstream feature branches. You only need a feature branch if you want to work on that feature. To work on a feature, make changes to the feature branch, push to your repository and file a pull request on github targeting the feature branch
  • master: Tracking the upstream master branch. New feature branches should be branched from this branch.
  • version branches: Tracking the upstream version branches. If you want to push a regression fix to an older release. (See #Regression fix)
  • bugfix branches: based on staging. Used to develop bugfixes (see Bug fix)

Git workflow

Working on code updates

What type of update?

To determine to which branch an update should be made, we have to consider the type of the change:

  • It's a new, big feature: This will need to get a feature branch. See #New feature / Big enhancement
  • It's a small enhancement: This will go to master. See #Small enhancement
  • It's a bug fix: This will go straight to staging. See Bug fix
  • It's a regression fix: This will need to go to the oldest supported version branch which is affected by the regression. See #Regression fix

New feature / Big enhancement

We need to create a new branch based on master. As a normal user you can't create feature branches on the official repository though.

Step-By-Step: The one implementing the feature has to do this:

#We use your own fork repository, not the official one!!!!
git clone git://github.com/yourname/dmd.git
git checkout master #This is the branch we base feature
git branch coolFeature
#Make your changes
git commit -m "Implement cool feature"
#Push to your fork on github
git push origin coolFeature

#Now request in the digitalmars.D newsgroup that someone creates a coolFeature feature branch on the official repository.

#Now go to github and file a pull request for coolFeature. The pull request must target the new official feature branch (here also called coolFeature)!

If someone requests a new feature branch the dmd staff has to do this:

#This time we need access to the official repository. We clone our user fork and add a remote
git clone git://github.com/yourname/dmd.git
git remote add upstream git://github.com/D-Programming-Language/dmd.git

git checkout master #This is the branch we base features on
git pull upstream master #Fetch changes from upstream

git branch coolFeature #Use a useful name
git push upstream coolFeature

Small enhancement

We merge directly into master.

Step-By-Step: The one implementing the feature has to do this:

#We use your own fork repository, not the official one!!!!
git clone git://github.com/yourname/dmd.git
git checkout master #This is the branch we base feature
git branch coolFeature
#Make your changes
git commit -m "Implement cool feature"
#Push to your fork on github
git push origin coolFeature

#Now go to github and file a pull request for coolFeature. The pull request must target the master branch!

Bug fix (not a regression!)

We need to create a local branch based on staging. Then file a pull request on github targeting staging.

Step-By-Step:

#We use your own fork repository, not the official one!!!!
git clone git://github.com/yourname/dmd.git
git checkout staging #This is the branch we base bugfix on
git branch bugFixNNN
#Make your changes
git commit -m "Implement bugfix #NNN"
#Push to your fork on github
git push origin bugFixNNN

#Now go to github and file a pull request for bugFixNNN. The pull request must target the staging branch!

Regression fix

The regression fix must be pushed to the oldest, still supported version branch affected by the regression. To determine if a version is still supported, see #Support times.

As an example (this doesn't match with 1.1 as we need a more complicated setup to describe the concept): 2.063 is the most recent release and supported. 2.062 is the previous release and supported. 2.061 is no longer supported. An regression is found that affects 2.061, 2.062, 2.063, staging and master.

2.061 is no longer supported, so the oldest supported and affected release is 2.062. Therefore the regression fix has to be made on the 2.062 release branch.

Note: Regression fixes are always based on an version branch, never on staging / master!

Step-By-Step: The one fixing the regression has to do this:

#We use your own fork repository, not the official one!!!!
git clone git://github.com/yourname/dmd.git
git checkout 2.062 #This is the branch we base our fix on
git branch fixRegressionNNN
#Edit and fix the regression
git commit -m "Fix regression #nnn"
#Push to your fork on github
git push origin fixRegressionNNN
#Now go to github and file a pull request for fixRegressionNNN. The pull request must target our base branch, e.g. 2.062!

The dmd staff now has to merge that pull request. The regression fix will be applied to the 2.062 branch. The dmd staff now also has to make sure this fix is also applied to all newer release branches (2.063 in our example) and to staging and master.

#This time we need access to the official repository. We clone our user fork and add a remote
git clone git://github.com/yourname/dmd.git
git remote add upstream git://github.com/D-Programming-Language/dmd.git

git checkout 2.062 #This is the branch the fix was based on
git pull upstream 2.062 #Fetch changes from upstream

#Repeat for all newer release branches
git checkout 2.063
git pull upstream 2.063 #Fetch remote changes from upstream first
git merge 2.062 #Now merge 2.062 branch into newer branch
git push upstream 2.063 #Now publish those changes

#We have to repeat that for staging
git checkout staging
git pull upstream staging #Fetch remote changes from upstream first
git merge 2.062 #Now merge 2.062 branch into staging branch
git push upstream staging #Now publish those changes

#We have to repeat that for master
git checkout master
git pull upstream master #Fetch remote changes from upstream first
git merge staging #Now merge staging branch into master branch
git push upstream master #Now publish those changes

Preparing a new major release

As described in 1 every 2 months a new major release will be made based on staging.

To start the release process (This is always done after a major release has been made) merge master into staging:

#This time we need access to the official repository. We clone our user fork and add a remote
git clone git://github.com/yourname/dmd.git
git remote add upstream git://github.com/D-Programming-Language/dmd.git

git checkout master
git pull upstream master

git checkout staging
git pull upstream staging

git merge master
git push upstream staging

Once a beta release is made, the dmd staff adds a tag on staging!

#This time we need access to the official repository. We clone our user fork and add a remote
git clone git://github.com/yourname/dmd.git
git remote add upstream git://github.com/D-Programming-Language/dmd.git

git checkout staging
git pull upstream staging

git tag v2.063-b1 #b1=>first beta
git push upstream v2.063-b1

For the final release, a new version branch is created:

#This time we need access to the official repository. We clone our user fork and add a remote
git clone git://github.com/yourname/dmd.git
git remote add upstream git://github.com/D-Programming-Language/dmd.git

git checkout staging
git pull upstream staging

git branch 2.063 #replace 2.063 with the new release number
git push upstream 2.063

#And make a tag
git tag v2.063
git push upstream v2.063

Preparing a new minor release

As described in 1 every 2 weeks a new minor release will be prepared for all supported releases.

To put further regression fixes into this release version follow the descriptions in 3.1.5

Once the release is made, the dmd staff adds a tag!

#This time we need access to the official repository. We clone our user fork and add a remote
git clone git://github.com/yourname/dmd.git
git remote add upstream git://github.com/D-Programming-Language/dmd.git

git checkout 2.063 #checkout the base branch where a new release is made
git pull upstream 2.063

git tag v2.063.1 #.1=>first minor update
git push upstream v2.063.1

Merging a feature branch

If a features implementation is sufficiently complete and has been tested well enough, the feature branch can be merged into master.

DMD staff:

#This time we need access to the official repository. We clone our user fork and add a remote
git clone git://github.com/yourname/dmd.git
git remote add upstream git://github.com/D-Programming-Language/dmd.git

git checkout featureXXX #checkout the feature branch
git pull upstream featureXXX

git checkout master
git pull upstream master
git merge featureXXX #if merge fails, do not fix it yourself. contact the maintainer of the feature branch 
git push upstream master

Short Summary

Contributors

  • Regression fixes go into version branches
  • Bug fixes go into the staging branch
  • Big new features are developed in feature branches and merged into master
  • Small enhancements can go directly into master

DMD staff

  • Merge regression fixes into version branch asap.
  • Merge regressions fixes from version to other version and to staging branch immediately.
  • Merge staging branch into master regularly
  • Merge bug fixes into staging regularly.
  • Merge feature branches into master on demand.
  • Merge master into staging after every release

Rationale

Staging

This setup has the advantage that staging stabilizes over a long time. staging get's a feature updates only after every major release is made. After that staging only recieves bug fixes. It also has the advance that bug fixes also have a clear target branch: With staging we can always target staging. Without staging we'd have to target the version branch of the currently stabilizing version branch. But that branch changes over time, so we'd have to update github pull requests, etc.

Regression vs bug fix

we need to differentiate between bug fixes that do not introduce new bugs vs bug fixes that may introduce new bugs *or* break existing code for the current release version. We also *have* to prevent new features and structural changes (destabilizers) from leaking into a stable release.

http://forum.dlang.org/post/dticrdtkkqdatdnhtzrc@forum.dlang.org

  • The regression/bug differentiation is therefore a very strict model. It's needed for dmd as every bug fix has a probability of breaking user code and therefore we should keep the changes as few as possible. In dmd we also have the issue that we have long-standing bugs: Bugs that were not introduced, but are differences between dmd and the specification. We don't want to get any of these fixed in minor releases. For druntime and phobos there are few such bugs: Every bug has been introduced in some version. The risk of a bug fix causing regressions also seems to be lower for phobos and druntime, so we could allow bug fixes in release branches for phobos/druntime after the process has been well established.

Stable

Possible optimization

Time spans

  • If it turns out that staging does not get reasonably stable to create the release immediately from staging we could introduce a time span (e.g 3 weeks) between branching the new version branch and releasing the version / setting the tag. In this timespan only regression fixes would be merged into the version branch. After that time span the release will be tagged on the version branch
    • additional betas can be released from the version branch during that time span
<x> = time in weeks
vxxx = Tag for version xxx (Marks the release)
rest = branches
\ = merge (merges from version to staging/master not shown)
---------------------------------------------------------------------------------------------- master branch. development is never stopped
                             \                   <8>                 \
---------------------------------------------------------------------------------------------- staging branch
            |               |                              |        |
       v2.062.0-b1          |                         v2.063.0-b1   |
                            |                                       |    <3>      .
                            |                    <8>                -------------------------- 2.063 release branch
                            |                                           |         |   <2>  |
                            |                                          rc1    v2.063.0   v2.063.1
                            |     <3>      .
                            ------------------------------------------------------------------ 2.062 release branch
                                 |         |  <2>    |    <2>   |
                           v2.062.0-rc1 v2.062.0 v2.062.1   v2.062.2

Release version numbering

  • When we start shipping shared libraries of druntime and phobos we might have to adjust our versioning scheme as those dictate special rules. (Think of ABI compatibility between minor releases, max 3 numbers for a version, etc)

rebasing

I guess we should have a hard stance on not rebasing any of the official branches. (this especially includes feature branches where this might seem to be useful, but probably is still a bad idea)