From a29e685441162ba55a60adb3d3de9063c56effaa Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Wed, 15 Jul 2015 13:34:42 +0800 Subject: [PATCH 1/6] Bunch of updates to the docs --- BREAKING CHANGES.md | 3 +- CONTRIBUTING.md | 19 +- Docs/buildServerSetup/appVeyor.md | 7 + Docs/buildServers.md | 30 +++ Docs/configuration.md | 52 +++++ Docs/configurationOptions.md | 1 - Docs/examples.md | 42 ++++ Docs/faq.md | 13 ++ Docs/howItWorks.md | 1 + {Icons => Docs/images}/CommitGraph.png | Bin Docs/incrementingPerCommit.md | 18 ++ Docs/readme.md | 4 +- Docs/usage.md | 10 +- Docs/usage/commandLine.md | 6 + Docs/usage/msbuildTask.md | 0 Docs/variables.md | 26 +++ Docs/whoIsUsingGitVersion.md | 1 + .../OutputVariables/VariableProvider.cs | 2 +- README.md | 209 +----------------- 19 files changed, 227 insertions(+), 217 deletions(-) create mode 100644 Docs/buildServerSetup/appVeyor.md create mode 100644 Docs/buildServers.md create mode 100644 Docs/configuration.md delete mode 100644 Docs/configurationOptions.md create mode 100644 Docs/examples.md create mode 100644 Docs/faq.md create mode 100644 Docs/howItWorks.md rename {Icons => Docs/images}/CommitGraph.png (100%) create mode 100644 Docs/incrementingPerCommit.md create mode 100644 Docs/usage/commandLine.md create mode 100644 Docs/usage/msbuildTask.md create mode 100644 Docs/variables.md create mode 100644 Docs/whoIsUsingGitVersion.md diff --git a/BREAKING CHANGES.md b/BREAKING CHANGES.md index e3710db790..c7fdefe8e2 100644 --- a/BREAKING CHANGES.md +++ b/BREAKING CHANGES.md @@ -1,6 +1,5 @@ v3.0.0 - - Develop no longer tracks master - - NextVersion.txt has been deprecated, only GitVersion.yaml is supported + - NextVersion.txt has been deprecated, only GitVersionConfig.yaml is supported - `AssemblyFileSemVer` variable removed, AssemblyVersioningScheme configuration value makes this variable obsolete - Variables `ClassicVersion` and `ClassicVersionWithTag` removed - MSBuild task arguments (AssemblyVersioningScheme, DevelopBranchTag, ReleaseBranchTag, TagPrefix, NextVersion) have been removed, use GitVersionConfig.yaml instead diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7667e065d1..6c974fd795 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,18 +6,23 @@ We love contributions to get started contributing you might need: - [An issue to work on](https://github.com/ParticularLabs/GitVersion/labels/up-for-grabs) - We are on [Up for grabs](http://up-for-grabs.net/), our up for grabs issues are tagged `up-for-grabs` - An understanding of our [architecture](#architecture) and how [we write tests](#writing-tests) -Once you know how to create a pull request and have an issue to work on, just post a comment saying you will work on it. +Once you know how to create a pull request and have an issue to work on, just post a comment saying you will work on it. If you end up not being able to complete the task, please post another comment so others can pick it up. -Issues are also welcome, [failing tests](#writing-tests) are even more welcome. +Issues are also welcome, [failing tests](#writing-tests) are even more welcome. + +# Contribution Guidelines + - Try to use feature branches rather than developing on master + - Please include tests covering the change + - The docs are now stored in the repository under the `Docs` folder, please include documentation updates with your PR # Architecture GitVersion has three distict steps for calculating versions in v3.0. 1. If the current commit is tagged, the tag is used and build metadata (Excluding commit count) is added. The other two steps will not execute -2. A set of strategies are evaluated to decide on the base version and some metadata about that version. +2. A set of strategies are evaluated to decide on the base version and some metadata about that version. These strategies include HighestReachableTag, NextVersionInConfig, MergedBranchWithVersion, VersionInBranchName etc. -3. The highest base version is selected, using that base version the new version is calculated. +3. The highest base version is selected, using that base version the new version is calculated. Visually it looks something like this: ![Version Calculation](http://www.plantuml.com:80/plantuml/png/fLCxJyCm4DxzAsuib4P914i69De1CS38Vd6kYIN7ZcodK8aVp-KX6Y2fKCbY9NV-7lVb2WoOeoVOMRDNfH0lz1vUoNbbpGwrR3K6ws1p3rlk-bN8u972f2AC3GHEbLN8m1D1Jjg-mPuXAZvx9kL1ZW1KY5dOZczMI0Pf54VnHtf7jpaAWJg0sW-uXw4PK3Eb1sMaevfCW6i1_0m6po1l7HfPJUxvu5XYUOHLWq5MLptCudmMK9--u5glJ0dIEaVo1Dw3JgVM6Km4cM9mzyrQXHuQHnj7chhl0JcnIrHjno1wiWtgfi8eWVK_7OQAmBHrJWvORFVM2PmrE7AcWZGh-Lj0FvptVvLiUPnCdG_XhNhOov9wQ1fzv7nw5S5EwSvw6CDQNfnMwUAP0XQyQpj70nkx3Nn3p5NFY9IshbNWepKi8ublWFiSPkC0ee8El75Dv5aOxqZQBScbWpWn0Pe2wb6aM1p4Eea_0G00) @@ -46,7 +51,7 @@ Each strategy needs to return an instance of `BaseVersion` which has the followi VersionInBranchBaseVersionStrategy uses this to strip out anything before the first - or /. So `foo` ends up being evaluated as `foo`. If in doubt, just use null # Writing Tests -We have made it super easy to write tests in GitVersion. Most tests you are interested in are in `GitVersionCore.Tests\IntegrationTests`. +We have made it super easy to write tests in GitVersion. Most tests you are interested in are in `GitVersionCore.Tests\IntegrationTests`. There is a scenario class for each type of branch. For example MasterScenarios, FeatureBranchScenarios etc. @@ -57,7 +62,7 @@ Find where your issue would logically sit. Or create a new scenario class if it We are currently using NUnit, so just create a descriptive test method and attribute it with `[Test]` ## 3. Use a fixture -We have a few fixtures for different scenarios. +We have a few fixtures for different scenarios. - `EmptyRepositoryFixture` - Gives you an empty git repo to start with - `RemoteRepositoryFixture` - A local repo tracking a test remote repository. The remote repo is available through the `Repository` property, the local is accessible via `LocalRepository` @@ -90,4 +95,4 @@ fixture.AssertFullSemver("1.0.1-test.1+5"); The last line is the most important. `AssertFullSemver` will run GitVersion and assert that the full SemVer it calculates is what you expect. ## 6. Submit a pull request with the failing test -Even better include the fix, but a failing test is a great start \ No newline at end of file +Even better include the fix, but a failing test is a great start diff --git a/Docs/buildServerSetup/appVeyor.md b/Docs/buildServerSetup/appVeyor.md new file mode 100644 index 0000000000..d406a98969 --- /dev/null +++ b/Docs/buildServerSetup/appVeyor.md @@ -0,0 +1,7 @@ +# AppVeyor Setup +AppVeyor is the first build server which has a setup helper built into `GitVersion init`. + + 1. Run `GitVersion init` + 2. Choose `Setup build scripts` (currently option 7, but that could change) + 3. Choose `AppVeyor` + 4. Follow the prompts to generate an appveyor.yml file which works nicely with GitVersion diff --git a/Docs/buildServers.md b/Docs/buildServers.md new file mode 100644 index 0000000000..d7a85da08e --- /dev/null +++ b/Docs/buildServers.md @@ -0,0 +1,30 @@ +# Build Server Support +GitVersion has support for quite a few build servers out of the box. Currently we support: + + - TeamCity + - AppVeyor + - Continua Ci + - MyGet + +When GitVersion.exe is run with the `/output buildserver` flag instead of outputting Json it will export variables to the current build server. +For instance if you are running in TeamCity after you run `GitVersion /output buildserver` you will have the `%system.GitVersion.SemVer%` available for you to use + +When running in MSBuild either from the MSBuild Task or by using the `/proj myproject.sln` GitVersion will make the MSBuild variables available in the format `$(GitVersion_SemVer)`. + +## Setup guides + - [AppVeyor](buildServerSetup/appVeyor.md) + +## Other plugins/helpers +### GitVersion meta runner for TeamCity +TeamCity has support for meta-runners which allow custom tasks. There is a GitVersion meta-runner available which makes it easy to use GitVersion. + + - [Project Link](https://github.com/JetBrains/meta-runner-power-pack/tree/master/gitversion) + +### GitVersion for Bamboo +If you use Bamboo then you can install *GitVersion for Bamboo* which gives you a GitVersion task in Bamboo. + + - [Blog Post](http://carolynvanslyck.com/blog/2015/03/gitversion-for-bamboo) + - [Project link](http://carolynvanslyck.com/projects/gitversion) + - [Download](https://marketplace.atlassian.com/plugins/com.carolynvs.gitversion) + - [Source](http://carolynvanslyck.com/projects/gitversion) + - [Issues](http://jira.carolynvanslyck.com/browse/GITVER) diff --git a/Docs/configuration.md b/Docs/configuration.md new file mode 100644 index 0000000000..dd9ff29e42 --- /dev/null +++ b/Docs/configuration.md @@ -0,0 +1,52 @@ +# Configuration +GitVersion 3.0 is mainly powered by configuration and no longer has branching strategies hard coded. + +## Configuration tool +If you run `GitVersion init` you will be launched into a configuration tool, it can help you configure GitVersion the way you want it. + +**Note:** GitVersion ships with internal default configuration which works with GitHubFlow and GitFlow, probably with others too. + +The *develop* branch is set to `ContinuousDeployment` mode by default as we have found that is generally what is needed when using GitFlow. + +You can run `GitVersion /showConfig` to see the effective configuration (defaults + overrides) + +To create your config file just type `GitVersion init` in your repo directory after installing via chocolatey and we will create a sample (but commented out) config file. +Uncomment and modify as you need. + +The configuration options are: + + - `next-version`: Allows you to bump the next version explicitly, useful for bumping `master` or a feature with breaking changes a major increment. + - `assembly-versioning-scheme`: When updating assembly info tells GitVersion how to treat the AssemblyVersion attribute. Useful to lock the major when using Strong Naming. + - `mode`: Either ContinuousDelivery or ContinuousDeployment. See [Octopus Deploy/CI Build NuGet Packages](#continuousdeployment) above for more information + - `continuous-delivery-fallback-tag`: When using `mode: ContinuousDeployment` the value specified will be used as the pre-release tag for branches which do not have one specified. + - `tag-prefix`: A regex which is used to trim git tags before processing (eg v1.0.0). Default is `[vV]` though this is just for illustrative purposes as we do a IgnoreCase match and could be `v` + +## Branch configuration + +Then we have branch specific configuration, which looks something like this: + +``` yaml +branches: + master: + tag: + increment: Patch + prevent-increment-of-merged-branch-version: true + (pull|pull\-requests|pr)[/-]: + tag: PullRequest + increment: Inherit + tag-number-pattern: '[/-](?\d+)[-/]' +``` + +The options in here are: + - `mode`: Same as above + - `tag`: The pre release tag to use for this branch. Use the value `use-branch-name-as-tag` to use the branch name instead. + For example `feature/foo` would become a pre-release tag of `foo` with this value + - `increment`: the part of the SemVer to increment when GitVersion detects it needs to be (i.e commit after a tag) + - `prevent-increment-of-merged-branch-version`: When `release-2.0.0` is merged into master, we want master to build `2.0.0`. + If `release-2.0.0` is merged into develop we want it to build `2.1.0`, this option prevents incrementing after a versioned branch is merged + - `tag-number-pattern`: Pull requests require us to pull the pre-release number out of the branch name so `refs/pulls/534/merge` builds as `PullRequest.5`. + This is a regex with a named capture group called `number` + - `track-merge-target`: Strategy which will look for tagged merge commits directly off the current branch. For example + develop -> release/1.0.0 -> merge into master and tag 1.0.0. The tag is *not* on develop, but develop should be 1.0.0 now. + +We don't envision many people needing to change most of these configuration values, but they are there if you need to. diff --git a/Docs/configurationOptions.md b/Docs/configurationOptions.md deleted file mode 100644 index 3cb2b938b1..0000000000 --- a/Docs/configurationOptions.md +++ /dev/null @@ -1 +0,0 @@ -# Configuration options diff --git a/Docs/examples.md b/Docs/examples.md new file mode 100644 index 0000000000..a6a65a7bd7 --- /dev/null +++ b/Docs/examples.md @@ -0,0 +1,42 @@ +# Examples +## Overview +![README](images/CommitGraph.png) + +At each commit sha GitVersion will calculate: + +``` +e137e9 -> 1.0.0+0 +a5f6c5 -> 1.0.1+1 +adb29a -> 1.0.1-feature-foo.1+1 (PR #5 Version: `1.0.1-PullRequest.5+2`) +7c2438 -> 1.0.1-feature-foo.1+2 (PR #5 Version: `1.0.1-PullRequest.5+3`) +5f413b -> 1.0.1+4 +d6155b -> 2.0.0-rc.1+0 (Before and after tag) +d53ab6 -> 2.0.0-rc.2+1 (Pre-release number was bumped because of the tag on previous commit) +b5d142 -> 2.0.0+0 (2.0.0 branch was merged, so master is now at 2.0.0) +``` + +This is just a small sample of the way GitVersion works. The idea is you just plug it in and you will get sensible version numbers by default. We support the following branch types ootb: + + - master + - develop + - hotfix/ + - feature/ + - pull requests (stash, github and a few others) + - support/ + - release/ + +If you have other branch types GitVersion is entirely configuration driven, so check out the [Configuration](#Configuration) section of the readme to understand how to make GitVersion work for you. + +## GitFlow +### Continuous Delivery mode +TODO Example of GitFlow using continuous delivery mode + +### Continuous Deployment mode +TODO Example of GitFlow using continuous deployment mode + +## GitHubFlow +### Continuous Delivery mode +TODO Example of GitHubFlow using continuous delivery mode + +### Continuous Deployment mode +TODO Example of GitHubFlow using continuous deployment mode diff --git a/Docs/faq.md b/Docs/faq.md new file mode 100644 index 0000000000..1aa8f435ba --- /dev/null +++ b/Docs/faq.md @@ -0,0 +1,13 @@ +# FAQ + +## Why is my version not incrementing? +GitVersion calculates the semantic version, this will only change once per *release*. Read more at [version increments](./versionIncrements.md) + +## I can't use the build number for NuGet +If you have used NuGet you would notice the versions above are not compatible with NuGet. GitVersion solves this by providing *variables*. + +What you have seen above is the **SemVer** variable. You can use the **NuGetVersion** variable to have the version formatted in a NuGet compatible way. +So `1.0.1-rc.1+5` would become `1.0.1-rc0001`, this takes into account characters which are not allowed and NuGets crap sorting. + +**note: ** The `NuGetVersion` variable is floating, so when NuGet 3.0 comes out with proper SemVer support GitVersion will switch this variable to a proper SemVer. +If you want to fix the version, use `NuGetVersionV2` which will stay the same after NuGet 3.0 comes out diff --git a/Docs/howItWorks.md b/Docs/howItWorks.md new file mode 100644 index 0000000000..33b974141e --- /dev/null +++ b/Docs/howItWorks.md @@ -0,0 +1 @@ +# How it works diff --git a/Icons/CommitGraph.png b/Docs/images/CommitGraph.png similarity index 100% rename from Icons/CommitGraph.png rename to Docs/images/CommitGraph.png diff --git a/Docs/incrementingPerCommit.md b/Docs/incrementingPerCommit.md new file mode 100644 index 0000000000..f9290abf37 --- /dev/null +++ b/Docs/incrementingPerCommit.md @@ -0,0 +1,18 @@ +# Incrementing per commit +When using the continuous deployment mode (which will increment the SemVer every commit) all builds *must* have a pre-release tag, except for builds which are explicitly tagged as stable. +Then the build metadata (which is the commit count) is promoted to the pre-release tag. Applying those rules the above commit graph would produce: + +``` +e137e9 -> 1.0.0+0 +a5f6c5 -> 1.0.1-ci.1 +adb29a -> 1.0.1-feature-foo.1 (PR #5 Version: `1.0.1-PullRequest.5+2`) +7c2438 -> 1.0.1-feature-foo.2 (PR #5 Version: `1.0.1-PullRequest.5+3`) +5f413b -> 1.0.1-ci.4 +d6155b -> 2.0.0-rc.1+4 (Before and after tag) +d53ab6 -> 2.0.0-rc.2 (If there was another commit on the release branch it would be 2.0.0-rc.3) +b5d142 -> 2.0.0-ci.0 (2.0.0 branch was merged, so master is now at 2.0.0) +``` + +As you can see the versions now no longer conflict. When you want to create a stable `2.0.0` release you simply `git tag 2.0.0` then build the tag and it will produce a stable 2.0.0 package. + +For more information/background on why we have come to this conclusion read [Xavier Decoster's blog post on the subject](http://www.xavierdecoster.com/semantic-versioning-auto-incremented-nuget-package-versions). diff --git a/Docs/readme.md b/Docs/readme.md index 38845b9d62..594ed65160 100644 --- a/Docs/readme.md +++ b/Docs/readme.md @@ -1,5 +1,5 @@ # GitVersion Docs -GitVersion is a tool to help you achieve Semantic Versioning on your project. +GitVersion is a tool to help you achieve *Semantic Versioning* on your project. This influences many of the decisions GitVersion has made, please read and understand this page as it will help you start using GitVersion effectively! @@ -26,7 +26,7 @@ Read more at [version sources](./versionSources.md) ## Configuration GitVersion v3 was rewritten to be very configuration driven rather than hardcoding git workflows into it. This has made it a lot more flexible. Configuration options can be set globally or per branch. -Read more about the different [configuration options](./configurationOptions.md) +Read more about [configuration](./configuration.md) ## Output Variables We recognise that a single formatted version number does not work for all cases. A simple example is NuGet, it doesn't support SemVer 2.0 meaning that the SemVer of `1.3.5-beta.10+500` needs to be formatted as `1.3.5-beta0010` so it will sort properly. diff --git a/Docs/usage.md b/Docs/usage.md index e96e88f0f0..e5b9723f3c 100644 --- a/Docs/usage.md +++ b/Docs/usage.md @@ -1,7 +1,9 @@ # Usage -Info about exe and msbuild task. +There are two main ways to consume GitVersion, the first is by running GitVersion.exe. The second is an MSBuild task. The MSBuild task is really easy to get up and running, simply install GitVersionTask from NuGet and it will integrate into your project and write out variables to your build server if it's running on one. The exe offers more options and works for not just .net projects. -### Output options -By default GitVersion returns a json object to stdout. This works great if you want to get your build scripts to parse the json object then use the variables, but there is a simpler way. + - [A Command Line tool](usage/commandLine.md) + - [An MSBuild Task](usage/msbuildTask.md) -`GitVersion.exe /output buildserver` will change the mode of GitVersion to write out the variables to whatever build server it is running in. You can then use those variables in your build scripts or run different tools to create versioned NuGet packages or whatever you would like to do. +## Other options + - [A NuGet Library package](https://github.com/Particular/GitVersion/wiki/GitVersion-NuGet-Library) - to use from your own code. Warning, we are not semantically versioning this library and it should be considered unstable. + - [A Ruby Gem](https://github.com/Particular/GitVersion/wiki/Ruby-Gem) - just a gem wrapper around the command line to make it easier to consume from Rake diff --git a/Docs/usage/commandLine.md b/Docs/usage/commandLine.md new file mode 100644 index 0000000000..f3c91f28f5 --- /dev/null +++ b/Docs/usage/commandLine.md @@ -0,0 +1,6 @@ +# Command Line Usage + +## Output +By default GitVersion returns a json object to stdout. This works great if you want to get your build scripts to parse the json object then use the variables, but there is a simpler way. + +`GitVersion.exe /output buildserver` will change the mode of GitVersion to write out the variables to whatever build server it is running in. You can then use those variables in your build scripts or run different tools to create versioned NuGet packages or whatever you would like to do. diff --git a/Docs/usage/msbuildTask.md b/Docs/usage/msbuildTask.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/Docs/variables.md b/Docs/variables.md new file mode 100644 index 0000000000..1ac600b029 --- /dev/null +++ b/Docs/variables.md @@ -0,0 +1,26 @@ +# Variables +Variables are quite useful if you need different formats of the version number. Running `GitVersion.exe` in your repo will show you what is available. +For the `release/3.0.0` branch of GitVersion it shows: + +```json +{ + "Major":3, + "Minor":0, + "Patch":0, + "PreReleaseTag":"beta.1", + "PreReleaseTagWithDash":"-beta.1", + "BuildMetaData":1, + "FullBuildMetaData":"1.Branch.release/3.0.0.Sha.28c853159a46b5a87e6cc9c4f6e940c59d6bc68a", + "MajorMinorPatch":"3.0.0", + "SemVer":"3.0.0-beta.1", + "LegacySemVer":"3.0.0-beta1", + "LegacySemVerPadded":"3.0.0-beta0001", + "AssemblySemVer":"3.0.0.0", + "FullSemVer":"3.0.0-beta.1+1", + "InformationalVersion":"3.0.0-beta.1+1.Branch.release/3.0.0.Sha.28c853159a46b5a87e6cc9c4f6e940c59d6bc68a", + "BranchName":"release/3.0.0", + "Sha":"28c853159a46b5a87e6cc9c4f6e940c59d6bc68a", + "NuGetVersionV2":"3.0.0-beta0001", + "NuGetVersion":"3.0.0-beta0001" +} +``` diff --git a/Docs/whoIsUsingGitVersion.md b/Docs/whoIsUsingGitVersion.md new file mode 100644 index 0000000000..e5ccb6e3c8 --- /dev/null +++ b/Docs/whoIsUsingGitVersion.md @@ -0,0 +1 @@ +# Who is using GitVersion diff --git a/GitVersionCore/OutputVariables/VariableProvider.cs b/GitVersionCore/OutputVariables/VariableProvider.cs index 0f9938e6cc..aff0c3a5ab 100644 --- a/GitVersionCore/OutputVariables/VariableProvider.cs +++ b/GitVersionCore/OutputVariables/VariableProvider.cs @@ -11,7 +11,7 @@ public static VersionVariables GetVariablesFor( if (mode == VersioningMode.ContinuousDeployment && !currentCommitIsTagged) { semanticVersion = new SemanticVersion(semanticVersion); - // Continuous Delivery always requires a pre-release tag unless the commit is tagged + // Continuous Deployment always requires a pre-release tag unless the commit is tagged if (!semanticVersion.PreReleaseTag.HasTag()) { semanticVersion.PreReleaseTag.Name = continuousDeploymentFallbackTag; diff --git a/README.md b/README.md index efe7294b4d..bc0fc142c1 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@ ![Icon](https://raw.github.com/Particular/GitVersion/master/Icons/package_icon.png) +# GitVersion +[![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/GitTools/GitVersion?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -The easy way to use semantic versioning (semver.org) with a Git. Running GitVersion will calculate the SemVer of your application by looking at your git history. - -GitVersion in action! +Versioning when using git, solved. GitVersion looks at your git history and works out the semantic versioning ([semver.org](http://semver.org)) of the commit being built. +## GitVersion in action! ![README](Icons/README.png) You are seeing: @@ -11,203 +12,11 @@ You are seeing: - Pull requests being built as pre-release builds - A branch called `release-1.0.0` producing beta v1 packages -## Examples - -## How it works -![README](Icons/CommitGraph.png) - -At each commit sha GitVersion will calculate: - -``` -e137e9 -> 1.0.0+0 -a5f6c5 -> 1.0.1+1 -adb29a -> 1.0.1-feature-foo.1+1 (PR #5 Version: `1.0.1-PullRequest.5+2`) -7c2438 -> 1.0.1-feature-foo.1+2 (PR #5 Version: `1.0.1-PullRequest.5+3`) -5f413b -> 1.0.1+4 -d6155b -> 2.0.0-rc.1+0 (Before and after tag) -d53ab6 -> 2.0.0-rc.2+1 (Pre-release number was bumped because of the tag on previous commit) -b5d142 -> 2.0.0+0 (2.0.0 branch was merged, so master is now at 2.0.0) -``` - -This is just a small sample of the way GitVersion works. The idea is you just plug it in and you will get sensible version numbers by default. We support the following branch types ootb: - - - master - - develop - - hotfix/ - - feature/ - - pull requests (stash, github and a few others) - - support/ - - release/ - -If you have other branch types GitVersion is entirely configuration driven, so check out the [Configuration](#Configuration) section of the readme to understand how to make GitVersion work for you. - -### The rules -GitVersion has a few things which can impact the version, first we calculate the base version then we increment if needed and finally we calculate the build metadata (including commit count). -The exception, if a commit is tagged we always use that version. - -There are a few ways the base version is found, they are: - - - Git tag (increments using default rules) - - Version in branch name - for example `release-1.0.0` (does not get incremented) - - Merge message - so when the versioned branch is merged the version is carried with it (does not get incremented) - - GitVersion.yaml configuration file (`next-version` property) (does not get incremented) - -The commit counting is done from where the base version originated from. - - -## Octopus Deploy/CI Build NuGet Packages -Those of you who have tried to do SemVer with Octopus Deploy or consume CI packages out of TeamCity would have hit -the problem that the SemVer version does not change each commit. - -By default GitVersion is setup for *continuous delivery*, meaning that when you want to release you publish the artifact attached to -your CI Build ([read more about what this means](https://github.com/GitTools/GitVersion/wiki/Continuous-Delivery-Mode)). - -If you want to consume packages from you CI server, for instance Octopus Deploy is looking at TeamCity's NuGet feed then you want GitVersion's *continuous deployment mode*. -See the [Configuration](#configuration) - -When using the continuous deployment mode all builds *must* have a pre-release tag, except for builds which are explicitly tagged as stable. -Then the build metadata (which is the commit count) is promoted to the pre-release tag. Applying those rules the above commit graph would produce: - -``` -e137e9 -> 1.0.0+0 -a5f6c5 -> 1.0.1-ci.1 -adb29a -> 1.0.1-feature-foo.1 (PR #5 Version: `1.0.1-PullRequest.5+2`) -7c2438 -> 1.0.1-feature-foo.2 (PR #5 Version: `1.0.1-PullRequest.5+3`) -5f413b -> 1.0.1-ci.4 -d6155b -> 2.0.0-rc.1+4 (Before and after tag) -d53ab6 -> 2.0.0-rc.2 (If there was another commit on the release branch it would be 2.0.0-rc.3) -b5d142 -> 2.0.0-ci.0 (2.0.0 branch was merged, so master is now at 2.0.0) -``` - -As you can see the versions now no longer conflict. When you want to create a stable `2.0.0` release you simply `git tag 2.0.0` then build the tag and it will produce a stable 2.0.0 package. - -For more information/background on why we have come to this conclusion read [Xavier Decoster's blog post on the subject](http://www.xavierdecoster.com/semantic-versioning-auto-incremented-nuget-package-versions). -The issue has also been discussed in quite a few issues. If you have other thoughts on this subject please open an issue to discuss! - -### NuGet Compatibility -Again, if you have used NuGet you would notice the versions above are not compatible with NuGet. GitVersion solves this by providing *variables*. - -What you have seen above is the **SemVer** variable. You can use the **NuGetVersion** variable to have the version formatted in a NuGet compatible way. -So `1.0.1-rc.1+5` would become `1.0.1-rc0001`, this takes into account characters which are not allowed and NuGets crap sorting. - -**note: ** The `NuGetVersion` variable is floating, so when NuGet 3.0 comes out with proper SemVer support GitVersion will switch this variable to a proper SemVer. -If you want to fix the version, use `NuGetVersionV2` which will stay the same after NuGet 3.0 comes out - -## Variables -Variables are quite useful if you need different formats of the version number. Running `GitVersion.exe` in your repo will show you what is available. -For the `release/3.0.0` branch of GitVersion it shows: -```json -{ - "Major":3, - "Minor":0, - "Patch":0, - "PreReleaseTag":"beta.1", - "PreReleaseTagWithDash":"-beta.1", - "BuildMetaData":1, - "FullBuildMetaData":"1.Branch.release/3.0.0.Sha.28c853159a46b5a87e6cc9c4f6e940c59d6bc68a", - "MajorMinorPatch":"3.0.0", - "SemVer":"3.0.0-beta.1", - "LegacySemVer":"3.0.0-beta1", - "LegacySemVerPadded":"3.0.0-beta0001", - "AssemblySemVer":"3.0.0.0", - "FullSemVer":"3.0.0-beta.1+1", - "InformationalVersion":"3.0.0-beta.1+1.Branch.release/3.0.0.Sha.28c853159a46b5a87e6cc9c4f6e940c59d6bc68a", - "BranchName":"release/3.0.0", - "Sha":"28c853159a46b5a87e6cc9c4f6e940c59d6bc68a", - "NuGetVersionV2":"3.0.0-beta0001", - "NuGetVersion":"3.0.0-beta0001" -} - -``` - -## Configuration -GitVersion 3.0 is mainly powered by configuration and no longer has branching strategies hard coded. -**Note:** GitVersion ships with internal default configuration which works with GitHubFlow and GitFlow, probably with others too. You **do not** need to run `GitVersion /init` to get started! -The *develop* branch is set to `ContinuousDeployment` mode by default as we have found that is generally what is needed when using GitFlow. - -You can run `GitVersion /showConfig` to see the effective configuration (defaults + overrides) - -To create your config file just type `GitVersion init` in your repo directory after installing via chocolatey and we will create a sample (but commented out) config file. -Uncomment and modify as you need. - -The configuration options are: - - - `next-version`: Allows you to bump the next version explicitly, useful for bumping `master` or a feature with breaking changes a major increment. - - `assembly-versioning-scheme`: When updating assembly info tells GitVersion how to treat the AssemblyVersion attribute. Useful to lock the major when using Strong Naming. - - `mode`: Either ContinuousDelivery or ContinuousDeployment. See [Octopus Deploy/CI Build NuGet Packages](#continuousdeployment) above for more information - - `continuous-delivery-fallback-tag`: When using `mode: ContinuousDeployment` the value specified will be used as the pre-release tag for branches which do not have one specified. - - `tag-prefix`: A regex which is used to trim git tags before processing (eg v1.0.0). Default is `[vV]` though this is just for illustrative purposes as we do a IgnoreCase match and could be `v` - -#### Branch configuration - -Then we have branch specific configuration, which looks something like this: - -``` yaml -branches: - master: - tag: - increment: Patch - prevent-increment-of-merged-branch-version: true - (pull|pull\-requests|pr)[/-]: - tag: PullRequest - increment: Inherit - tag-number-pattern: '[/-](?\d+)[-/]' -``` - -The options in here are: - - `mode`: Same as above - - `tag`: The pre release tag to use for this branch. Use the value `use-branch-name-as-tag` to use the branch name instead. - For example `feature/foo` would become a pre-release tag of `foo` with this value - - `increment`: the part of the SemVer to increment when GitVersion detects it needs to be (i.e commit after a tag) - - `prevent-increment-of-merged-branch-version`: When `release-2.0.0` is merged into master, we want master to build `2.0.0`. - If `release-2.0.0` is merged into develop we want it to build `2.1.0`, this option prevents incrementing after a versioned branch is merged - - `tag-number-pattern`: Pull requests require us to pull the pre-release number out of the branch name so `refs/pulls/534/merge` builds as `PullRequest.5`. - This is a regex with a named capture group called `number` - - `track-merge-target`: Strategy which will look for tagged merge commits directly off the current branch. For example - develop -> release/1.0.0 -> merge into master and tag 1.0.0. The tag is *not* on develop, but develop should be 1.0.0 now. - -We don't envision many people needing to change most of these configuration values, but they are there if you need to. - -## Build Server support -GitVersion has support for quite a few build servers out of the box. Currently we support: - - - TeamCity - - AppVeyor - - Continua Ci - - MyGet - -When GitVersion.exe is run with the `/output buildserver` flag instead of outputting Json it will export variables to the current build server. -For instance if you are running in TeamCity after you run `GitVersion /output buildserver` you will have the `%system.GitVersion.SemVer%` available for you to use - -When running in MSBuild either from the MSBuild Task or by using the `/proj myproject.sln` GitVersion will make the MSBuild variables available in the format `$(GitVersion_SemVer)`. - -## MSBuild Task/Ruby Gem/API -GitVersion has multiple ways it can be consumed. - - - [A Command Line tool](https://github.com/Particular/GitVersion/wiki/Command-Line-Tool) - - [An MSBuild Task](https://github.com/Particular/GitVersion/wiki/MSBuild-Task-Usage) - - [A NuGet Library package](https://github.com/Particular/GitVersion/wiki/GitVersion-NuGet-Library) - to use from your own code - - [A Ruby Gem](https://github.com/Particular/GitVersion/wiki/Ruby-Gem) - -### Examples -We have a bunch of examples in our Wiki, if something is missing, let us know! There are examples for GitHubFlow and GitFlow - -### Who is using GitVersion? -Find a list of projects who are currently using GitVersion [here](https://github.com/GitTools/GitVersion/wiki/Who-is-using-GitVersion%3F) - -## Additional Links - -### [FAQ and Common Problems](https://github.com/Particular/GitVersion/wiki/FAQ) - -### [Semantic Versioning](http://semver.org/) - -### [Git Visualiser used above](http://onlywei.github.io/explain-git-with-d3/) - -## Chat - -Have questions? Come join in the chat room: - -[![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/GitTools/GitVersion?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +## Quick Links + - [Documentation](https://github.com/GitTools/GitVersion/tree/master/Docs) + - [How it works](https://github.com/GitTools/GitVersion/tree/master/Docs/howItWorks.md) + - [FAQ](https://github.com/GitTools/GitVersion/tree/master/Docs/faq.md) + - [Who is using GitVersion](https://github.com/GitTools/GitVersion/tree/master/Docs/whoIsUsingGitVersion) ## Icon Tree designed by David Chapman from The Noun Project From 65b04a58079b366f8603c03a890805d6dfc857a1 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Wed, 15 Jul 2015 13:39:39 +0800 Subject: [PATCH 2/6] Relative paths --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index bc0fc142c1..587d04a078 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,10 @@ You are seeing: - A branch called `release-1.0.0` producing beta v1 packages ## Quick Links - - [Documentation](https://github.com/GitTools/GitVersion/tree/master/Docs) - - [How it works](https://github.com/GitTools/GitVersion/tree/master/Docs/howItWorks.md) - - [FAQ](https://github.com/GitTools/GitVersion/tree/master/Docs/faq.md) - - [Who is using GitVersion](https://github.com/GitTools/GitVersion/tree/master/Docs/whoIsUsingGitVersion) + - [Documentation](Docs/) + - [How it works](Docs/howItWorks.md) + - [FAQ](Docs/faq.md) + - [Who is using GitVersion](whoIsUsingGitVersion) ## Icon Tree designed by David Chapman from The Noun Project From 3f3ea6ccd9e2982e724f38312e652a5ec18773df Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Wed, 15 Jul 2015 13:54:43 +0800 Subject: [PATCH 3/6] Added why gitversion --- Docs/readme.md | 2 ++ Docs/why.md | 24 ++++++++++++++++++++++++ README.md | 3 ++- 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 Docs/why.md diff --git a/Docs/readme.md b/Docs/readme.md index 594ed65160..8880465e58 100644 --- a/Docs/readme.md +++ b/Docs/readme.md @@ -1,4 +1,6 @@ # GitVersion Docs +**NOTE:** We will move these docs onto a GitHub.io page, but for the moment just use the GitHub source explorer to move around the docs. + GitVersion is a tool to help you achieve *Semantic Versioning* on your project. This influences many of the decisions GitVersion has made, please read and understand this page as it will help you start using GitVersion effectively! diff --git a/Docs/why.md b/Docs/why.md new file mode 100644 index 0000000000..486728bfd7 --- /dev/null +++ b/Docs/why.md @@ -0,0 +1,24 @@ +# Why use GitVersion +GitVersion makes versioning woes a thing of the past. It looks at your git history to calculate what the version currently is. I have seen and used many different approaches in the past, all have downfalls and often are not transportable between projects. + +It solves: + - Rebuilding tags always produces the same version + - Not having to rebuild to increment versions + - Not duplicating version information in multiple places (branch release/2.0.0 already has the version in it, why do I need to change something else) + - Each branch calculates it's SemVer and versions flow between branches when they are merged + - Pull requests produce unique pre-release version numbers + - NuGet semver issues + - Build server integration + - Updating assembly info + - And a whole lot of edge cases you don't want to think about + +## Advantages vs other approaches +### Version.txt/Version in build script + - With version.txt/build script, after the release you need to do an additional commit to bump the version + - After tagging a release, the next build will still be the same version + +### Build Server versioning + - Cannot have different version numbers on different branches + - Rebuilding will result in a different build number (if using an auto incrementing number in the version) + - Need to login to the build server to change version number + - Only build administrators can change the version number diff --git a/README.md b/README.md index 587d04a078..986a610f00 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,8 @@ You are seeing: - A branch called `release-1.0.0` producing beta v1 packages ## Quick Links - - [Documentation](Docs/) + - [Why GitVersion](Docs/why.md) + - [Documentation](Docs/#gitversion-docs) - [How it works](Docs/howItWorks.md) - [FAQ](Docs/faq.md) - [Who is using GitVersion](whoIsUsingGitVersion) From d7aab24c0a1cb310f016f9901657b0dade616365 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Wed, 15 Jul 2015 14:15:59 +0800 Subject: [PATCH 4/6] Few more notes on version incrementing --- Docs/versionIncrements.md | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/Docs/versionIncrements.md b/Docs/versionIncrements.md index d539715ffa..f94a84c673 100644 --- a/Docs/versionIncrements.md +++ b/Docs/versionIncrements.md @@ -1,22 +1,39 @@ # Version Incrementing -SemVer is all about *releases*, not builds. When you release the next version of your library/app/website/whatever you should only increment major/minor or patch then reset all lower parts to 0, for instance given 1.0.0, the next release should be either `2.0.0`, `1.1.0` or `1.0.1`. Bumping one of the version components by more than 1 in a single release means you will be missing versions. +Because GitVersion works with a number of workflows the way it does it's version incrementing may work perfectly for you, or it may cause you issues. This page is split up into two sections, first is all about understanding the approach GitVersion uses by default, and the second is how you can manually increment the version. -Because of this, GitVersion works out what the next SemVer of your app is on each commit. When you are ready to release you simply deploy the latest built version and tag the release it was from. This practice is called *continuous delivery*. GitVersion will increment the metadata for each build so you can tell builds apart. For example `1.0.0+5` followed by `1.0.0+6`. +## Approach +Semantic Versioning is all about *releases*, not builds. When you release the next version of your library/app/website/whatever you should only increment major/minor or patch then reset all lower parts to 0, for instance given 1.0.0, the next release should be either `2.0.0`, `1.1.0` or `1.0.1`. Bumping one of the version components by more than 1 in a single release means you will have gaps in your version number, which defeats the purpose of SemVer. + +Because of this, GitVersion works out what the next SemVer of your app is on each commit. When you are ready to release you simply deploy the latest built version and tag the release it was from. This practice is called **continuous delivery**. GitVersion will increment the *metadata* for each build so you can tell builds apart. For example `1.0.0+5` followed by `1.0.0+6`. It is important to note that build metadata *is not part of the semantic version, it is just metadata!*. + +All this effectively means that GitVersion will produce the same version NuGet package each commit until you tag a release. This causes problems for people as NuGet and other package managers do not support multiple packages with the same version with only different metadata. There are a few ways to handle this problem depending on what your requirements are: -## 1. GitFlow -If you are using GitFlow then builds off the `develop` branch will actually increment on every commit. By default `develop` builds are tagged with the `unstable` pre-release tag. This is so they are sorted higher than release branches. +### 1. GitFlow +If you are using GitFlow then builds off the `develop` branch will actually *increment on every commit*. This is known in GitVersion as *continuous deployment mode*. By default `develop` builds are tagged with the `unstable` pre-release tag. This is so they are sorted higher than release branches. If you need to consume packages built from develop, we recommend publishing these packages to a separate NuGet feed as an alpha channel. That way you can publish beta/release candidate builds and only people who opt into the alpha feed will see the unstable pacakges. -## 2. Octopus deploy +### 2. Octopus deploy Because Octopus uses NuGet under the covers you cannot publish every build into Octopus deploy. For this we have two possible options: -### 2a. 'Release' packages to Octopus deploy +#### 2a. 'Release' packages to Octopus deploy Rather than all builds going into Octopus's NuGet feed, you release builds into it's feed. When you push a package into the NuGet feed you need to tag that release. The next commit will then increment the version. This has the advantage that if you have a multi-stage deployment pipeline you pick packages which you would like to start through the pipeline, then you can see all the versions which did not make it through the pipeline (for instance, they got to UAT but not production due to a bug being found). In the release notes this can be mentioned or those versions can be skipped. -### 2b. Configure GitVersion to increment per commit +#### 2b. Configure GitVersion to increment per commit As mentioned above, this means you will burn multiple versions per release. This might not be an issue for you, but can confuse consumers of your library as the version has semantic meaning. + +## Manually incrementing the version +With v3 there are multiple approaches. + +### GitVersionConfig.yaml +The first is by setting the `next-version` property in the GitVersionConfig.yaml file. This property only serves as a base version, + +### Branch name +If you create a branch with the version number in the branch name such as `release-1.2.0` or `hotfix/1.0.1` then GitVersion will take the version number from the branch name as a source + +### Tagging commit +By tagging a commit, GitVersion will use that tag for the version of that commit, then increment the next commit automatically based on the increment rules for that branch (some branches bump patch, some minor). From d44eea6d657336bd3684d532e46f0d0dfefae1ba Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Wed, 15 Jul 2015 14:18:26 +0800 Subject: [PATCH 5/6] How to choose branching strategy --- Docs/faq.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Docs/faq.md b/Docs/faq.md index 1aa8f435ba..f8a254eef1 100644 --- a/Docs/faq.md +++ b/Docs/faq.md @@ -11,3 +11,6 @@ So `1.0.1-rc.1+5` would become `1.0.1-rc0001`, this takes into account character **note: ** The `NuGetVersion` variable is floating, so when NuGet 3.0 comes out with proper SemVer support GitVersion will switch this variable to a proper SemVer. If you want to fix the version, use `NuGetVersionV2` which will stay the same after NuGet 3.0 comes out + +## How do I choose my branching strategy (GitFlow vs GitHubFlow) +If you run `gitversion init` then choose `Getting started wizard` then choose `Unsure, tell me more`, GitVersion will run through a series of questions which will try and help point you towards a branching strategy and why you would use it. From d29f898677a5a2036d49e60f125b30c2fb3ebff3 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Wed, 15 Jul 2015 14:55:48 +0800 Subject: [PATCH 6/6] Bunch more docs --- Docs/branchingStrategies/gitFlow.md | 134 +++++++++++++++++++ Docs/branchingStrategies/readme.md | 1 + Docs/buildServerSetup/dynamicRepositories.md | 37 +++++ Docs/buildServerSetup/teamCity.md | 60 +++++++++ Docs/buildServers.md | 1 + Docs/faq.md | 8 ++ Docs/introToSemVer.md | 27 ++++ Docs/usage/commandLine.md | 13 +- Docs/usage/gem.md | 32 +++++ Docs/usage/msbuildTask.md | 33 +++++ Docs/versionIncrements.md | 2 +- Docs/whoIsUsingGitVersion.md | 12 ++ 12 files changed, 356 insertions(+), 4 deletions(-) create mode 100644 Docs/branchingStrategies/gitFlow.md create mode 100644 Docs/branchingStrategies/readme.md create mode 100644 Docs/buildServerSetup/dynamicRepositories.md create mode 100644 Docs/buildServerSetup/teamCity.md create mode 100644 Docs/introToSemVer.md create mode 100644 Docs/usage/gem.md diff --git a/Docs/branchingStrategies/gitFlow.md b/Docs/branchingStrategies/gitFlow.md new file mode 100644 index 0000000000..8f620c253e --- /dev/null +++ b/Docs/branchingStrategies/gitFlow.md @@ -0,0 +1,134 @@ +#GitFlow +GitFlow allows more structured releases, and GitVersion will derive sensible SemVer compatible versions from this structure. + +### Assumptions: + +* Using [GitFlow branching model](http://nvie.com/git-model/) which always has a master and a develop branch +* Following [Semantic Versioning](http://semver.org/) +* Planned releases (bumps in major or minor) are done on release branches prefixed with release-. Eg: release-4.1 (or release-4.1.0) +* Hotfixes are prefixed with hotfix- Eg. hotfix-4.0.4 +* 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. +* Tags are used on the master branch and reflects the SemVer of each stable release eg 3.3.8 , 4.0.0, etc +* Tags can also be used to override versions while we transition repositories over to GitVersion +* Using a build server with multi-branch building enabled eg TeamCity 8 + +### How Branches are handled + +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: + +* `targetBranch` => the branch we are targeting +* `targetCommit` => the commit we are targeting on `targetbranch` + +#### Master branch + +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. + +If we try to build from a commit that is no merge and no tag then assume `0.1.0` + +`mergeVersion` => the SemVer extracted from `targetCommit.Message` + +* major: `mergeVersion.Major` +* minor: `mergeVersion.Minor` +* patch: `mergeVersion.Patch` +* pre-release: 0 (perhaps count ahead commits later) +* stability: final + +Optional Tags (only when transitioning existing repository): +* TagOnHeadCommit.Name={semver} => overrides the version to be {semver} + +Long version: + + {major}.{minor}.{patch} Sha:'{sha}' + 1.2.3 Sha:'a682956dccae752aa24597a0f5cd939f93614509' + +#### Develop branch + +`targetCommitDate` => the date of the `targetCommit` +`masterVersionCommit` => the first version (merge commit or SemVer tag) on `master` that is older than the `targetCommitDate` +`masterMergeVersion` => the SemVer extracted from `masterVersionCommit.Message` + +* major: `masterMergeVersion.Major` +* minor: `masterMergeVersion.Minor + 1` (0 if the override above is used) +* patch: 0 +* pre-release: `unstable{n}` where n = how many commits `develop` is in front of `masterVersionCommit.Date` ('0' padded to 4 characters) + +Long version: + + {major}.{minor}.{patch}-{pre-release} Branch:'{branchName}' Sha:'{sha}' + 1.2.3-unstable645 Branch:'develop' Sha:'a682956dccae752aa24597a0f5cd939f93614509' + +#### Hotfix branches + +Named: `hotfix-{versionNumber}` eg `hotfix-1.2` + +`branchVersion` => the SemVer extracted from `targetBranch.Name` + +* major: `mergeVersion.Major` +* minor: `mergeVersion.Minor` +* patch: `mergeVersion.Patch` +* pre-release: `beta{n}` where n = number of commits on branch ('0' padded to 4 characters) + +Long version: + + {major}.{minor}.{patch}-{pre-release} Branch:'{branchName}' Sha:'{sha}' + 1.2.3-beta645 Branch:'hotfix-foo' Sha:'a682956dccae752aa24597a0f5cd939f93614509' + +#### Release branches + + * May branch off from: develop + * Must merge back into: develop and master + * Branch naming convention: `release-{n}` eg `release-1.2` + +`releaseVersion` => the SemVer extracted from `targetBranch.Name` +`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` + +* major: `mergeVersion.Major` +* minor: `mergeVersion.Minor` +* patch: 0 +* pre-release: `{releaseTag.preRelease}.{n}` where n = 1 + the number of commits since `releaseTag`. + +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` + +Long version: + + {major}.{minor}.{patch}-{pre-release} Branch:'{branchName}' Sha:'{sha}' + 1.2.3-alpha2.4 Branch:'release-1.2' Sha:'a682956dccae752aa24597a0f5cd939f93614509' + 1.2.3-rc2 Branch:'release-1.2' Sha:'a682956dccae752aa24597a0f5cd939f93614509' + +#### Feature branches + +May branch off from: `develop` +Must merge back into: `develop` +Branch naming convention: anything except `master`, `develop`, `release-{n}`, or `hotfix-{n}`. + +TODO: feature branches cannot start with a SemVer. to stop people from create branches named like "4.0.3" + +* major: `masterMergeVersion.Major` +* minor: `masterMergeVersion.Minor + 1` (0 if the override above is used) +* patch: 0 +* pre-release: `unstable.feature-{n}` where n = First 8 characters of the commit SHA of the first commit + + +Long version: + + {major}.{minor}.{patch}-{pre-release} Branch:'{branchName}' Sha:'{sha}' + 1.2.3-unstable.feature-a682956d Branch:'feature1' Sha:'a682956dccae752aa24597a0f5cd939f93614509' + +#### Pull-request branches + +May branch off from: `develop` +Must merge back into: `develop` +Branch naming convention: anything except `master`, `develop`, `release-{n}`, or `hotfix-{n}`. Canonical branch name contains `/pull/`. + +* major: `masterMergeVersion.Major` +* minor: `masterMergeVersion.Minor + 1` (0 if the override above is used) +* patch: 0 +* pre-release: `unstable.pull{n}` where n = the pull request number ('0' padded to 4 characters) + +### Nightly Builds + +**develop**, **feature** and **pull-request** builds are considered nightly builds and as such are not in strict adherence to SemVer. + +## Release Candidates + +How do we do release candidates?? Perhaps tag a release branch and then count commits forward from the tag to get RC1, RC2 etc?? diff --git a/Docs/branchingStrategies/readme.md b/Docs/branchingStrategies/readme.md new file mode 100644 index 0000000000..4194877af6 --- /dev/null +++ b/Docs/branchingStrategies/readme.md @@ -0,0 +1 @@ +This folder contains notes about different branching strategies and how they work in GitVersion diff --git a/Docs/buildServerSetup/dynamicRepositories.md b/Docs/buildServerSetup/dynamicRepositories.md new file mode 100644 index 0000000000..4b44d9c842 --- /dev/null +++ b/Docs/buildServerSetup/dynamicRepositories.md @@ -0,0 +1,37 @@ +# Dynamic repositories +GitVersion.exe requires access to the Git repository in order to do / infer all the lovely things that it does. + +Well maybe that's not so much of a revelation.. + +_But did you know_ that in some circumstances, you may find that when your code is built, the build process isn't aware of the Git repository at all - i.e _there is no Git Repository available locally to the build!_ + +For an example of one such circumstance, you can have a read about [Team City's checkout mode: Automatically on Server](https://confluence.jetbrains.com/display/TCD7/VCS+Checkout+Mode) + +So `how is GitVersion meant to work in that scenario?` - well it needs to be able to obtain a copy of the Git repo on the fly and not rely on the build system making one locally available.. + +Enter: **Dynamically Obtained Repo's** + +## Tell GitVersion.exe how to obtain your repository + +Unless you tell GitVersion.exe how to obtain the Git repository, it will assume that the Git repository is already available locally to the process - i.e. it will assume there is already a ".git" folder present, and it will use it. + +To tell GitVersion.exe to obtain the repository on the fly, you need to call `GitVersion.exe` with the following arguments: + +* /url [the url of your git repo] +* /u [authentication username] +* /p [authentication password] +* /b [branch name] +* /c [commit id] + +Please note that these arguments (and their usage) are described [here.](https://github.com/ParticularLabs/GitVersion/wiki/Command-Line-Tool) + +Also, be aware that if you don't specify the `/b` argument (branch name) then GitVersion will currently fallback to targeting whatever the default branch name happens to be for the repo. This could lead to incorrect results, so for that reason it's recommended to always explicitly specify the branch name. + +NB: In Team City, the VCS branch is available from a configuration parameter with the following name: + +`teamcity.build.vcs.branch.` + +Where `` is the `VCS root ID` as described on the Configuring `VCS Roots` page. + +## Where is the repository stored +GitVersion will checkout the dynamic repository into the %tmp% directory and just keep that dynamic repository up to date, this saves recloning the repository every build. diff --git a/Docs/buildServerSetup/teamCity.md b/Docs/buildServerSetup/teamCity.md new file mode 100644 index 0000000000..9c80cdfc16 --- /dev/null +++ b/Docs/buildServerSetup/teamCity.md @@ -0,0 +1,60 @@ +# TeamCity Setup +## Basic Usage +In [TeamCity](https://www.jetbrains.com/teamcity/) you can create a build step as follows: + +* **Runner type:** Command Line +* **Run:** Executable with parameters +* **Command executable:** `GitVersion.exe` +* **Command parameters:** `/output buildserver /updateassemblyinfo true` + +Then in your build parameters simply [add a placeholder](https://github.com/Particular/GitVersion/wiki/Variables#recommended-teamcity-setup) of the GitVersion variables you would like to use. + +GitVersion writes system parameters into TeamCity, so they will automatically be passed to your build scripts to use. + +## Running inside TeamCity +* Make sure to use **agent checkouts** (required, server checkouts do not copy the needed `.git` directory) + - If you want to use *checkout on server*, see [dynamic repositories](dynamicRepositories.md) +* For the moment you need to promote the `%teamcity.build.vcs.branch.{configurationid}%` build parameter to an environment variable with the same name for pull requests to be handled correctly +* We update the TC build number to the GitVersion number automatically +* We output the individual values of the GitVersion version as the build parameter: `GitVersion.*` (Eg: `GitVersion.Major`) if you need access to them in your build script + +### NuGet in TeamCity +* Add dummy [parameter](http://confluence.jetbrains.com/display/TCD8/Configuring+Build+Parameters) to +the project called `GitVersion.NuGetVersion`. If many of your projects uses git-flow and SemVer you +can add the parameter to the "root-project" (TeamCity 8.x+) +* Then setup you nuget pack build set the "version" to `%GitVersion.NuGetVersion%` + +### When TeamCity -> GitHub can't use https +GitVersion requires the presence of master branch in order to determine the version number. If TeamCity uses https to clone git repos then GitVersion will pull down master branch for you during the build. + +If however your TeamCity uses SSH to clone git repos and https is unavailable then GitVersion will error with a message like + +> [GitVersionTask.UpdateAssemblyInfo] Error occurred: GitVersion.MissingBranchException: Could not fetch from 'git@github.dev.xero.com:Xero/Bus.git' since LibGit2 does not support the transport. You have most likely cloned using SSH. If there is a remote branch named 'master' then fetch it manually, otherwise please create a local branch named 'master'. ---> LibGit2Sharp.LibGit2SharpException: An error was raised by libgit2. Category = Net (Error). +This transport isn't implemented. Sorry + +You need to create a TeamCity build step before your compile step which manually creates a local master branch which tracks remote master. Like so (in powershell): + +```Powershell +$branchBeingBuilt = . git symbolic-ref --short -q HEAD +. git pull 2>&1 | write-host +foreach ($remoteBranch in . git branch -r) { + . git checkout $remoteBranch.Trim().Replace("origin/", "") 2>&1 | write-host + . git pull 2>&1 | write-host +} +. git checkout $branchBeingBuilt 2>&1 | write-host +exit 0 +``` + +you should get build output like + +``` +[Step 1/1]: Ensure all branches are available for GitVersion (Powershell) (5s) +[Step 1/1] From file:///C:/BuildAgent2/system/git/git-12345678 +[Step 1/1] * [new branch] master -> origin/master +[Step 1/1] Switched to a new branch 'master' +[Step 1/1] Branch master set up to track remote branch master from origin. +[Step 1/1] Switched to branch 'develop' +``` + +## Guides + - [Continuous Delivery Setup in TeamCity](http://jake.ginnivan.net/blog/2014/07/09/my-typical-teamcity-build-setup) diff --git a/Docs/buildServers.md b/Docs/buildServers.md index d7a85da08e..54ab14be57 100644 --- a/Docs/buildServers.md +++ b/Docs/buildServers.md @@ -13,6 +13,7 @@ When running in MSBuild either from the MSBuild Task or by using the `/proj mypr ## Setup guides - [AppVeyor](buildServerSetup/appVeyor.md) + - [TeamCity](buildServerSetup/teamCity.md) ## Other plugins/helpers ### GitVersion meta runner for TeamCity diff --git a/Docs/faq.md b/Docs/faq.md index f8a254eef1..dae48144fd 100644 --- a/Docs/faq.md +++ b/Docs/faq.md @@ -3,6 +3,14 @@ ## Why is my version not incrementing? GitVersion calculates the semantic version, this will only change once per *release*. Read more at [version increments](./versionIncrements.md) +## How can GitVersion run for a shallow clone or checkout on server working directories +GitVersion needs a proper git repository to run, some build servers do not do a proper clone which can cause issues. GitVersion has a feature called [dynamic repositories](dynamicRepositories.md) which solves this by cloning the repository and working against that clone instead of the working directory. + +## I don't understand what SemVer is all about +Not a problem, we have a quick introduction to SemVer which can be a good primer to read before reading [SemVer.org](http://semver.org) + +Read more at [intro to semver](introToSemVer.md) + ## I can't use the build number for NuGet If you have used NuGet you would notice the versions above are not compatible with NuGet. GitVersion solves this by providing *variables*. diff --git a/Docs/introToSemVer.md b/Docs/introToSemVer.md new file mode 100644 index 0000000000..161bbb2a37 --- /dev/null +++ b/Docs/introToSemVer.md @@ -0,0 +1,27 @@ +# Intro to SemVer +For the official Semantic Version docs head to [semver.org](http://semver.org), this is a quick guide for people getting started and how SemVer is used in GitVersion. + +## Why SemVer? +Quick reason is to solve two problems, Version Lock and Version promiscuity. To explain these things lets imagine the scenario where I am building an app which authenticates with facebook (v1.0.0) and twitter (v1.0.0). Both the facebook and twitter libraries use a json library (v1.0.0). + +Version lock is when we rely on absolute versions, both **FacebookApi** and **TwitterApi** rely on _v1.0.0_ of **JsonLibrary**. **JsonLibrary** _v1.1.0_ comes out and **FacebookApi** decides to upgrade. If our dependency management relies on exact versions we cannot upgrade our application to use **FacebookApi** because **TwitterApi** references _v1.0.0_. The only way we can upgrade is if **TwitterApi** also upgrades to _v1.1.0_ of **JsonLibrary**. + +Version Promiscuity is the opposite problem, **JsonLibrary** releases _v1.1.0_ with some breaking changes then we will just upgrade an **TwitterApi** will break unexpectedly. + +SemVer introduces conventions about breaking changes into our version numbers so we can safely upgrade dependencies without fear of unexpected breaking changes while still allowing us to upgrade downstream libraries to get new features and bug fixes. The convention is quite simple. + +{major}.{minor}.{patch}-{tag}+{buildmetadata} +{major} = Only incremented if the release has breaking changes (includes bug fixes which have breaking behavioural changes +{minor} = Incremented if the release has new non-breaking features +{patch} = Incremented if the release only contains non-breaking bug fixes +{tag} = Optional -{tag} denotes a pre-release of the version preceeding +{buildmetadata} = Options +{buildmetadata} contains additional information about the version, but DOES NOT AFFECT the semantic version preceding it. + +Only one number should be incremented per release, and all lower parts should be reset to 0 (if major is incrememented then minor and patch should become 0). + +For a more complete explaination checkout [semver.org](http://semver.org) which is the official spec. Remember this is a breif introduction and does not cover all parts of semantic versioning, just the important parts to get started. + +## SemVer in GitVersion +GitVersion makes it easy to follow semantic versioning in your library by automatically calculating the next semantic version which your library/application is likely to use. In GitFlow the develop branch will bump the *minor* when master is tagged, while GitHubFlow will bump the *patch*. + +Because one side does not always fit all, GitVersion provides many [Variables](variables.md) for you to use which contain different variations of the version. For example SemVer will be in the format {major}.{minor}.{patch}-{tag}, but FullSemVer will also include build metadata: {major}.{minor}.{patch}-{tag}+{buildmetadata} diff --git a/Docs/usage/commandLine.md b/Docs/usage/commandLine.md index f3c91f28f5..89921e04f5 100644 --- a/Docs/usage/commandLine.md +++ b/Docs/usage/commandLine.md @@ -1,6 +1,13 @@ -# Command Line Usage +# Command Line +If you want a command line version installed on your machine then you can use [Chocolatey](http://chocolatey.org) to install GitVersion + +Available on [Chocolatey](http://chocolatey.org) under [GitVersion.Portable](http://chocolatey.org/packages/GitVersion.Portable) + + > choco install GitVersion.Portable + +Switches are available with `GitVersion /?` ## Output -By default GitVersion returns a json object to stdout. This works great if you want to get your build scripts to parse the json object then use the variables, but there is a simpler way. +By default GitVersion returns a json object to stdout containing all the [variables](variables.md) which GitVersion generates. This works great if you want to get your build scripts to parse the json object then use the variables, but there is a simpler way. -`GitVersion.exe /output buildserver` will change the mode of GitVersion to write out the variables to whatever build server it is running in. You can then use those variables in your build scripts or run different tools to create versioned NuGet packages or whatever you would like to do. +`GitVersion.exe /output buildserver` will change the mode of GitVersion to write out the variables to whatever build server it is running in. You can then use those variables in your build scripts or run different tools to create versioned NuGet packages or whatever you would like to do. See [build servers](buildServers.md) for more information about this. diff --git a/Docs/usage/gem.md b/Docs/usage/gem.md new file mode 100644 index 0000000000..b1ad775e6a --- /dev/null +++ b/Docs/usage/gem.md @@ -0,0 +1,32 @@ +# Ruby Gem usage +**NOTE** This is currenly not being pushed.. Please get in touch if you are using this + +If you want a Ruby gem version installed on your machine then you can use [Bundler](http://bundler.io/) or [Gem](http://rubygems.org/) to install the `gitversion` gem. + + gem install gitversion + +The gem comes with a module to include in your Rakefile: + +```ruby +require 'git_version' + +include GitVersion + +puts git_version.sha +``` + +Internally, this will call the `GitVersion.exe` that is bundled with the Ruby gem, parse its JSON output and make all the JSON keys available through Ruby methods. You can either use Pascal case (`git_version.InformationalVersion`) or Ruby-style snake case (`git_version.informational_version`) to access the JSON properties. + +gitversion internally caches the JSON output, so `GitVersion.exe` is only called once. + +Any arguments passed to `git_version` will be passed to `GitVersion.exe`: + +```ruby +require 'git_version' + +include GitVersion + +puts git_version('C:/read/info/from/another/repository').sha +``` + +**Note:** Mono is not currently supported due to downstream dependencies on libgit2. The Gem can only be used with the .NET framework diff --git a/Docs/usage/msbuildTask.md b/Docs/usage/msbuildTask.md index e69de29bb2..33c39aba1d 100644 --- a/Docs/usage/msbuildTask.md +++ b/Docs/usage/msbuildTask.md @@ -0,0 +1,33 @@ +#MSBuild Task usage +The MSBuild task will wire GitVersion into the MSBuild pipeline of a project and automatically stamp that assembly with the appropriate SemVer information + +Available on [Nuget](https://www.nuget.org) under [GitVersionTask](https://www.nuget.org/packages/GitVersionTask/) + + Install-Package GitVersionTask + +Remove the `Assembly*Version` attributes from your `Properties\AssemblyInfo.cs` file. Sample default: + + [assembly: AssemblyVersion("1.0.0.0")] + [assembly: AssemblyFileVersion("1.0.0.0")] + [assembly: AssemblyInformationalVersion("1.0.0.0")] + +Make sure there is a tag somewhere on master named `v1.2.3` before `HEAD` (change the numbers as desired). Now when you build: + +* AssemblyVersion will be set to 1.2.0.0 (i.e Major.Minor.0.0) +* AssemblyFileVersion will be set to 1.2.3.0 (i.e Major.Minor.Patch) +* AssemblyInformationalVersion will be set to `1.2.4+.Branch..Sha.` where: + * `` is the number of commits between the `v1.2.3` tag and `HEAD`. + * `` is the name of the branch you are on. + * `` is the commit hash of `HEAD`. + +Continue working as usual and when you release/deploy, tag the branch/release `v1.2.4`. + +If you want to bump up the major or minor version, create a text file in the root directory named NextVersion.txt and inside of it on a single line enter the version number that you want your next release to be. e.g., `2.0`. + +## Why is AssemblyVersion only set to Major.Minor? + +This is a common approach that gives you the ability to roll out hot fixes to your assembly without breaking existing applications that may be referencing it. You are still able to get the full version number if you need to by looking at its file version number. + +## My Git repository requires authentication. What do I do? + +Set the environmental variables `GITVERSION_REMOTE_USERNAME` and `GITVERSION_REMOTE_PASSWORD` before the build is initiated. diff --git a/Docs/versionIncrements.md b/Docs/versionIncrements.md index f94a84c673..d65589cb90 100644 --- a/Docs/versionIncrements.md +++ b/Docs/versionIncrements.md @@ -2,7 +2,7 @@ Because GitVersion works with a number of workflows the way it does it's version incrementing may work perfectly for you, or it may cause you issues. This page is split up into two sections, first is all about understanding the approach GitVersion uses by default, and the second is how you can manually increment the version. ## Approach -Semantic Versioning is all about *releases*, not builds. When you release the next version of your library/app/website/whatever you should only increment major/minor or patch then reset all lower parts to 0, for instance given 1.0.0, the next release should be either `2.0.0`, `1.1.0` or `1.0.1`. Bumping one of the version components by more than 1 in a single release means you will have gaps in your version number, which defeats the purpose of SemVer. +Semantic Versioning is all about *releases*, not builds. This means that the version only increases after you release, this directly conflicts with the concept of published CI builds. When you release the next version of your library/app/website/whatever you should only increment major/minor or patch then reset all lower parts to 0, for instance given 1.0.0, the next release should be either `2.0.0`, `1.1.0` or `1.0.1`. Bumping one of the version components by more than 1 in a single release means you will have gaps in your version number, which defeats the purpose of SemVer. Because of this, GitVersion works out what the next SemVer of your app is on each commit. When you are ready to release you simply deploy the latest built version and tag the release it was from. This practice is called **continuous delivery**. GitVersion will increment the *metadata* for each build so you can tell builds apart. For example `1.0.0+5` followed by `1.0.0+6`. It is important to note that build metadata *is not part of the semantic version, it is just metadata!*. diff --git a/Docs/whoIsUsingGitVersion.md b/Docs/whoIsUsingGitVersion.md index e5ccb6e3c8..c112eff50d 100644 --- a/Docs/whoIsUsingGitVersion.md +++ b/Docs/whoIsUsingGitVersion.md @@ -1 +1,13 @@ # Who is using GitVersion +Various people are actively using GitVersion, and taking advantage of the automatic generation of their version numbers. Here is a list of applications that we know about today. + + * [Catel](https://github.com/catel/catel) + * [ChocolateyGUI](https://github.com/chocolatey/ChocolateyGUI) + * [Daidalos.NET](https://github.com/froko/Daidalos.NET) + * [GitLink](github.com/CatenaLogic/GitLink) + * [Orc.* packages](https://github.com/wildgums?query=orc) + * [Orchestra](https://github.com/wildgums/orchestra) + * [Shouldly](https://github.com/shouldly/shouldly) + * [WeavR](https://github.com/WeavR/WeavR) + +If you are using GitVersion in your projects, and you are not listed above, please feel free to add a link to your project.