Skip to content

Commit 24fa6b5

Browse files
committed
Merge pull request #458 from JakeGinnivan/Docs
Docs
2 parents 3cffd4a + ca422f7 commit 24fa6b5

28 files changed

+848
-47
lines changed

Docs/configurationOptions.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Confiuration options

Docs/index.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# GitVersion Docs
2+
GitVersion is a tool to help you achieve Semantic Versioning on your project.
3+
4+
This influences many of the decisions GitVersion has made, please read and understand this page as it will help you start using GitVersion effectively!
5+
6+
## Assumptions/Rules
7+
### You tag releases when you release, not before
8+
GitVersion assumes that tags are used to *tag a release* and not used to build a release.
9+
10+
This means that the version is calculated pre-emptively, if you currently tag, build then release that tag then GitVersion will probably not work for you.
11+
12+
### Tags override other rules
13+
If a commit is tagged, then GitVersion will *always* use that version over any calculated versions. This is so if you rebuild a tag then the same version will be produced.
14+
15+
### The Semantic Version does not increment every commit
16+
This trips a lot of people up, by default GitVersion *does not* increment the SemVer every commit. This means that you will get multiple builds producing the *same version* of your application.
17+
18+
Read more at [version increments](./versionIncrements.md)
19+
20+
### Version sources
21+
There are a number of sources GitVersion can get it's versions from, they include:
22+
23+
- Tags
24+
- Version numbers in branches (i.e `release/2.0.0`)
25+
- Merge messages (for branches with versions in them, i.e `Merged branch 'release/2.0.0' into master`)
26+
- Track version of another branch (i.e develop tracks master, so when master increments so does develop)
27+
- GitVersionConfig.yaml file (i.e `next-version: 2.0.0`)
28+
29+
Read more at [version sources](./versionSources.md)
30+
31+
## Configuration
32+
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.
33+
34+
Read more about the different [configuration options](./configurationOptions.md)
35+
36+
## Output Variables
37+
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.
38+
39+
You can just run `GitVersion.exe` in your repository to see what variables are available (by default a json object is returned).
40+
41+
## Exe or MSBuild Task
42+
There are two 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.
43+
44+
Read more about [using GitVersion](./usage.md)

Docs/usage.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Usage
2+
Info about exe and msbuild task.
3+
4+
### Output options
5+
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.
6+
7+
`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.

Docs/versionIncrements.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Version Incrementing
2+
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.
3+
4+
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`.
5+
6+
This causes problems for people as NuGet and other package managers do not support multiple packages with the same version with only different metadata.
7+
There are a few ways to handle this problem depending on what your requirements are:
8+
9+
## 1. GitFlow
10+
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.
11+
12+
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.
13+
14+
## 2. Octopus deploy
15+
Because Octopus uses NuGet under the covers you cannot publish every build into Octopus deploy. For this we have two possible options:
16+
17+
### 2a. 'Release' packages to Octopus deploy
18+
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.
19+
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.
20+
21+
### 2b. Configure GitVersion to increment per commit
22+
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.

Docs/versionSources.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Version Sources
2+
GitVersion has a two step process for calculating the version number, the first is to calculate the base version which is used to then calculate what the next version should be.
3+
4+
The logic of GitVersion is something like this:
5+
6+
- Is the current commit tagged
7+
- Yes: Use the tag as the version
8+
- No: continue
9+
- Calculate the base version (highest version from all the sources)
10+
- Increment version if needed based on branch config
11+
- Calculate the build metadata (everything after the +) and append to the calcuated version
12+
13+
## Version Sources
14+
### Highest Accessible Tag
15+
GitVersion will find all tags on the current branch and return the highest one.
16+
17+
Will increment: true
18+
19+
### Version in branch name
20+
If the branch has a version in it, then that version will be returned
21+
22+
Will increment: false
23+
24+
### Merge message
25+
If a branch with a version number in it is merged into the current branch, that version number will be used.
26+
27+
Will increment: false
28+
29+
### GitVersionConfig.yaml
30+
If the next-version property is specified in the config file, it will be used as a version source.
31+
32+
Will increment: false
33+
34+
### Others?
35+
Want more ways to increment the version? Open an issue with your idea and submit a pull request!

GitVersionCore.Tests/ConfigProviderTests.cs

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -124,24 +124,6 @@ public void CanReadDefaultDocument()
124124
config.NextVersion.ShouldBe(null);
125125
}
126126

127-
[Test]
128-
public void VerifyInit()
129-
{
130-
var config = typeof(Config);
131-
var aliases = config.GetProperties()
132-
.Where(p => p.GetCustomAttribute<ObsoleteAttribute>() == null)
133-
.Select(p => ((YamlMemberAttribute) p.GetCustomAttribute(typeof(YamlMemberAttribute))).Alias);
134-
var writer = new StringWriter();
135-
136-
ConfigSerialiser.WriteSample(writer);
137-
var initFile = writer.GetStringBuilder().ToString();
138-
139-
foreach (var alias in aliases)
140-
{
141-
initFile.ShouldContain(alias);
142-
}
143-
}
144-
145127
[Test]
146128
public void VerifyAliases()
147129
{

GitVersionCore/Configuration/ConfigSerialiser.cs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,5 @@ public static void Write(Config config, TextWriter writer)
2222
var serializer = new Serializer(SerializationOptions.None, new HyphenatedNamingConvention());
2323
serializer.Serialize(writer, config);
2424
}
25-
26-
public static void WriteSample(TextWriter writer)
27-
{
28-
writer.WriteLine("# assembly-versioning-scheme: MajorMinorPatchTag | MajorMinorPatch | MajorMinor | Major");
29-
writer.WriteLine("# tag-prefix: '[vV|version-] # regex to match git tag prefix");
30-
writer.WriteLine("# next-version: 1.0.0");
31-
writer.WriteLine("# mode: ContinuousDelivery | ContinuousDeployment");
32-
writer.WriteLine("# continuous-delivery-fallback-tag: ci");
33-
writer.WriteLine("#branches:");
34-
writer.WriteLine("# release[/-]:\n mode: ContinuousDelivery | ContinuousDeployment\n tag: rc");
35-
writer.WriteLine("# develop:\n# mode: ContinuousDelivery | ContinuousDeployment\n# tag: alpha");
36-
}
3725
}
3826
}

GitVersionCore/Configuration/ConfigurationProvider.cs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,27 +33,24 @@ public static string GetEffectiveConfigAsString(string gitDirectory, IFileSystem
3333
return stringBuilder.ToString();
3434
}
3535

36-
public static void WriteSample(string workingDirectory, IFileSystem fileSystem)
36+
static string GetConfigFilePath(string workingDirectory)
37+
{
38+
return Path.Combine(workingDirectory, "GitVersionConfig.yaml");
39+
}
40+
41+
public static void Init(string workingDirectory, IFileSystem fileSystem)
3742
{
3843
var configFilePath = GetConfigFilePath(workingDirectory);
44+
var config = new ConfigInitWizard().Run(Provide(workingDirectory, fileSystem));
45+
if (config == null) return;
3946

40-
if (!fileSystem.Exists(configFilePath))
41-
{
42-
using (var stream = fileSystem.OpenWrite(configFilePath))
43-
using (var writer = new StreamWriter(stream))
44-
{
45-
ConfigSerialiser.WriteSample(writer);
46-
}
47-
}
48-
else
47+
using (var stream = fileSystem.OpenWrite(configFilePath))
48+
using (var writer = new StreamWriter(stream))
4949
{
50-
Logger.WriteError("Cannot write sample, GitVersionConfig.yaml already exists");
50+
Logger.WriteInfo("Saving config file");
51+
ConfigSerialiser.Write(config, writer);
52+
stream.Flush();
5153
}
5254
}
53-
54-
static string GetConfigFilePath(string workingDirectory)
55-
{
56-
return Path.Combine(workingDirectory, "GitVersionConfig.yaml");
57-
}
5855
}
5956
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
namespace GitVersion
2+
{
3+
using System.Collections.Generic;
4+
5+
public class AssemblyVersioningSchemeSetting : ConfigInitWizardStep
6+
{
7+
protected override StepResult HandleResult(string result, Queue<ConfigInitWizardStep> steps, Config config)
8+
{
9+
switch (result)
10+
{
11+
case "0":
12+
steps.Enqueue(new EditConfigStep());
13+
return StepResult.Ok();
14+
case "1":
15+
config.AssemblyVersioningScheme = AssemblyVersioningScheme.Major;
16+
steps.Enqueue(new EditConfigStep());
17+
return StepResult.Ok();
18+
case "2":
19+
config.AssemblyVersioningScheme = AssemblyVersioningScheme.MajorMinor;
20+
steps.Enqueue(new EditConfigStep());
21+
return StepResult.Ok();
22+
case "3":
23+
config.AssemblyVersioningScheme = AssemblyVersioningScheme.MajorMinorPatch;
24+
steps.Enqueue(new EditConfigStep());
25+
return StepResult.Ok();
26+
case "4":
27+
config.AssemblyVersioningScheme = AssemblyVersioningScheme.MajorMinorPatchTag;
28+
steps.Enqueue(new EditConfigStep());
29+
return StepResult.Ok();
30+
}
31+
32+
return StepResult.InvalidResponseSelected();
33+
}
34+
35+
protected override string GetPrompt(Config config)
36+
{
37+
return @"What assembly versioning scheme do you want to use:
38+
39+
0) Back
40+
1) Major.0.0.0
41+
2) Major.Minor.0.0
42+
3) Major.Minor.Patch.0 (default)
43+
4) Major.Minor.Patch.TagCount (Allows different pre-release tags to cause assembly version to change)";
44+
}
45+
46+
protected override string DefaultResult
47+
{
48+
get { return "0"; }
49+
}
50+
}
51+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
namespace GitVersion
2+
{
3+
using System;
4+
using System.Collections.Generic;
5+
6+
public class ConfigInitWizard
7+
{
8+
public Config Run(Config config)
9+
{
10+
Console.WriteLine("GitVersion init will guide you through setting GitVersion up to work for you");
11+
var steps = new Queue<ConfigInitWizardStep>();
12+
steps.Enqueue(new SimpleOrTutorialStep());
13+
14+
while (steps.Count > 0)
15+
{
16+
var currentStep = steps.Dequeue();
17+
if (!currentStep.Apply(steps, config))
18+
{
19+
return null;
20+
}
21+
}
22+
23+
return config;
24+
}
25+
}
26+
}

0 commit comments

Comments
 (0)