diff --git a/src/GitLabApiClient/BranchClient.cs b/src/GitLabApiClient/BranchClient.cs index 2746d61b..bfb49e53 100644 --- a/src/GitLabApiClient/BranchClient.cs +++ b/src/GitLabApiClient/BranchClient.cs @@ -4,6 +4,7 @@ using GitLabApiClient.Internal.Http; using GitLabApiClient.Internal.Paths; using GitLabApiClient.Internal.Queries; +using GitLabApiClient.Internal.Utilities; using GitLabApiClient.Models.Branches.Requests; using GitLabApiClient.Models.Branches.Responses; using GitLabApiClient.Models.Projects.Responses; @@ -30,7 +31,7 @@ internal BranchClient( /// The branch name. /// public async Task GetAsync(ProjectId projectId, string branchName) => - await _httpFacade.Get($"projects/{projectId}/repository/branches/{branchName}"); + await _httpFacade.Get($"projects/{projectId}/repository/branches/{branchName.UrlEncode()}"); /// /// @@ -62,7 +63,7 @@ public async Task CreateAsync(ProjectId projectId, CreateBranchRequest r /// The ID, path or of the project. /// The branch, you want deleted. public async Task DeleteBranch(ProjectId projectId, string branchName) => - await _httpFacade.Delete($"projects/{projectId}/repository/branches/{branchName}"); + await _httpFacade.Delete($"projects/{projectId}/repository/branches/{branchName.UrlEncode()}"); /// /// Deletes the merged branches @@ -78,7 +79,7 @@ public async Task DeleteMergedBranches(ProjectId projectId) => /// The protected branch /// A protected branch public async Task GetProtectedBranchesAsync(ProjectId projectId, string branchName) => - await _httpFacade.Get($"projects/{projectId}/protected_branches/{branchName}"); + await _httpFacade.Get($"projects/{projectId}/protected_branches/{branchName.UrlEncode()}"); /// /// Retrieves a list of Protected Branches from a project. @@ -103,6 +104,6 @@ public async Task ProtectBranchAsync(ProjectId projectId, Prote /// The ID, path or of the project. /// The Branch, you want to unprotect. public async Task UnprotectBranchAsync(ProjectId projectId, string branchName) => - await _httpFacade.Delete($"projects/{projectId}/protected_branches/{branchName}"); + await _httpFacade.Delete($"projects/{projectId}/protected_branches/{branchName.UrlEncode()}"); } } diff --git a/src/GitLabApiClient/IProjectsClient.cs b/src/GitLabApiClient/IProjectsClient.cs index 75df4984..6447cbe6 100644 --- a/src/GitLabApiClient/IProjectsClient.cs +++ b/src/GitLabApiClient/IProjectsClient.cs @@ -82,6 +82,14 @@ public interface IProjectsClient /// Newly created project. Task CreateAsync(CreateProjectRequest request); + /// + /// Create a new fork of a project + /// + /// The ID, path or of the project. + /// Create fork request + /// + Task CreateForkAsync(ProjectId projectId, CreateProjectForkRequest request); + /// /// Creates new project label. /// diff --git a/src/GitLabApiClient/Models/Projects/Requests/CreateProjectForkRequest.cs b/src/GitLabApiClient/Models/Projects/Requests/CreateProjectForkRequest.cs new file mode 100644 index 00000000..885c4401 --- /dev/null +++ b/src/GitLabApiClient/Models/Projects/Requests/CreateProjectForkRequest.cs @@ -0,0 +1,68 @@ +using GitLabApiClient.Internal.Utilities; +using Newtonsoft.Json; + +namespace GitLabApiClient.Models.Projects.Requests +{ + public sealed class CreateProjectForkRequest + { + + /// + /// Initializes a new instance of the class. + /// The name of the new project. + /// + public static CreateProjectForkRequest FromName(string name) + { + Guard.NotEmpty(name, nameof(name)); + return new CreateProjectForkRequest + { + Name = name, + Path = name.ToLower() + }; + } + + private CreateProjectForkRequest() { } + + /// + /// The description assigned to the resultant project after forking + /// + [JsonProperty("description")] + public string Description { get; set; } + + /// + /// For forked projects, target merge requests to this project. If , the target is the upstream project + /// + [JsonProperty("mr_default_target_self")] + public bool DefaultTargetSelf { get; set; } + + /// + /// The name assigned to the resultant project after forking + /// + [JsonProperty("name")] + public string Name { get; set; } + + /// + /// The ID of the namespace that the project is forked to + /// + [JsonProperty("namespace_id")] + public int NamespaceId { get; set; } + + /// + /// The path of the namespace that the project is forked to + /// + [JsonProperty("namespace_path")] + public int NamespacePath { get; set; } + + /// + /// The path assigned to the resultant project after forking + /// + [JsonProperty("path")] + public string Path { get; set; } + + /// + /// The assigned to the resultant project after forking + /// + [JsonProperty("visibility")] + public ProjectVisibilityLevel? Visibility { get; set; } + + } +} diff --git a/src/GitLabApiClient/ProjectsClient.cs b/src/GitLabApiClient/ProjectsClient.cs index ffd52c0f..fba71036 100644 --- a/src/GitLabApiClient/ProjectsClient.cs +++ b/src/GitLabApiClient/ProjectsClient.cs @@ -136,6 +136,19 @@ public async Task CreateAsync(CreateProjectRequest request) return await _httpFacade.Post("projects", request); } + /// + /// Create a new fork of a project + /// + /// The ID, path or of the project. + /// Create fork request + /// Newly created project. + /// The forking operation for a project is asynchronous and is completed in a background job. The request returns immediately. To determine whether the fork of the project has completed, query the import_status for the new project. + public async Task CreateForkAsync(ProjectId projectId, CreateProjectForkRequest request) + { + Guard.NotNull(request, nameof(request)); + return await _httpFacade.Post($"projects/{projectId}/fork", request); + } + /// /// Creates new project label. ///