Implements SimpleGitVersion.Abstractions thanks to the excellent LibGit2Sharp.
The CommitInfo is the main object of this library. The hard work is done by the TagCollector.
Simplest usage (other overloads exist):
// path can be in any folder. The first parent with a /.git folder is found.
var info = CommitInfo.LoadFromPath( path );Configurations can be done thanks to the optional RepositoryInfo.xml file that may appear at the root level in the repository.
This file can contain a <SimpleGitVersion>...</SimpleGitVersion> element that define options like CI builds or StartingVersion that drives the behavior of SimpleGitVersion.Core.
This defines the first version that should be considered in the repository:
<RepositoryInfo>
<SimpleGitVersion StartingVersion="v0.6.0-rc">
</SimpleGitVersion>
</RepositoryInfo>When this version is specified, any existing commit tag with a version lower than it are ignored. This is typically used to start using CSemVer on a repository that did not use it before and therefore has incoherent or invalid tags.
Another common use is when for any reason one need to boost the actual version: jumping from any current version (like 1.0.0) to a target that violates the SemVer rule of consecutive versions (like 10.0.0).
The last usage it to restart a branch from an old commit point for which new versions must be produced, typically patches or minor versions. For this scenario, set StartingVersion to any non released version: this version and its direct successors will be allowed (excluding any version greater than or equal to the lowest existing version if any).
This configures the build configuration to use between "Debug" and "Release". By default, it is the ReleaseCandidate quality: only release candidates or stable versions will use "Release".
<RepositoryInfo>
<!-- Always uses "Debug" -->
<SimpleGitVersion UseReleaseBuildConfigurationFrom="None" />
</RepositoryInfo>When specified, it must be:
CI: always use "Release" build configuration.Exploratory: always use "Release" except for CI builds.Preview: use "Debug" for CI and Exploratory qualities, "Release" otherwise.ReleaseCandidateorrc: this is the default.Stable: only stable versions will use "Release", all prerelease versions will use "Debug".None: always use "Debug" build configuration.
This attribute can also be set at a branch level and overrides the top-level one:
<RepositoryInfo>
<!-- Always uses "Release" except on "fx/new-way" where only release candidates
or stable versions will use "Release". -->
<SimpleGitVersion UseReleaseBuildConfigurationFrom="CI">
<Branches>
<Branch Name="develop" CIVersionMode="LastReleaseBased" />
<Branch Name="fx/new-way" VersionName="explore" CIVersionMode="ZeroTimed" UseReleaseBuildConfigurationFrom="ReleaseCandidate" />
</Branches>
</SimpleGitVersion>
</RepositoryInfo>If for any reason "Debug" vs. "Release" is not enough, a simple extension point can be used to compute any esoteric build
configuration string. The build configuration is computed by the static CommitInfo.BuildConfigurationSelector function
that can be replaced. See CommitInfo.FinalBuildInfo.cs.
The RepositoryInfo.xml file can define two attributes:
SingleMajor: Setting this major number will only allow versions with this exact number as their Major.
<RepositoryInfo>
<SimpleGitVersion SingleMajor="4" />
</RepositoryInfo>OnlyPatch: Defaults to false. Sets it to true to allow only patches version (any version that bumps the Major or the Minor part will be forbidden).
<RepositoryInfo>
<SimpleGitVersion OnlyPatch="true" />
</RepositoryInfo>This SingleMajor and OnlyPatch are enough to fully drive the behavior of SimpleGitVersion
regarding "Long Term Support" application life cycle.
Specifying which branches should generate CI-Builds assemblies and/or packages is easy:
<RepositoryInfo>
<SimpleGitVersion>
<Branches>
<Branch Name="develop" CIVersionMode="LastReleaseBased" />
<Branch Name="fx/new-way" VersionName="explore" CIVersionMode="ZeroTimed" />
</Branches>
</SimpleGitVersion>
</RepositoryInfo>The VersionName and CIVersionMode are optional.
- When specified
VersionNameoverrides the branchNameas the CI-Build identifier. To be able to generate CI-Build versions that fit into NuGet V2 package name (CSemVer short form), theVersionName(or the branchName) must not exceed 8 characters. CIVersionModecan be:None: This suppress any CI builds as if the<Branch>element was not specified.LastReleaseBased: This is the default. Semantic versions computed in this mode are greater than the base release but lower than any subsequent release.ZeroTimed: The computed semantic version is a 0.0.0 version with a suffix that makes it lower than any actual package (ie. lower than v0.0.0-alpha that is the very first possible CSemVer version).
Why does CSemVer define ZeroBased for CI-Builds and SimpleGitVersion uses ZeroTimed term?
The CSemVer's ZeroBased simply specifies that the 0.0.0 version must be used as the base version with a -XXX prerelease but does not state what the -XXX is. SimpleGitVersion uses the date and time of the commit.
To support the short form, we must respect the 20 characters limit, SimpleGitVersion uses the number of seconds between the commit's time and the 1st of january 2015, and this number of seconds is expressed in base 36 padded on 7 chars: 1000 years fit into 7 chars.
We also use -- trick and append the branch name (that must not exceed 8 characters):
0.0.0--00yI6aT-develop
The code is here.
<RepositoryInfo>
<SimpleGitVersion>
<IgnoreModifiedFiles>
<Add>SharedKey.snk</Add>
<Add>Common/Doc/ReleaseNotes.txt</Add>
</IgnoreModifiedFiles>
</SimpleGitVersion>
</RepositoryInfo>This can be used if for any reason some files should (or can safely) be ignored in terms of local changes: uncommitted changes for these files will be ignored.
This is a dangerous option since it ignores all the locally modified files.
<RepositoryInfo>
<SimpleGitVersion>
<Debug IgnoreDirtyWorkingFolder="true"/>
</SimpleGitVersion>
</RepositoryInfo>When set to true, existing version tags will be checked.
Existing versions are filtered by SingleMajor if it is defined and the following checks are made:
- If there is a
StartingVersionthe first existing version must be this starting one. - If there is no
StartingVersionthe first version must be one of the CSemVer's FirstPossibleVersions. - Existing version tags must always be compact (no "holes" must exist between them).
These are really strong constraints and that's why this option defaults to false.
<RepositoryInfo>
<SimpleGitVersion CheckExistingVersions="true" />
</RepositoryInfo>Defaults to "origin" (can never be null or empty) and should rarely be set: it is the name of the remote repository that will be considered when working with branches.
<RepositoryInfo>
<SimpleGitVersion RemoteName="dev-lead" />
</RepositoryInfo>