|
| 1 | +#GitFlow |
| 2 | +GitFlow allows more structured releases, and GitVersion will derive sensible SemVer compatible versions from this structure. |
| 3 | + |
| 4 | +### Assumptions: |
| 5 | + |
| 6 | +* Using [GitFlow branching model](http://nvie.com/git-model/) which always has a master and a develop branch |
| 7 | +* Following [Semantic Versioning](http://semver.org/) |
| 8 | +* Planned releases (bumps in major or minor) are done on release branches prefixed with release-. Eg: release-4.1 (or release-4.1.0) |
| 9 | +* Hotfixes are prefixed with hotfix- Eg. hotfix-4.0.4 |
| 10 | +* The original GitFlow model (http://nvie.com/posts/a-successful-git-branching-model/) specifies branches with a "-" separator while the git flow extensions (https://github.com/nvie/gitflow) default to a "/" separator. Either work with GitVersion. |
| 11 | +* Tags are used on the master branch and reflects the SemVer of each stable release eg 3.3.8 , 4.0.0, etc |
| 12 | +* Tags can also be used to override versions while we transition repositories over to GitVersion |
| 13 | +* Using a build server with multi-branch building enabled eg TeamCity 8 |
| 14 | + |
| 15 | +### How Branches are handled |
| 16 | + |
| 17 | +The descriptions of how commits and branches are versioned can be considered a type of pseudopod. With that in mind there are a few common "variables" that we will refer to: |
| 18 | + |
| 19 | +* `targetBranch` => the branch we are targeting |
| 20 | +* `targetCommit` => the commit we are targeting on `targetbranch` |
| 21 | + |
| 22 | +#### Master branch |
| 23 | + |
| 24 | +Commits on master will always be a merge commit (Either from a `hotfix` or a `release` branch) or a tag. As such we can simply take the commit message or tag message. |
| 25 | + |
| 26 | +If we try to build from a commit that is no merge and no tag then assume `0.1.0` |
| 27 | + |
| 28 | +`mergeVersion` => the SemVer extracted from `targetCommit.Message` |
| 29 | + |
| 30 | +* major: `mergeVersion.Major` |
| 31 | +* minor: `mergeVersion.Minor` |
| 32 | +* patch: `mergeVersion.Patch` |
| 33 | +* pre-release: 0 (perhaps count ahead commits later) |
| 34 | +* stability: final |
| 35 | + |
| 36 | +Optional Tags (only when transitioning existing repository): |
| 37 | +* TagOnHeadCommit.Name={semver} => overrides the version to be {semver} |
| 38 | + |
| 39 | +Long version: |
| 40 | + |
| 41 | + {major}.{minor}.{patch} Sha:'{sha}' |
| 42 | + 1.2.3 Sha:'a682956dccae752aa24597a0f5cd939f93614509' |
| 43 | + |
| 44 | +#### Develop branch |
| 45 | + |
| 46 | +`targetCommitDate` => the date of the `targetCommit` |
| 47 | +`masterVersionCommit` => the first version (merge commit or SemVer tag) on `master` that is older than the `targetCommitDate` |
| 48 | +`masterMergeVersion` => the SemVer extracted from `masterVersionCommit.Message` |
| 49 | + |
| 50 | +* major: `masterMergeVersion.Major` |
| 51 | +* minor: `masterMergeVersion.Minor + 1` (0 if the override above is used) |
| 52 | +* patch: 0 |
| 53 | +* pre-release: `unstable{n}` where n = how many commits `develop` is in front of `masterVersionCommit.Date` ('0' padded to 4 characters) |
| 54 | + |
| 55 | +Long version: |
| 56 | + |
| 57 | + {major}.{minor}.{patch}-{pre-release} Branch:'{branchName}' Sha:'{sha}' |
| 58 | + 1.2.3-unstable645 Branch:'develop' Sha:'a682956dccae752aa24597a0f5cd939f93614509' |
| 59 | + |
| 60 | +#### Hotfix branches |
| 61 | + |
| 62 | +Named: `hotfix-{versionNumber}` eg `hotfix-1.2` |
| 63 | + |
| 64 | +`branchVersion` => the SemVer extracted from `targetBranch.Name` |
| 65 | + |
| 66 | +* major: `mergeVersion.Major` |
| 67 | +* minor: `mergeVersion.Minor` |
| 68 | +* patch: `mergeVersion.Patch` |
| 69 | +* pre-release: `beta{n}` where n = number of commits on branch ('0' padded to 4 characters) |
| 70 | + |
| 71 | +Long version: |
| 72 | + |
| 73 | + {major}.{minor}.{patch}-{pre-release} Branch:'{branchName}' Sha:'{sha}' |
| 74 | + 1.2.3-beta645 Branch:'hotfix-foo' Sha:'a682956dccae752aa24597a0f5cd939f93614509' |
| 75 | + |
| 76 | +#### Release branches |
| 77 | + |
| 78 | + * May branch off from: develop |
| 79 | + * Must merge back into: develop and master |
| 80 | + * Branch naming convention: `release-{n}` eg `release-1.2` |
| 81 | + |
| 82 | +`releaseVersion` => the SemVer extracted from `targetBranch.Name` |
| 83 | +`releaseTag` => the first version tag placed on the branch. Note that at least one version tag is required on the branch. The recommended initial tag is `{releaseVersion}.0-alpha1`. So for a branch named `release-1.2` the recommended tag would be `1.2.0-alpha1` |
| 84 | + |
| 85 | +* major: `mergeVersion.Major` |
| 86 | +* minor: `mergeVersion.Minor` |
| 87 | +* patch: 0 |
| 88 | +* pre-release: `{releaseTag.preRelease}.{n}` where n = 1 + the number of commits since `releaseTag`. |
| 89 | + |
| 90 | +So on a branch named `release-1.2` with a tag `1.2.0-alpha1` and 4 commits after that tag the version would be `1.2.0-alpha1.4` |
| 91 | + |
| 92 | +Long version: |
| 93 | + |
| 94 | + {major}.{minor}.{patch}-{pre-release} Branch:'{branchName}' Sha:'{sha}' |
| 95 | + 1.2.3-alpha2.4 Branch:'release-1.2' Sha:'a682956dccae752aa24597a0f5cd939f93614509' |
| 96 | + 1.2.3-rc2 Branch:'release-1.2' Sha:'a682956dccae752aa24597a0f5cd939f93614509' |
| 97 | + |
| 98 | +#### Feature branches |
| 99 | + |
| 100 | +May branch off from: `develop` |
| 101 | +Must merge back into: `develop` |
| 102 | +Branch naming convention: anything except `master`, `develop`, `release-{n}`, or `hotfix-{n}`. |
| 103 | + |
| 104 | +TODO: feature branches cannot start with a SemVer. to stop people from create branches named like "4.0.3" |
| 105 | + |
| 106 | +* major: `masterMergeVersion.Major` |
| 107 | +* minor: `masterMergeVersion.Minor + 1` (0 if the override above is used) |
| 108 | +* patch: 0 |
| 109 | +* pre-release: `unstable.feature-{n}` where n = First 8 characters of the commit SHA of the first commit |
| 110 | + |
| 111 | + |
| 112 | +Long version: |
| 113 | + |
| 114 | + {major}.{minor}.{patch}-{pre-release} Branch:'{branchName}' Sha:'{sha}' |
| 115 | + 1.2.3-unstable.feature-a682956d Branch:'feature1' Sha:'a682956dccae752aa24597a0f5cd939f93614509' |
| 116 | + |
| 117 | +#### Pull-request branches |
| 118 | + |
| 119 | +May branch off from: `develop` |
| 120 | +Must merge back into: `develop` |
| 121 | +Branch naming convention: anything except `master`, `develop`, `release-{n}`, or `hotfix-{n}`. Canonical branch name contains `/pull/`. |
| 122 | + |
| 123 | +* major: `masterMergeVersion.Major` |
| 124 | +* minor: `masterMergeVersion.Minor + 1` (0 if the override above is used) |
| 125 | +* patch: 0 |
| 126 | +* pre-release: `unstable.pull{n}` where n = the pull request number ('0' padded to 4 characters) |
| 127 | + |
| 128 | +### Nightly Builds |
| 129 | + |
| 130 | +**develop**, **feature** and **pull-request** builds are considered nightly builds and as such are not in strict adherence to SemVer. |
| 131 | + |
| 132 | +## Release Candidates |
| 133 | + |
| 134 | +How do we do release candidates?? Perhaps tag a release branch and then count commits forward from the tag to get RC1, RC2 etc?? |
0 commit comments