Skip to content

Jenkins Pipeline compatibility #1201

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public class EnvironmentVariableJenkinsTests
string key = "JENKINS_URL";
string branch = "GIT_BRANCH";
string localBranch = "GIT_LOCAL_BRANCH";
string pipelineBranch = "BRANCH_NAME";

private void SetEnvironmentVariableForDetection()
{
Expand Down Expand Up @@ -60,4 +61,28 @@ public void JenkinsTakesLocalBranchNameNotRemoteName()
Environment.SetEnvironmentVariable(branch, branchOrig);
Environment.SetEnvironmentVariable(localBranch, localBranchOrig);
}

[Test]
public void JenkinsTakesBranchNameInPipelineAsCode()
{
// Save original values so they can be restored
string branchOrig = Environment.GetEnvironmentVariable(branch);
string localBranchOrig = Environment.GetEnvironmentVariable(localBranch);
string pipelineBranchOrig = Environment.GetEnvironmentVariable(pipelineBranch);

// Set BRANCH_NAME in pipeline mode
Environment.SetEnvironmentVariable(pipelineBranch, "master");
// When Jenkins uses a Pipeline, GIT_BRANCH and GIT_LOCAL_BRANCH are not set:
Environment.SetEnvironmentVariable(branch, null);
Environment.SetEnvironmentVariable(localBranch, null);

// Test Jenkins GetCurrentBranch method now returns BRANCH_NAME
var j = new Jenkins();
j.GetCurrentBranch(true).ShouldBe("master");

// Restore environment variables
Environment.SetEnvironmentVariable(branch, branchOrig);
Environment.SetEnvironmentVariable(localBranch, localBranchOrig);
Environment.SetEnvironmentVariable(pipelineBranch, pipelineBranchOrig);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ branches:
tag: PullRequest
increment: Inherit
prevent-increment-of-merged-branch-version: false
tag-number-pattern: '[/-](?<number>\d+)[-/]'
tag-number-pattern: '[/-](?<number>\d+)'
track-merge-target: false
regex: (pull|pull\-requests|pr)[/-]
tracks-release-branches: false
Expand Down
5 changes: 5 additions & 0 deletions src/GitVersionCore/BuildServers/BuildServerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,10 @@ public virtual void WriteIntegration(Action<string> writer, VersionVariables var
writer(buildParameter);
}
}

public virtual bool ShouldCleanUpRemotes()
{
return false;
}
}
}
1 change: 1 addition & 0 deletions src/GitVersionCore/BuildServers/IBuildServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ public interface IBuildServer
/// If the build server should not try and fetch
/// </summary>
bool PreventFetch();
bool ShouldCleanUpRemotes();
}
}
19 changes: 18 additions & 1 deletion src/GitVersionCore/BuildServers/Jenkins.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,31 @@ public override string[] GenerateSetParameterMessage(string name, string value)

public override string GetCurrentBranch(bool usingDynamicRepos)
{
return Environment.GetEnvironmentVariable("GIT_LOCAL_BRANCH") ?? Environment.GetEnvironmentVariable("GIT_BRANCH");
return IsPipelineAsCode()
? Environment.GetEnvironmentVariable("BRANCH_NAME")
: (Environment.GetEnvironmentVariable("GIT_LOCAL_BRANCH") ?? Environment.GetEnvironmentVariable("GIT_BRANCH"));
}

private bool IsPipelineAsCode()
{
return !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("BRANCH_NAME"));
}

public override bool PreventFetch()
{
return true;
}

/// <summary>
/// When Jenkins uses pipeline-as-code, it creates two remotes: "origin" and "origin1".
/// This should be cleaned up, so that normizaling the Git repo will not fail.
/// </summary>
/// <returns></returns>
public override bool ShouldCleanUpRemotes()
{
return IsPipelineAsCode();
}

public override void WriteIntegration(Action<string> writer, VersionVariables variables)
{
base.WriteIntegration(writer, variables);
Expand Down
2 changes: 1 addition & 1 deletion src/GitVersionCore/Configuration/ConfigurationProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public static void ApplyDefaultsTo(Config config)
GetOrCreateBranchDefaults(config, PullRequestBranchKey),
PullRequestRegex,
defaultTag: "PullRequest",
defaultTagNumberPattern: @"[/-](?<number>\d+)[-/]",
defaultTagNumberPattern: @"[/-](?<number>\d+)",
defaultIncrementStrategy: IncrementStrategy.Inherit);
ApplyBranchDefaults(config,
GetOrCreateBranchDefaults(config, HotfixBranchKey),
Expand Down
3 changes: 2 additions & 1 deletion src/GitVersionCore/ExecuteCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ public VersionVariables ExecuteGitVersion(string targetUrl, string dynamicReposi
var applicableBuildServers = BuildServerList.GetApplicableBuildServers();
var buildServer = applicableBuildServers.FirstOrDefault();
var fetch = noFetch || (buildServer != null && buildServer.PreventFetch());
var shouldCleanUpRemotes = buildServer != null && buildServer.ShouldCleanUpRemotes();
var gitPreparer = new GitPreparer(targetUrl, dynamicRepositoryLocation, authentication, fetch, workingDirectory);
gitPreparer.Initialise(buildServer != null, ResolveCurrentBranch(buildServer, targetBranch, !string.IsNullOrWhiteSpace(dynamicRepositoryLocation)));
gitPreparer.Initialise(buildServer != null, ResolveCurrentBranch(buildServer, targetBranch, !string.IsNullOrWhiteSpace(dynamicRepositoryLocation)), shouldCleanUpRemotes);
var dotGitDirectory = gitPreparer.GetDotGitDirectory();
var projectRoot = gitPreparer.GetProjectRootDirectory();

Expand Down
15 changes: 14 additions & 1 deletion src/GitVersionCore/GitPreparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,18 @@ public bool IsDynamicGitRepository

public string DynamicGitRepositoryPath { get; private set; }

public void Initialise(bool normaliseGitDirectory, string currentBranch)
public void Initialise(bool normaliseGitDirectory, string currentBranch, bool shouldCleanUpRemotes = false)
{
if (string.IsNullOrWhiteSpace(targetUrl))
{
if (normaliseGitDirectory)
{
using (Logger.IndentLog(string.Format("Normalizing git directory for branch '{0}'", currentBranch)))
{
if (shouldCleanUpRemotes)
{
CleanupDuplicateOrigin();
}
GitRepositoryHelper.NormalizeGitDirectory(GetDotGitDirectory(), authentication, noFetch, currentBranch);
}
}
Expand All @@ -70,6 +74,15 @@ public void Initialise(bool normaliseGitDirectory, string currentBranch)
DynamicGitRepositoryPath = CreateDynamicRepository(tempRepositoryPath, authentication, targetUrl, currentBranch, noFetch);
}

private void CleanupDuplicateOrigin()
{
var repo = new Repository(GetDotGitDirectory());
if (repo.Network.Remotes.Any(remote => remote.Name == "origin1"))
{
repo.Network.Remotes.Remove("origin1");
}
}

public TResult WithRepository<TResult>(Func<IRepository, TResult> action)
{
using (IRepository repo = new Repository(GetDotGitDirectory()))
Expand Down
1 change: 1 addition & 0 deletions src/GitVersionExe.Tests/GitVersionExe.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
<Compile Include="HelpWriterTests.cs" />
<Compile Include="JsonOutputOnBuildServer.cs" />
<Compile Include="MsBuildProjectArgTest.cs" />
<Compile Include="PullRequestInJenkinsPipelineTest.cs" />
<Compile Include="PullRequestInTeamCityTest.cs" />
<Compile Include="AssemblyInfoFileUpdateTests.cs" />
<Compile Include="VersionWriterTests.cs" />
Expand Down
60 changes: 60 additions & 0 deletions src/GitVersionExe.Tests/PullRequestInJenkinsPipelineTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
using System;
using GitTools.Testing;
using LibGit2Sharp;
using NUnit.Framework;
using Shouldly;

[TestFixture]
public class PullRequestInJenkinsTest
{
[TestCase]
public void GivenJenkinsPipelineHasDuplicatedOrigin_VersionIsCalculatedProperly()
{
string pipelineBranch = "BRANCH_NAME";
string pipelineBranchOrig = Environment.GetEnvironmentVariable(pipelineBranch);

using (var fixture = new EmptyRepositoryFixture())
{
var remoteRepositoryPath = PathHelper.GetTempPath();
Repository.Init(remoteRepositoryPath);
using (var remoteRepository = new Repository(remoteRepositoryPath))
{
remoteRepository.Config.Set("user.name", "Test");
remoteRepository.Config.Set("user.email", "[email protected]");
fixture.Repository.Network.Remotes.Add("origin", remoteRepositoryPath);
// Jenkins Pipeline will create a duplicate origin:
fixture.Repository.Network.Remotes.Add("origin1", remoteRepositoryPath);
Console.WriteLine("Created git repository at {0}", remoteRepositoryPath);
remoteRepository.MakeATaggedCommit("1.0.3");

var branch = remoteRepository.CreateBranch("FeatureBranch");
Commands.Checkout(remoteRepository, branch);
remoteRepository.MakeCommits(2);
Commands.Checkout(remoteRepository, remoteRepository.Head.Tip.Sha);
//Emulate merge commit
var mergeCommitSha = remoteRepository.MakeACommit().Sha;
Commands.Checkout(remoteRepository, "master"); // HEAD cannot be pointing at the merge commit
remoteRepository.Refs.Add("refs/heads/pull/5/head", new ObjectId(mergeCommitSha));

// Checkout PR commit
Commands.Fetch((Repository)fixture.Repository, "origin", new string[0], new FetchOptions(), null);
Commands.Checkout(fixture.Repository, mergeCommitSha);
}

// Emulating Jenkins environment variable
Environment.SetEnvironmentVariable(pipelineBranch, "PR-5");
Environment.SetEnvironmentVariable("JENKINS_URL", "url", EnvironmentVariableTarget.Process);

var result = GitVersionHelper.ExecuteIn(fixture.RepositoryPath);

result.ExitCode.ShouldBe(0);
result.OutputVariables.FullSemVer.ShouldBe("1.0.4-PullRequest0005.3");

// Cleanup repository files
DirectoryHelper.DeleteDirectory(remoteRepositoryPath);

Environment.SetEnvironmentVariable(pipelineBranch, pipelineBranchOrig);
Environment.SetEnvironmentVariable("JENKINS_URL", null, EnvironmentVariableTarget.Process);
}
}
}