From 32251bae2b1718309161b70cbb6f023a811f7d55 Mon Sep 17 00:00:00 2001 From: Hector FROHLICH CORTEZ Date: Mon, 24 Mar 2025 21:36:20 -0300 Subject: [PATCH] [feature] list, create and force sync remote mirrors for a project --- src/GitLabApiClient/IProjectsClient.cs | 25 +++++++++++ .../Internal/Paths/ProjectId.cs | 10 +---- .../Requests/CreateRemoteMirrorRequest.cs | 29 +++++++++++++ .../Requests/TransferProjectRequest.cs | 1 + .../Models/Projects/Responses/ImportStatus.cs | 2 + .../Models/Projects/Responses/RemoteMirror.cs | 41 +++++++++++++++++++ src/GitLabApiClient/ProjectsClient.cs | 30 +++++++++++++- 7 files changed, 129 insertions(+), 9 deletions(-) create mode 100644 src/GitLabApiClient/Models/Projects/Requests/CreateRemoteMirrorRequest.cs create mode 100644 src/GitLabApiClient/Models/Projects/Responses/RemoteMirror.cs diff --git a/src/GitLabApiClient/IProjectsClient.cs b/src/GitLabApiClient/IProjectsClient.cs index 75df4984..471374fe 100644 --- a/src/GitLabApiClient/IProjectsClient.cs +++ b/src/GitLabApiClient/IProjectsClient.cs @@ -213,5 +213,30 @@ public interface IProjectsClient /// The ID, path or of the project. /// Status of the import Task GetImportStatusAsync(ProjectId projectId); + + /// + /// Gets the remote mirrors for a project. + /// + /// The project identifier. + /// List of remote mirrors + Task> GetRemoteMirrorsAsync(ProjectId projectId); + + /// + /// Creates a remote mirror in a project. + /// + /// The project identifier. + /// The request . + /// An instance of + + Task CreateRemoteMirrorAsync(ProjectId projectId, CreateRemoteMirrorRequest request); + + /// + /// Forces the mirror to sync. + /// + /// The project identifier. + /// The mirror identifier. + + Task ForceSyncMirrorAsync(ProjectId projectId, int mirrorId); + } } diff --git a/src/GitLabApiClient/Internal/Paths/ProjectId.cs b/src/GitLabApiClient/Internal/Paths/ProjectId.cs index 16dc321a..b5bb0348 100644 --- a/src/GitLabApiClient/Internal/Paths/ProjectId.cs +++ b/src/GitLabApiClient/Internal/Paths/ProjectId.cs @@ -15,15 +15,9 @@ public class ProjectId /// /// The project path ie. 'group/project' /// - public static implicit operator ProjectId(string projectPath) - { - return new ProjectId(projectPath.UrlEncode()); - } + public static implicit operator ProjectId(string projectPath) => new ProjectId(projectPath.UrlEncode()); - public static implicit operator ProjectId(int projectId) - { - return new ProjectId(projectId.ToString()); - } + public static implicit operator ProjectId(int projectId) => new ProjectId(projectId.ToString()); public static implicit operator ProjectId(Project project) { diff --git a/src/GitLabApiClient/Models/Projects/Requests/CreateRemoteMirrorRequest.cs b/src/GitLabApiClient/Models/Projects/Requests/CreateRemoteMirrorRequest.cs new file mode 100644 index 00000000..cffd68bb --- /dev/null +++ b/src/GitLabApiClient/Models/Projects/Requests/CreateRemoteMirrorRequest.cs @@ -0,0 +1,29 @@ +using Newtonsoft.Json; + +namespace GitLabApiClient.Models.Projects.Requests +{ + public class CreateRemoteMirrorRequest + { + + [JsonProperty("url", NullValueHandling = NullValueHandling.Ignore)] + public string Url { get; set; } + + [JsonProperty("enabled", NullValueHandling = NullValueHandling.Ignore)] + public bool? Enabled { get; set; } + + /// + /// Gets or sets the authentication method. + /// + /// + /// ssh_public_key or password + /// + [JsonProperty("auth_method", NullValueHandling = NullValueHandling.Ignore)] + public string AuthMethod { get; set; } + + [JsonProperty("only_protected_branches", NullValueHandling = NullValueHandling.Ignore)] + public bool? OnlyProtectedBranches { get; set; } + + [JsonProperty("keep_divergent_refs", NullValueHandling = NullValueHandling.Ignore)] + public bool? KeepDivergentRefs { get; set; } + } +} diff --git a/src/GitLabApiClient/Models/Projects/Requests/TransferProjectRequest.cs b/src/GitLabApiClient/Models/Projects/Requests/TransferProjectRequest.cs index 222eae74..210423a9 100644 --- a/src/GitLabApiClient/Models/Projects/Requests/TransferProjectRequest.cs +++ b/src/GitLabApiClient/Models/Projects/Requests/TransferProjectRequest.cs @@ -1,3 +1,4 @@ +using System; using Newtonsoft.Json; namespace GitLabApiClient.Models.Projects.Requests diff --git a/src/GitLabApiClient/Models/Projects/Responses/ImportStatus.cs b/src/GitLabApiClient/Models/Projects/Responses/ImportStatus.cs index 8fea28b4..3305ca97 100644 --- a/src/GitLabApiClient/Models/Projects/Responses/ImportStatus.cs +++ b/src/GitLabApiClient/Models/Projects/Responses/ImportStatus.cs @@ -1,3 +1,4 @@ +using System; using Newtonsoft.Json; namespace GitLabApiClient.Models.Projects.Responses @@ -28,4 +29,5 @@ public sealed class ImportStatus [JsonProperty("import_status")] public ImportStatusEnum Status { get; set; } } + } diff --git a/src/GitLabApiClient/Models/Projects/Responses/RemoteMirror.cs b/src/GitLabApiClient/Models/Projects/Responses/RemoteMirror.cs new file mode 100644 index 00000000..d7e00f84 --- /dev/null +++ b/src/GitLabApiClient/Models/Projects/Responses/RemoteMirror.cs @@ -0,0 +1,41 @@ +using System; +using Newtonsoft.Json; + +namespace GitLabApiClient.Models.Projects.Responses +{ + public class RemoteMirror + { + [JsonProperty("enabled", NullValueHandling = NullValueHandling.Ignore)] + public bool? Enabled { get; set; } + + [JsonProperty("id", NullValueHandling = NullValueHandling.Ignore)] + public int? Id { get; set; } + + [JsonProperty("auth_method", NullValueHandling = NullValueHandling.Ignore)] + public string AuthMethod { get; set; } + + [JsonProperty("last_error", NullValueHandling = NullValueHandling.Ignore)] + public object LastError { get; set; } + + [JsonProperty("last_successful_update_at", NullValueHandling = NullValueHandling.Ignore)] + public DateTime? LastSuccessfulUpdateAt { get; set; } + + [JsonProperty("last_update_at", NullValueHandling = NullValueHandling.Ignore)] + public DateTime? LastUpdateAt { get; set; } + + [JsonProperty("last_update_started_at", NullValueHandling = NullValueHandling.Ignore)] + public DateTime? LastUpdateStartedAt { get; set; } + + [JsonProperty("only_protected_branches", NullValueHandling = NullValueHandling.Ignore)] + public bool? OnlyProtectedBranches { get; set; } + + [JsonProperty("keep_divergent_refs", NullValueHandling = NullValueHandling.Ignore)] + public bool? KeepDivergentRefs { get; set; } + + [JsonProperty("update_status", NullValueHandling = NullValueHandling.Ignore)] + public string UpdateStatus { get; set; } + + [JsonProperty("url", NullValueHandling = NullValueHandling.Ignore)] + public string Url { get; set; } + } +} diff --git a/src/GitLabApiClient/ProjectsClient.cs b/src/GitLabApiClient/ProjectsClient.cs index ffd52c0f..a3b57630 100644 --- a/src/GitLabApiClient/ProjectsClient.cs +++ b/src/GitLabApiClient/ProjectsClient.cs @@ -106,7 +106,7 @@ public async Task> GetJobsAsync(ProjectId projectId, Action(url); } @@ -335,5 +335,33 @@ public async Task GetImportStatusAsync(ProjectId projectId) { return await _httpFacade.Get($"projects/{projectId}/import"); } + + /// + /// Gets the remote mirrors for a project. + /// + /// The project identifier. + /// List of remote mirrors + public async Task> GetRemoteMirrorsAsync(ProjectId projectId) + { + return await _httpFacade.Get>($"projects/{projectId}/remote_mirrors"); + } + + /// + /// Creates a remote mirror in a project. + /// + /// The project identifier. + /// The request . + /// + public async Task CreateRemoteMirrorAsync(ProjectId projectId, CreateRemoteMirrorRequest request) + { + return await _httpFacade.Post($"projects/{projectId}/remote_mirrors", request); + } + + /// + /// Forces the mirror to sync. + /// + /// The project identifier. + /// The mirror identifier. + public async Task ForceSyncMirrorAsync(ProjectId projectId, int mirrorId) => await _httpFacade.Post($"projects/{projectId}/remote_mirrors/{mirrorId}/sync"); } }