Skip to content

Commit 4e2b895

Browse files
committed
Add ClonePullRequests
1 parent ec0ccc7 commit 4e2b895

12 files changed

Lines changed: 101 additions & 22 deletions

File tree

CloneDevOpsTemplate/Controllers/RepositoryController.cs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public async Task<IActionResult> PullRequests(Guid projectId)
4848
return View(pullRequests.Value);
4949
}
5050

51-
pullRequests = await _repositoryService.GetGitPullRequest(projectId) ?? new();
51+
pullRequests = await _repositoryService.GetGitPullRequestAsync(projectId) ?? new();
5252
return View(pullRequests.Value);
5353
}
5454

@@ -72,4 +72,24 @@ public async Task<IActionResult> CloneRepository(Guid templateProjectId, Guid pr
7272

7373
return await CloneRepository();
7474
}
75+
76+
[HttpGet]
77+
public async Task<IActionResult> ClonePullRequests()
78+
{
79+
return await CloneRepository();
80+
}
81+
82+
[HttpPost]
83+
public async Task<IActionResult> ClonePullRequests(Guid templateProjectId, Guid projectId)
84+
{
85+
if (!ModelState.IsValid)
86+
{
87+
return await ClonePullRequests();
88+
}
89+
90+
await _cloneManager.CloneGitPullRequestsAsync(templateProjectId, projectId);
91+
ViewBag.SuccessMessage = "Success";
92+
93+
return await ClonePullRequests();
94+
}
7595
}

CloneDevOpsTemplate/IServices/IRepositoryService.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ public interface IRepositoryService
1010
Task<HttpResponseMessage> DeleteRepositoryAsync(Guid projectId, Guid repositoryId);
1111
Task<GitImportRequest?> CreateImportRequestAsync(Guid projectId, Guid repositoryId, string sourceRepositoryRemoteUrl, Guid serviceEndpointId);
1212
Task<GitImportRequest?> GetImportRequestAsync(Guid projectId, Guid repositoryId, int importRequestId);
13-
Task<GitPullRequests?> GetGitPullRequest(Guid projectId);
13+
Task<GitPullRequests?> GetGitPullRequestAsync(Guid projectId);
14+
Task<HttpResponseMessage> CreateGitPullRequestAsync(Guid projectId, Guid repositoryId, GitPullRequestBase pullRequest);
1415
}

CloneDevOpsTemplate/Managers/CloneManager.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,4 +216,33 @@ public async Task CloneTeamIterationsAsync(Guid templateProjectId, Guid projectI
216216
}
217217
}
218218
}
219+
220+
public async Task CloneGitPullRequestsAsync(Guid templateProjectId, Guid projectId)
221+
{
222+
var templatePullRequests = await _repositoryService.GetGitPullRequestAsync(templateProjectId) ?? new();
223+
var mappedRespositories = await MapRepositories(templateProjectId, projectId);
224+
foreach (var templatePullRequest in templatePullRequests.Value)
225+
{
226+
var repository = mappedRespositories.GetValueOrDefault(templatePullRequest.Repository.Id);
227+
await _repositoryService.CreateGitPullRequestAsync(projectId, repository, templatePullRequest);
228+
}
229+
}
230+
231+
public async Task<Dictionary<Guid, Guid>> MapRepositories(Guid templateProjectId, Guid projectId)
232+
{
233+
var mappedRespositories = new Dictionary<Guid, Guid>();
234+
var repositories = await _repositoryService.GetRepositoriesAsync(projectId) ?? new();
235+
var templateRepositories = await _repositoryService.GetRepositoriesAsync(templateProjectId) ?? new();
236+
237+
foreach (var templateRepository in templateRepositories.Value)
238+
{
239+
var mappedRespository = repositories.Value.FirstOrDefault(r => r.Name == templateRepository.Name);
240+
if (mappedRespository is not null)
241+
{
242+
mappedRespositories.Add(templateRepository.Id, mappedRespository.Id);
243+
}
244+
}
245+
246+
return mappedRespositories;
247+
}
219248
}

CloneDevOpsTemplate/Managers/ICloneManager.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ public interface ICloneManager
1515
Task CloneTeamsAndSettingsAndBoardsAsync(Project templateProject, Project project);
1616
Task CloneTeamSettingsAsync(Guid templateProjectId, Guid projectId, Guid templateTeamId, Guid projectTeamId);
1717
Task CloneTeamIterationsAsync(Guid templateProjectId, Guid projectId, Guid templateTeamId, Guid projectTeamId);
18+
Task CloneGitPullRequestsAsync(Guid templateProjectId, Guid projectId);
1819
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace CloneDevOpsTemplate.Models;
2+
3+
public class IdentityRef
4+
{
5+
public string DisplayName { get; set; } = string.Empty;
6+
public string Url { get; set; } = string.Empty;
7+
public string Descriptor { get; set; } = string.Empty;
8+
public string DirectoryAlias { get; set; } = string.Empty;
9+
public string Id { get; set; } = string.Empty;
10+
public bool IsDeletedInOrigin { get; set; }
11+
}

CloneDevOpsTemplate/Models/PullRequests.cs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,29 @@ public class GitPullRequests
88
public GitPullRequest[] Value { get; set; } = [];
99
}
1010

11-
public class GitPullRequest
11+
public class GitPullRequestBase
12+
{
13+
public string Title { get; set; } = string.Empty;
14+
public string Description { get; set; } = string.Empty;
15+
public string SourceRefName { get; set; } = string.Empty;
16+
public string TargetRefName { get; set; } = string.Empty;
17+
public IdentityRef CreatedBy { get; set; } = new();
18+
public bool IsDraft { get; set; }
19+
public IdentityRef[] Reviewers { get; set; } = [];
20+
}
21+
22+
public class GitPullRequest : GitPullRequestBase
1223
{
1324
public Repository Repository { get; set; } = new();
1425
public int PullRequestId { get; set; }
1526
public int CodeReviewId { get; set; }
1627
public PullRequestStatus Status { get; set; }
17-
public User CreatedBy { get; set; } = new();
1828
public DateTime CreationDate { get; set; }
19-
public string Title { get; set; } = string.Empty;
20-
public string Description { get; set; } = string.Empty;
21-
public string SourceRefName { get; set; } = string.Empty;
22-
public string TargetRefName { get; set; } = string.Empty;
2329
public PullRequestAsyncStatus MergeStatus { get; set; }
24-
public bool IsDraft { get; set; }
2530
public Guid MergeId { get; set; }
2631
public GitCommitRef LastMergeSourceCommit { get; set; } = new();
2732
public GitCommitRef LastMergeTargetCommit { get; set; } = new();
2833
public GitCommitRef LastMergeCommit { get; set; } = new();
29-
public User[] Reviewers { get; set; } = [];
3034
public bool SupportsIterations { get; set; }
3135
}
3236

CloneDevOpsTemplate/Models/Services.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,13 @@ public class ServiceModelBase
1919
public class ServiceModel : ServiceModelBase
2020
{
2121
public Guid Id { get; set; }
22-
public User CreatedBy { get; set; } = new();
22+
public IdentityRef CreatedBy { get; set; } = new();
2323
public string Description { get; set; } = string.Empty;
2424
public bool IsShared { get; set; }
2525
public bool IsOutdated { get; set; }
2626
public DateTime CreationDate { get; set; }
2727
}
2828

29-
public class User
30-
{
31-
public string DisplayName { get; set; } = string.Empty;
32-
public string Url { get; set; } = string.Empty;
33-
}
34-
3529
public class ServiceAuthorization
3630
{
3731
public string Scheme { get; set; } = string.Empty;

CloneDevOpsTemplate/Services/RepositoryService.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,13 @@ public Task<HttpResponseMessage> DeleteRepositoryAsync(Guid projectId, Guid repo
4949
return _client.GetFromJsonAsync<GitImportRequest>($"{projectId}/_apis/git/repositories/{repositoryId}/importRequests/{importRequestId}");
5050
}
5151

52-
public Task<GitPullRequests?> GetGitPullRequest(Guid projectId)
52+
public Task<GitPullRequests?> GetGitPullRequestAsync(Guid projectId)
5353
{
5454
return _client.GetFromJsonAsync<GitPullRequests>($"{projectId}/_apis/git/pullrequests");
5555
}
56+
57+
public Task<HttpResponseMessage> CreateGitPullRequestAsync(Guid projectId, Guid repositoryId, GitPullRequestBase pullRequest)
58+
{
59+
return _client.PostAsJsonAsync($"{projectId}/_apis/git/repositories/{repositoryId}/pullrequests?api-version=7.1", pullRequest);
60+
}
5661
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
@model ProjectBase[]
2+
@{
3+
ViewData["Title"] = "Clone pull requests";
4+
}
5+
6+
<h1>Clone pull requests</h1>
7+
8+
@{
9+
await Html.RenderPartialAsync("_CloneByProject", Tuple.Create(Model, "Repository", "ClonePullRequests"));
10+
}

CloneDevOpsTemplate/Views/Shared/_Header.cshtml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@
6262
<a class="dropdown-item" asp-controller="Repository"
6363
asp-action="CloneRepository">Repository</a>
6464
</li>
65+
<li>
66+
<a class="dropdown-item" asp-controller="Repository" asp-action="ClonePullRequests">Pull
67+
requests</a>
68+
</li>
6569
</ul>
6670
</li>
6771
<li class="nav-item-button">

0 commit comments

Comments
 (0)