Skip to content

Commit d6289ba

Browse files
committed
Merge pull request #755 from JakeGinnivan/PreventFetchForVso
Prevent fetch for Vso and Jenkins
2 parents 6af005e + 64a64ca commit d6289ba

File tree

10 files changed

+109
-64
lines changed

10 files changed

+109
-64
lines changed

docs/build-server-support/build-server/teamcity.md

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,28 @@ TeamCity has support for meta-runners which allow custom tasks. There is a GitVe
1717
- [Project Link](https://github.com/JetBrains/meta-runner-power-pack/tree/master/gitversion)
1818

1919
## Running inside TeamCity
20-
* Make sure to use **agent checkouts** (required, server checkouts do not copy the needed `.git` directory)
21-
- If you want to use *checkout on server*, see [dynamic repositories](../../more-info/dynamic-repositories.md)
22-
* 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
20+
When running in TeamCIty you have two options, run using **agent checkout** or use dynamic repositories.
21+
22+
### Agent checkout
23+
For GitVersion to pick up pull requests properly you need to promote the `%teamcity.build.vcs.branch.{configurationid}%` variable to a system variable called `Git_Branch`
24+
25+
Just go to your build configuration, Parameters, click Add, Name should be `system.Git_Branch`, value should be `%teamcity.build.vcs.branch.{vcsid}%` where vcsid is your VCS root id. You should get auto completion for this.
26+
27+
### Dynamic repositories
28+
To use server side checkout, you must use the dynamic repositories feature of GitVersion. Server side checkout sends just the files to the agent and not the actual .git folder. Dynamic repositories will clone your repo into a temp folder and use it to calculate version information.
29+
30+
See [dynamic repositories](../../more-info/dynamic-repositories.md) for more info.
31+
32+
### Output
2333
* We update the TC build number to the GitVersion number automatically
24-
* 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
34+
* We output the individual values of the GitVersion version variables as build parameters with format `GitVersion.*` (Eg: `GitVersion.Major`) if you need access to them in your build script. Being system variables they will be passed as msbuild/environmental variables to other build steps
2535

2636
### NuGet in TeamCity
2737
* Add dummy [parameter](http://confluence.jetbrains.com/display/TCD8/Configuring+Build+Parameters) to
2838
the project called `GitVersion.NuGetVersion`. If many of your projects uses git-flow and SemVer you
29-
can add the parameter to the "root-project" (TeamCity 8.x+)
39+
can add the parameter to the "root-project" (TeamCity 8.x+). You need a dummy param because GitVersion creates the variables at runtime, and you cannot reference a paramter which is not available statically. GitVersion will overwrite the dummy value
3040
* Then setup you nuget pack build set the "version" to `%GitVersion.NuGetVersion%`
41+
* If you do your pack in a build script then you can just use environmental variables because teamcity will pass them through automatically.
3142

3243
### When TeamCity -> GitHub can't use https
3344
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.
@@ -37,29 +48,5 @@ If however your TeamCity uses SSH to clone git repos and https is unavailable th
3748
> [GitVersionTask.UpdateAssemblyInfo] Error occurred: GitVersion.MissingBranchException: Could not fetch from '[email protected]: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).
3849
This transport isn't implemented. Sorry
3950

40-
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):
41-
42-
```Powershell
43-
$branchBeingBuilt = . git symbolic-ref --short -q HEAD
44-
. git pull 2>&1 | write-host
45-
foreach ($remoteBranch in . git branch -r) {
46-
. git checkout $remoteBranch.Trim().Replace("origin/", "") 2>&1 | write-host
47-
. git pull 2>&1 | write-host
48-
}
49-
. git checkout $branchBeingBuilt 2>&1 | write-host
50-
exit 0
51-
```
52-
53-
you should get build output like
54-
55-
```
56-
[Step 1/1]: Ensure all branches are available for GitVersion (Powershell) (5s)
57-
[Step 1/1] From file:///C:/BuildAgent2/system/git/git-12345678
58-
[Step 1/1] * [new branch] master -> origin/master
59-
[Step 1/1] Switched to a new branch 'master'
60-
[Step 1/1] Branch master set up to track remote branch master from origin.
61-
[Step 1/1] Switched to branch 'develop'
62-
```
63-
6451
## Guides
6552
- [Continuous Delivery Setup in TeamCity](http://jake.ginnivan.net/blog/2014/07/09/my-typical-teamcity-build-setup)

src/GitVersionCore.Tests/BuildServers/VsoAgentTests.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@
77
[TestFixture]
88
public class VsoAgentTests
99
{
10-
1110
string key = "BUILD_BUILDNUMBER";
1211

13-
1412
[SetUp]
1513
public void SetEnvironmentVariableForTest()
1614
{

src/GitVersionCore/BuildServers/BuildServerBase.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,16 @@ public abstract class BuildServerBase : IBuildServer
88
public abstract string GenerateSetVersionMessage(VersionVariables variables);
99
public abstract string[] GenerateSetParameterMessage(string name, string value);
1010

11-
public virtual string GetCurrentBranch()
11+
public virtual string GetCurrentBranch(bool usingDynamicRepos)
1212
{
1313
return null;
1414
}
1515

16+
public virtual bool PreventFetch()
17+
{
18+
return false;
19+
}
20+
1621
public virtual void WriteIntegration(Action<string> writer, VersionVariables variables)
1722
{
1823
if (writer == null)

src/GitVersionCore/BuildServers/IBuildServer.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@ public interface IBuildServer
77
bool CanApplyToCurrentContext();
88
string GenerateSetVersionMessage(VersionVariables variables);
99
string[] GenerateSetParameterMessage(string name, string value);
10-
1110
void WriteIntegration(Action<string> writer, VersionVariables variables);
12-
string GetCurrentBranch();
11+
string GetCurrentBranch(bool usingDynamicRepos);
12+
/// <summary>
13+
/// If the build server should not try and fetch
14+
/// </summary>
15+
bool PreventFetch();
1316
}
1417
}

src/GitVersionCore/BuildServers/Jenkins.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ public override string[] GenerateSetParameterMessage(string name, string value)
3434
};
3535
}
3636

37+
public override string GetCurrentBranch(bool usingDynamicRepos)
38+
{
39+
return Environment.GetEnvironmentVariable("GIT_BRANCH");
40+
}
41+
42+
public override bool PreventFetch()
43+
{
44+
return true;
45+
}
46+
3747
public override void WriteIntegration(Action<string> writer, VersionVariables variables)
3848
{
3949
base.WriteIntegration(writer, variables);

src/GitVersionCore/BuildServers/TeamCity.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,39 @@ public override bool CanApplyToCurrentContext()
99
return !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("TEAMCITY_VERSION"));
1010
}
1111

12+
public override string GetCurrentBranch(bool usingDynamicRepos)
13+
{
14+
var branchName = Environment.GetEnvironmentVariable("Git_Branch");
15+
16+
if (string.IsNullOrEmpty(branchName))
17+
{
18+
if (!usingDynamicRepos)
19+
{
20+
WriteBranchEnvVariableWarning();
21+
}
22+
23+
return base.GetCurrentBranch(usingDynamicRepos);
24+
}
25+
26+
return branchName;
27+
}
28+
29+
static void WriteBranchEnvVariableWarning()
30+
{
31+
Logger.WriteWarning(@"TeamCity doesn't make the current branch available through environmental variables.
32+
33+
Depending on your authentication and transport setup of your git VCS root things may work. In that case, ignore this warning.
34+
35+
In your TeamCity build configuration, add a parameter called `system.Git_Branch` with value %teamcity.build.vcs.branch.<vcsid>%
36+
37+
See http://gitversion.readthedocs.org/en/latest/build-server-support/build-server/teamcity for more info");
38+
}
39+
40+
public override bool PreventFetch()
41+
{
42+
return !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("Git_Branch"));
43+
}
44+
1245
public override string[] GenerateSetParameterMessage(string name, string value)
1346
{
1447
return new[]

src/GitVersionCore/BuildServers/VsoAgent.cs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
public class VsoAgent : BuildServerBase
88
{
99
public override bool CanApplyToCurrentContext()
10-
{
11-
return !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("TF_BUILD"));
10+
{
11+
return !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("TF_BUILD"));
1212
}
1313

1414
public override string[] GenerateSetParameterMessage(string name, string value)
@@ -19,22 +19,32 @@ public override string[] GenerateSetParameterMessage(string name, string value)
1919
};
2020
}
2121

22-
public override string GetCurrentBranch()
22+
public override string GetCurrentBranch(bool usingDynamicRepos)
2323
{
2424
return Environment.GetEnvironmentVariable("BUILD_SOURCEBRANCH");
2525
}
2626

27+
public override bool PreventFetch()
28+
{
29+
return true;
30+
}
31+
2732
public override string GenerateSetVersionMessage(VersionVariables variables)
2833
{
2934
// For VSO, we'll get the Build Number and insert GitVersion variables where
3035
// specified
31-
3236
var buildNum = Environment.GetEnvironmentVariable("BUILD_BUILDNUMBER");
3337

34-
buildNum = variables.Aggregate(buildNum, (current, kvp) =>
38+
var newBuildNum = variables.Aggregate(buildNum, (current, kvp) =>
3539
current.RegexReplace(string.Format(@"\$\(GITVERSION_{0}\)", kvp.Key), kvp.Value ?? string.Empty, RegexOptions.IgnoreCase));
3640

37-
return string.Format("##vso[build.updatebuildnumber]{0}", buildNum);
41+
// If no variable substitution has happened, use FullSemVer
42+
if (buildNum == newBuildNum)
43+
{
44+
return string.Format("##vso[build.updatebuildnumber]{0}", variables.FullSemVer);
45+
}
46+
47+
return string.Format("##vso[build.updatebuildnumber]{0}", newBuildNum);
3848
}
3949
}
4050
}

src/GitVersionCore/ExecuteCore.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ public ExecuteCore(IFileSystem fileSystem)
2222
public VersionVariables ExecuteGitVersion(string targetUrl, string dynamicRepositoryLocation, Authentication authentication, string targetBranch, bool noFetch, string workingDirectory, string commitId)
2323
{
2424
// Normalise if we are running on build server
25-
var gitPreparer = new GitPreparer(targetUrl, dynamicRepositoryLocation, authentication, noFetch, workingDirectory);
25+
var applicableBuildServers = BuildServerList.GetApplicableBuildServers();
26+
var buildServer = applicableBuildServers.FirstOrDefault();
27+
var fetch = noFetch || (buildServer != null && buildServer.PreventFetch());
28+
var gitPreparer = new GitPreparer(targetUrl, dynamicRepositoryLocation, authentication, fetch, workingDirectory);
2629
var dotGitDirectory = gitPreparer.GetDotGitDirectory();
2730
var projectRoot = gitPreparer.GetProjectRootDirectory();
2831
Logger.WriteInfo(string.Format("Project root is: " + projectRoot));
@@ -37,7 +40,7 @@ public VersionVariables ExecuteGitVersion(string targetUrl, string dynamicReposi
3740
var versionVariables = gitVersionCache.LoadVersionVariablesFromDiskCache(repo, dotGitDirectory);
3841
if (versionVariables == null)
3942
{
40-
versionVariables = ExecuteInternal(targetBranch, commitId, repo, gitPreparer, projectRoot);
43+
versionVariables = ExecuteInternal(targetBranch, commitId, repo, gitPreparer, projectRoot, buildServer);
4144
gitVersionCache.WriteVariablesToDiskCache(repo, dotGitDirectory, versionVariables);
4245
}
4346

@@ -60,25 +63,22 @@ public bool TryGetVersion(string directory, out VersionVariables versionVariable
6063
}
6164
}
6265

63-
static string ResolveCurrentBranch(IBuildServer buildServer, string targetBranch)
66+
static string ResolveCurrentBranch(IBuildServer buildServer, string targetBranch, bool isDynamicRepository)
6467
{
6568
if (buildServer == null)
6669
{
6770
return targetBranch;
6871
}
6972

70-
var currentBranch = buildServer.GetCurrentBranch() ?? targetBranch;
73+
var currentBranch = buildServer.GetCurrentBranch(isDynamicRepository) ?? targetBranch;
7174
Logger.WriteInfo("Branch from build environment: " + currentBranch);
7275

7376
return currentBranch;
7477
}
7578

76-
VersionVariables ExecuteInternal(string targetBranch, string commitId, IRepository repo, GitPreparer gitPreparer, string projectRoot)
79+
VersionVariables ExecuteInternal(string targetBranch, string commitId, IRepository repo, GitPreparer gitPreparer, string projectRoot, IBuildServer buildServer)
7780
{
78-
var applicableBuildServers = BuildServerList.GetApplicableBuildServers();
79-
var buildServer = applicableBuildServers.FirstOrDefault();
80-
81-
gitPreparer.Initialise(buildServer != null, ResolveCurrentBranch(buildServer, targetBranch));
81+
gitPreparer.Initialise(buildServer != null, ResolveCurrentBranch(buildServer, targetBranch, gitPreparer.IsDynamicGitRepository));
8282

8383
var versionFinder = new GitVersionFinder();
8484
var configuration = ConfigurationProvider.Provide(projectRoot, fileSystem);

src/GitVersionExe/ArgumentParser.cs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ namespace GitVersion
66
using System.Linq;
77
using System.Text.RegularExpressions;
88

9-
109
public class ArgumentParser
1110
{
1211
public static Arguments ParseArguments(string commandLineArguments)
@@ -61,23 +60,23 @@ public static Arguments ParseArguments(List<string> commandLineArguments)
6160
arguments.TargetPath = firstArgument;
6261
namedArguments = commandLineArguments.Skip(1).ToList();
6362
}
64-
63+
6564
var args = CollectSwitchesAndValuesFromArguments(namedArguments);
6665

6766
foreach (var name in args.AllKeys)
6867
{
6968
var values = args.GetValues(name);
70-
69+
7170
string value = null;
72-
71+
7372
if (values != null)
7473
{
7574
//Currently, no arguments use more than one value, so having multiple values is an input error.
7675
//In the future, this exception can be removed to support multiple values for a switch.
7776
if (values.Length > 1) throw new WarningException(string.Format("Could not parse command line parameter '{0}'.", values[1]));
78-
77+
7978
value = values.FirstOrDefault();
80-
}
79+
}
8180

8281
if (IsSwitch("l", name))
8382
{
@@ -168,7 +167,7 @@ public static Arguments ParseArguments(List<string> commandLineArguments)
168167
}
169168
else
170169
{
171-
arguments.UpdateAssemblyInfo = true;
170+
arguments.UpdateAssemblyInfo = true;
172171
}
173172
continue;
174173
}
@@ -186,11 +185,11 @@ public static Arguments ParseArguments(List<string> commandLineArguments)
186185
{
187186
versionVariable = VersionVariables.AvailableVariables.SingleOrDefault(av => av.Equals(value.Replace("'", ""), StringComparison.CurrentCultureIgnoreCase));
188187
}
189-
188+
190189
if (versionVariable == null)
191190
{
192191
var messageFormat = "{0} requires a valid version variable. Available variables are:\n{1}";
193-
var message = string.Format(messageFormat, name, String.Join(", ", VersionVariables.AvailableVariables.Select(x=>string.Concat("'", x, "'"))));
192+
var message = string.Format(messageFormat, name, String.Join(", ", VersionVariables.AvailableVariables.Select(x => string.Concat("'", x, "'"))));
194193
throw new WarningException(message);
195194
}
196195

@@ -210,7 +209,7 @@ public static Arguments ParseArguments(List<string> commandLineArguments)
210209
}
211210
else
212211
{
213-
arguments.ShowConfig = true;
212+
arguments.ShowConfig = true;
214213
}
215214
continue;
216215
}
@@ -253,15 +252,15 @@ static NameValueCollection CollectSwitchesAndValuesFromArguments(List<string> na
253252
currentKey = arg;
254253
args.Add(currentKey, null);
255254
}
256-
//If this is a value (not a switch)
255+
//If this is a value (not a switch)
257256
else
258257
{
259258
//And if the current switch does not have a value yet, set it's value to this argument.
260-
if (String.IsNullOrEmpty(args[currentKey]))
259+
if (string.IsNullOrEmpty(args[currentKey]))
261260
{
262261
args[currentKey] = arg;
263262
}
264-
//Otherwise add the value under the same switch.
263+
//Otherwise add the value under the same switch.
265264
else
266265
{
267266
args.Add(currentKey, arg);
@@ -273,7 +272,7 @@ static NameValueCollection CollectSwitchesAndValuesFromArguments(List<string> na
273272

274273
static bool IsSwitchArgument(string value)
275274
{
276-
return value != null && (value.StartsWith("-") || value.StartsWith("/"))
275+
return value != null && (value.StartsWith("-") || value.StartsWith("/"))
277276
&& !Regex.Match(value, @"/\w+:").Success; //Exclude msbuild & project parameters in form /blah:, which should be parsed as values, not switch names.
278277
}
279278

src/GitVersionExe/Arguments.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,6 @@ public Arguments()
3434
public string UpdateAssemblyInfoFileName;
3535

3636
public bool ShowConfig;
37-
public bool NoFetch { get; set; }
37+
public bool NoFetch;
3838
}
3939
}

0 commit comments

Comments
 (0)