Skip to content
Closed
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
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should tests have been deleted from here?

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using Calamari.ArgoCD.Git;
using Calamari.ArgoCD.Git.GitVendorApiAdapters;
using Calamari.ArgoCD.Git.GitVendorApiAdapters.GitHub;
using FluentAssertions;
using NUnit.Framework;

Expand All @@ -9,41 +10,25 @@ namespace Calamari.Tests.ArgoCD.Git.GitVendorApiAdapters
[TestFixture]
public class GitHubApiAdapterFactoryTests
{
[Test]
public void RandomHost_ReturnsNull()
{
var git = new GitHubApiAdapterFactory();
var adapter = git.TryCreateGitVendorApiAdaptor(CreateConnection("http://someurl.com/org/repo"));
adapter.Should().BeNull();
}

[Test]
public void GitHubDomain_ReturnsAdapter()
{
var git = new GitHubApiAdapterFactory();
var adapter = git.TryCreateGitVendorApiAdaptor(CreateConnection("http://github.com/org/repo"));
var adapter = git.Create(CreateConnection("http://github.com/org/repo"));
adapter.Should().NotBeNull();
}

[Test]
public void GitHubSubDomain_ReturnsAdapter()
{
var git = new GitHubApiAdapterFactory();
var adapter = git.TryCreateGitVendorApiAdaptor(CreateConnection("http://foo.github.com/org/repo"));
var adapter = git.Create(CreateConnection("http://foo.github.com/org/repo"));
adapter.Should().NotBeNull();
}

[Test]
public void NonGitHubSubDomain_ReturnsNull()
{
var git = new GitHubApiAdapterFactory();
var adapter = git.TryCreateGitVendorApiAdaptor(CreateConnection("http://github.com.foobar/org/repo"));
adapter.Should().BeNull();
}

GitConnection CreateConnection(string url)
{
return new GitConnection(Some.String(), Some.String(), new Uri(url), GitBranchName.CreateFromFriendlyName("main"));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
using System.Threading.Tasks;
using Calamari.ArgoCD.Git;
using Calamari.ArgoCD.Git.GitVendorApiAdapters;
using Calamari.ArgoCD.Git.GitVendorApiAdapters.AzureDevOps;
using Calamari.ArgoCD.Git.GitVendorApiAdapters.BitBucket;
using Calamari.ArgoCD.Git.GitVendorApiAdapters.GitHub;
using Calamari.ArgoCD.Git.GitVendorApiAdapters.GitLab;
using Calamari.Common.Plumbing.FileSystem;
using FluentAssertions;
using LibGit2Sharp;
Expand Down
2 changes: 1 addition & 1 deletion source/Calamari.Tests/ArgoCD/Git/RepositoryFactoryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public void Init()
bareOrigin = RepositoryHelpers.CreateBareRepository(OriginPath);
RepositoryHelpers.CreateBranchIn(branchName, OriginPath);

repositoryFactory = new RepositoryFactory(log, fileSystem, tempDirectory, new GitVendorAgnosticApiAdapterFactory(Array.Empty<IGitVendorApiAdapterFactory>()), new SystemClock());
repositoryFactory = new RepositoryFactory(log, fileSystem, tempDirectory, new GitVendorAgnosticApiAdapterFactory(Array.Empty<IResolvingGitVendorApiAdapterFactory>()), new SystemClock());
}

[TearDown]
Expand Down
2 changes: 1 addition & 1 deletion source/Calamari.Tests/ArgoCD/Git/RepositoryWrapperTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public void Init()
Arg.Any<GitBranchName>(),
Arg.Any<CancellationToken>())
.Returns(new PullRequest("title", 1, "url"));
gitVendorAgnosticApiAdapterFactory.TryCreateGitVendorApiAdaptor(Arg.Any<IRepositoryConnection>()).Returns(gitVendorApiAdapter);
gitVendorAgnosticApiAdapterFactory.Create(Arg.Any<IRepositoryConnection>()).Returns(gitVendorApiAdapter);

var repositoryFactory = new RepositoryFactory(log, fileSystem, tempDirectory, gitVendorAgnosticApiAdapterFactory, new SystemClock());
gitConnection = new GitConnection(null, null, new Uri(OriginPath), branchName);
Expand Down
10 changes: 6 additions & 4 deletions source/Calamari/ArgoCD/ArgoCDModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
using Calamari.ArgoCD.Conventions;
using Calamari.ArgoCD.Git;
using Calamari.ArgoCD.Git.GitVendorApiAdapters;
using Calamari.ArgoCD.GitHub;
using Calamari.ArgoCD.Git.GitVendorApiAdapters.GitLab;
using Microsoft.Extensions.Caching.Memory;

namespace Calamari.ArgoCD
{
Expand All @@ -14,13 +15,14 @@ protected override void Load(ContainerBuilder builder)
builder.RegisterType<CommitMessageGenerator>().As<ICommitMessageGenerator>().InstancePerLifetimeScope();

builder.RegisterAssemblyTypes(GetType().Assembly)
.AssignableTo<IGitVendorApiAdapterFactory>()
.Except<GitVendorAgnosticApiAdapterFactory>()
.As<IGitVendorApiAdapterFactory>();
.AssignableTo<IResolvingGitVendorApiAdapterFactory>()
.As<IResolvingGitVendorApiAdapterFactory>();

builder.RegisterType<GitVendorAgnosticApiAdapterFactory>().As<IGitVendorAgnosticApiAdapterFactory>().InstancePerLifetimeScope();
builder.RegisterType<ArgoCDManifestsFileMatcher>().As<IArgoCDManifestsFileMatcher>().InstancePerLifetimeScope();
builder.RegisterType<ArgoCDFilesUpdatedReporter>().As<IArgoCDFilesUpdatedReporter>().InstancePerLifetimeScope();

builder.RegisterType<SelfHostedGitLabInspector>().AsSelf().InstancePerLifetimeScope();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Calamari.ArgoCD.Git.GitVendorApiAdapters
namespace Calamari.ArgoCD.Git.GitVendorApiAdapters.AzureDevOps
{
public class AzureDevOpsApiAdapter : IGitVendorApiAdapter
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;

namespace Calamari.ArgoCD.Git.GitVendorApiAdapters.AzureDevOps
{
public class AzureDevOpsAgnosticApiAdapterFactory : IResolvingGitVendorApiAdapterFactory
{
public bool CanHandleAsCloudHosted(IRepositoryConnection repositoryConnection)
{
return AzureDevOpsApiAdapter.CanInvokeWith(repositoryConnection.Url);
}
public IGitVendorApiAdapter? Create(IRepositoryConnection repositoryConnection)
{
throw new NotImplementedException();
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Calamari.ArgoCD.Git.GitVendorApiAdapters
namespace Calamari.ArgoCD.Git.GitVendorApiAdapters.BitBucket
{
public class BitBucketApiAdapter : IGitVendorApiAdapter
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;

namespace Calamari.ArgoCD.Git.GitVendorApiAdapters.BitBucket
{
public class BitBucketAgnosticApiAdapterFactory: IResolvingGitVendorApiAdapterFactory
{
static Uri baseUrl = new Uri("https://bitbucket.org");

public bool CanHandleAsCloudHosted(IRepositoryConnection repositoryConnection)
{
return repositoryConnection.Url.Host.Equals(baseUrl.Host, StringComparison.OrdinalIgnoreCase);
}

public IGitVendorApiAdapter Create(IRepositoryConnection repositoryConnection)
{
return new BitBucketApiAdapter(repositoryConnection, baseUrl);
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Calamari.ArgoCD.GitHub;
using Octokit;

namespace Calamari.ArgoCD.Git.GitVendorApiAdapters
namespace Calamari.ArgoCD.Git.GitVendorApiAdapters.GitHub
{
public class GitHubApiAdapter: IGitVendorApiAdapter
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,22 @@
using Octokit;
using Octokit.Internal;

namespace Calamari.ArgoCD.Git.GitVendorApiAdapters
namespace Calamari.ArgoCD.Git.GitVendorApiAdapters.GitHub
{
public class GitHubApiAdapterFactory: IGitVendorApiAdapterFactory
public class GitHubApiAdapterFactory: IResolvingGitVendorApiAdapterFactory
{
bool CanInvokeWith(IRepositoryConnection repositoryConnection)
{
return GitHubRepositoryOwnerParser.IsGitHub(repositoryConnection.Url);
}

public IGitVendorApiAdapter? TryCreateGitVendorApiAdaptor(IRepositoryConnection repositoryConnection)
public bool CanHandleAsCloudHosted(IRepositoryConnection repositoryConnection)
{
return CanInvokeWith(repositoryConnection);
}

public IGitVendorApiAdapter Create(IRepositoryConnection repositoryConnection)
{
if (!CanInvokeWith(repositoryConnection))
{
return null;
}

var credentials = new Credentials(repositoryConnection.Username, repositoryConnection.Password);
var client = CreateGitHubClient(credentials);
return new GitHubApiAdapter(client, repositoryConnection, new Uri("https://github.com/"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using NGitLab;
using NGitLab.Models;

namespace Calamari.ArgoCD.Git.GitVendorApiAdapters
namespace Calamari.ArgoCD.Git.GitVendorApiAdapters.GitLab
{
public class GitLabApiAdapter : IGitVendorApiAdapter
{
Expand All @@ -28,18 +28,35 @@ public async Task<PullRequest> CreatePullRequest(string pullRequestTitle,
GitBranchName destinationBranch,
CancellationToken cancellationToken)
{
await Task.CompletedTask;

await Task.CompletedTask;

var gitlabSrcBranch = StripBranchPrefix(sourceBranch.Value);
var gitlabDestBranch = StripBranchPrefix(destinationBranch.Value);
Comment on lines +34 to +35
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reasoning for this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

coz it doesn't work if we don't :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gitlab accepts the literal branch name with no prefixing.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So broken to begin it sounds like?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct.



var mergeRequest = gitLabClient.GetMergeRequest(projectPath).Create(new MergeRequestCreate()
{
Title = pullRequestTitle,
SourceBranch = sourceBranch.Value,
TargetBranch = destinationBranch.Value,
SourceBranch = gitlabSrcBranch,
TargetBranch = gitlabDestBranch,
Description = body
});
return new PullRequest(mergeRequest.Title, mergeRequest.Id, mergeRequest.WebUrl);
}

static string StripBranchPrefix(string input)
{
const string branchPrefix = "refs/heads/";
if (input.StartsWith(branchPrefix))
{
return input.Substring(branchPrefix.Length);
}

return input;
}



public string GenerateCommitUrl(string commit)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#nullable enable
using System;
using System.Threading;
using NGitLab;

namespace Calamari.ArgoCD.Git.GitVendorApiAdapters.GitLab
{
public class GitLabApiAdapterFactory : IResolvingGitVendorApiAdapterFactory
{
readonly string CloudHost = "https://gitlab.com";

readonly SelfHostedGitLabInspector selfHostedGitLabInspector;

public GitLabApiAdapterFactory(SelfHostedGitLabInspector selfHostedGitLabInspector)
{
this.selfHostedGitLabInspector = selfHostedGitLabInspector;
}

public bool CanHandleAsCloudHosted(Uri repositoryUri)
{
return repositoryUri.Host.Equals("gitlab.com", StringComparison.OrdinalIgnoreCase)
//Handle www.gitlab.com
|| repositoryUri.Host.EndsWith(".gitlab.com", StringComparison.OrdinalIgnoreCase);
}

public bool CanHandleAsSelfHosted(IRepositoryConnection repositoryConnection)
{
return selfHostedGitLabInspector.IsSelfHostedGitLabInstance(repositoryConnection.Url, CancellationToken.None).Result;
}

public IGitVendorApiAdapter Create(IRepositoryConnection repositoryConnection)
{
var host = CanHandleAsCloudHosted(repositoryConnection.Url)
? CloudHost
: SelfHostedGitLabInspector.GetSelfHostedBaseRepositoryUrl(repositoryConnection.Url);

var client = new GitLabClient(host, repositoryConnection.Password);

return new GitLabApiAdapter(client, repositoryConnection, new Uri(host));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Memory;

// This is duplicated from the OctopusDeploy server repo
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Helpful to add this same note to the server copy too

// source/Octopus.Core/Features/Git/PullRequests/Vendors/GitLab/SelfHostedGitLabInspector.cs
// Adjustments required:
// * Namespace
// * removed references to IOctopusHttpClientFactory - construct HtpClient directly
// * removed memory cache
// * removed semaphoreslim

namespace Calamari.ArgoCD.Git.GitVendorApiAdapters.GitLab;

public class SelfHostedGitLabInspector()
{
public static string GetSelfHostedBaseRepositoryUrl(Uri repositoryUri) => repositoryUri.GetLeftPart(UriPartial.Authority); //this elides the path & query

public async Task<bool> IsSelfHostedGitLabInstance(Uri repositoryUri, CancellationToken cancellationToken)
{
var selfHostedUri = GetSelfHostedBaseRepositoryUrl(repositoryUri);
var key = $"gitlab_{selfHostedUri}";

using var httpClient = new HttpClient();

//we can make an anonymous HTTP call to `/api/v4` and inspect the headers for `X-GitLab-Meta`
var apiUrl = new UriBuilder(selfHostedUri)
{
Path = "/api/v4"
};

bool hasGitLabHeader;
try
{
var response = await httpClient.SendAsync(new HttpRequestMessage(HttpMethod.Head, apiUrl.Uri),
HttpCompletionOption.ResponseHeadersRead,
cancellationToken);

//all API requests from GitLab have this header (afaik)
hasGitLabHeader = response.Headers.Contains("x-gitlab-meta");
}
catch
{
//any exception we ignore
hasGitLabHeader = false;
}

return hasGitLabHeader;
}
}
Loading