Skip to content

Commit

Permalink
Implement Pipeline Schedule Client (#773)
Browse files Browse the repository at this point in the history
* Implement Pipeline Schedule Client

* Fix detailed PipelineSchedule model deserialization

* Implement Schedule's pipelines endpoint

* Fix naming convention

* Add Last Pipeline information

* MR Suggestions
  • Loading branch information
mlemieuxlafontaine-ubi authored Oct 25, 2024
1 parent 0a601ce commit d78dcb9
Show file tree
Hide file tree
Showing 15 changed files with 392 additions and 0 deletions.
3 changes: 3 additions & 0 deletions NGitLab.Mock/Clients/GitLabClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ public IGraphQLClient GraphQL

public IPipelineClient GetPipelines(ProjectId projectId) => new PipelineClient(Context, jobClient: GetJobs(projectId), projectId: projectId);

public IPipelineScheduleClient GetPipelineSchedules(ProjectId projectId)
=> new PipelineScheduleClient(Context, projectId);

public IProjectBadgeClient GetProjectBadgeClient(int projectId) => GetProjectBadgeClient((long)projectId);

public IProjectBadgeClient GetProjectBadgeClient(ProjectId projectId) => new ProjectBadgeClient(Context, projectId);
Expand Down
70 changes: 70 additions & 0 deletions NGitLab.Mock/Clients/PipelineScheduleClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using NGitLab.Mock.Internals;
using NGitLab.Models;

namespace NGitLab.Mock.Clients;

internal class PipelineScheduleClient : ClientBase, IPipelineScheduleClient
{
private readonly ProjectId _projectId;

public PipelineScheduleClient(ClientContext context, ProjectId projectId)
: base(context)
{
_projectId = projectId;
}

public Models.PipelineSchedule this[int id]
{
get
{
using (Context.BeginOperationScope())
{
var project = GetProject(_projectId, ProjectPermission.View);
var schedule = project.PipelineSchedules.GetById(id);
if (schedule == null)
throw new GitLabNotFoundException();

return schedule.ToPipelineScheduleClient();
}
}
}

public IEnumerable<PipelineScheduleBasic> All
{
get
{
using (Context.BeginOperationScope())
{
var project = GetProject(_projectId, ProjectPermission.View);
return project.PipelineSchedules.Select(s => s.ToPipelineScheduleBasicClient()).ToList();
}
}
}

public GitLabCollectionResponse<PipelineScheduleBasic> GetAllAsync()
=> GitLabCollectionResponse.Create(All);

public GitLabCollectionResponse<PipelineBasic> GetAllSchedulePipelinesAsync(int id)
{
using (Context.BeginOperationScope())
{
var project = GetProject(_projectId, ProjectPermission.View);
var pipelines = project.Pipelines
.Where(p => string.Equals(p.Source, "schedule", System.StringComparison.Ordinal))
.Select(p => p.ToPipelineBasicClient());

return GitLabCollectionResponse.Create(pipelines);
}
}

public async Task<Models.PipelineSchedule> GetByIdAsync(int id, CancellationToken cancellationToken = default)
{
await Task.Yield();

return this[id];
}
}
3 changes: 3 additions & 0 deletions NGitLab.Mock/GitLabServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public sealed class GitLabServer : GitLabObject, IDisposable
private int _lastIssueId = 10000;
private int _lastMilestoneId = 10000;
private int _lastPipelineId = 10000;
private int _lastPipelineScheduleId = 10000;
private int _lastJobId = 10000;
private int _lastBadgeId = 10000;
private int _lastLabelId = 10000;
Expand Down Expand Up @@ -118,6 +119,8 @@ public void Dispose()

internal int GetNewPipelineId() => Interlocked.Increment(ref _lastPipelineId);

internal int GetNewPipelineScheduleId() => Interlocked.Increment(ref _lastPipelineScheduleId);

internal int GetNewJobId() => Interlocked.Increment(ref _lastJobId);

internal int GetNewBadgeId() => Interlocked.Increment(ref _lastBadgeId);
Expand Down
4 changes: 4 additions & 0 deletions NGitLab.Mock/Pipeline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public Pipeline(string @ref)

public Sha1 Sha { get; set; }

public string Source { get; set; }

public Sha1 BeforeSha { get; set; }

public string YamlError { get; set; }
Expand Down Expand Up @@ -126,6 +128,7 @@ internal PipelineBasic ToPipelineBasicClient()
Status = Status,
Ref = Ref,
Sha = Sha,
Source = Source,
CreatedAt = CreatedAt.UtcDateTime,
UpdatedAt = UpdatedAt.UtcDateTime,
ProjectId = Project.Id,
Expand All @@ -141,6 +144,7 @@ internal Models.Pipeline ToPipelineClient()
Ref = Ref,
Tag = Tag,
Sha = Sha,
Source = Source,
BeforeSha = BeforeSha,
YamlError = YamlError,
User = User.ToClientUser(),
Expand Down
81 changes: 81 additions & 0 deletions NGitLab.Mock/PipelineSchedule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NGitLab.Models;

namespace NGitLab.Mock;

public sealed class PipelineSchedule : GitLabObject
{
public Project Project => (Project)Parent;

public int Id { get; set; }

public string Description { get; set; }

public string Ref { get; set; }

public string Cron { get; set; }

public DateTime NextRunAt { get; set; }

public bool Active { get; set; }

public DateTime CreatedAt { get; set; }

public DateTime UpdatedAt { get; set; }

public User Owner { get; set; }

public IDictionary<string, string> Variables { get; set; } = new Dictionary<string, string>(StringComparer.Ordinal);

public PipelineScheduleBasic ToPipelineScheduleBasicClient()
=> new()
{
Id = Id,
Active = Active,
CreatedAt = CreatedAt,
Cron = Cron,
Description = Description,
NextRunAt = NextRunAt,
Owner = Owner.ToClientUser(),
Ref = Ref,
UpdatedAt = UpdatedAt,
};

public Models.PipelineSchedule ToPipelineScheduleClient()
=> new()
{
Id = Id,
Active = Active,
CreatedAt = CreatedAt,
Cron = Cron,
Description = Description,
NextRunAt = NextRunAt,
Owner = Owner.ToClientUser(),
Ref = Ref,
UpdatedAt = UpdatedAt,
Variables = Variables.Select((kvp) => new PipelineVariable
{
Key = kvp.Key,
Value = kvp.Value,
}),
};

public Pipeline AddNewPipeline()
{
var pipeline = new Pipeline(Ref)
{
Source = "schedule",
Variables = Variables.Select((kvp) => new PipelineVariable
{
Key = kvp.Key,
Value = kvp.Value,
}),
User = Owner,
};

Project.Pipelines.Add(pipeline);
return pipeline;
}
}
33 changes: 33 additions & 0 deletions NGitLab.Mock/PipelineScheduleCollection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using System.Linq;

namespace NGitLab.Mock;

public class PipelineScheduleCollection : Collection<PipelineSchedule>
{
private readonly Project _project;

public PipelineScheduleCollection(Project project)
: base(project)
{
_project = project;
}

public PipelineSchedule GetById(int id)
{
return this.FirstOrDefault(x => x.Id == id);
}

public override void Add(PipelineSchedule schedule)
{
if (schedule is null)
throw new ArgumentNullException(nameof(schedule));

if (schedule.Id == default)
{
schedule.Id = Server.GetNewPipelineScheduleId();
}

base.Add(schedule);
}
}
3 changes: 3 additions & 0 deletions NGitLab.Mock/Project.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public Project(string name, string path)
Issues = new IssueCollection(this);
Milestones = new MilestoneCollection(this);
Pipelines = new PipelineCollection(this);
PipelineSchedules = new PipelineScheduleCollection(this);
Jobs = new JobCollection(this);
Badges = new BadgeCollection(this);
Labels = new LabelsCollection(this);
Expand Down Expand Up @@ -120,6 +121,8 @@ public string[] Tags

public PipelineCollection Pipelines { get; }

public PipelineScheduleCollection PipelineSchedules { get; }

public JobCollection Jobs { get; }

public LabelsCollection Labels { get; }
Expand Down
33 changes: 33 additions & 0 deletions NGitLab.Mock/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,8 @@ NGitLab.Mock.Pipeline.Ref.get -> string
NGitLab.Mock.Pipeline.Ref.set -> void
NGitLab.Mock.Pipeline.Sha.get -> NGitLab.Sha1
NGitLab.Mock.Pipeline.Sha.set -> void
NGitLab.Mock.Pipeline.Source.get -> string
NGitLab.Mock.Pipeline.Source.set -> void
NGitLab.Mock.Pipeline.StartedAt.get -> System.DateTimeOffset?
NGitLab.Mock.Pipeline.StartedAt.set -> void
NGitLab.Mock.Pipeline.Status.get -> NGitLab.JobStatus
Expand All @@ -836,6 +838,35 @@ NGitLab.Mock.PipelineCollection
NGitLab.Mock.PipelineCollection.Add(string ref, NGitLab.JobStatus status, NGitLab.Mock.User user) -> NGitLab.Mock.Pipeline
NGitLab.Mock.PipelineCollection.GetById(int id) -> NGitLab.Mock.Pipeline
NGitLab.Mock.PipelineCollection.PipelineCollection(NGitLab.Mock.GitLabObject parent) -> void
NGitLab.Mock.PipelineSchedule
NGitLab.Mock.PipelineSchedule.Active.get -> bool
NGitLab.Mock.PipelineSchedule.Active.set -> void
NGitLab.Mock.PipelineSchedule.AddNewPipeline() -> NGitLab.Mock.Pipeline
NGitLab.Mock.PipelineSchedule.CreatedAt.get -> System.DateTime
NGitLab.Mock.PipelineSchedule.CreatedAt.set -> void
NGitLab.Mock.PipelineSchedule.Cron.get -> string
NGitLab.Mock.PipelineSchedule.Cron.set -> void
NGitLab.Mock.PipelineSchedule.Description.get -> string
NGitLab.Mock.PipelineSchedule.Description.set -> void
NGitLab.Mock.PipelineSchedule.Id.get -> int
NGitLab.Mock.PipelineSchedule.Id.set -> void
NGitLab.Mock.PipelineSchedule.NextRunAt.get -> System.DateTime
NGitLab.Mock.PipelineSchedule.NextRunAt.set -> void
NGitLab.Mock.PipelineSchedule.Owner.get -> NGitLab.Mock.User
NGitLab.Mock.PipelineSchedule.Owner.set -> void
NGitLab.Mock.PipelineSchedule.PipelineSchedule() -> void
NGitLab.Mock.PipelineSchedule.Project.get -> NGitLab.Mock.Project
NGitLab.Mock.PipelineSchedule.Ref.get -> string
NGitLab.Mock.PipelineSchedule.Ref.set -> void
NGitLab.Mock.PipelineSchedule.ToPipelineScheduleBasicClient() -> NGitLab.Models.PipelineScheduleBasic
NGitLab.Mock.PipelineSchedule.ToPipelineScheduleClient() -> NGitLab.Models.PipelineSchedule
NGitLab.Mock.PipelineSchedule.UpdatedAt.get -> System.DateTime
NGitLab.Mock.PipelineSchedule.UpdatedAt.set -> void
NGitLab.Mock.PipelineSchedule.Variables.get -> System.Collections.Generic.IDictionary<string, string>
NGitLab.Mock.PipelineSchedule.Variables.set -> void
NGitLab.Mock.PipelineScheduleCollection
NGitLab.Mock.PipelineScheduleCollection.GetById(int id) -> NGitLab.Mock.PipelineSchedule
NGitLab.Mock.PipelineScheduleCollection.PipelineScheduleCollection(NGitLab.Mock.Project project) -> void
NGitLab.Mock.Project
NGitLab.Mock.Project.AccessibleMergeRequests.get -> bool
NGitLab.Mock.Project.AccessibleMergeRequests.set -> void
Expand Down Expand Up @@ -911,6 +942,7 @@ NGitLab.Mock.Project.Path.get -> string
NGitLab.Mock.Project.PathWithNamespace.get -> string
NGitLab.Mock.Project.Permissions.get -> NGitLab.Mock.PermissionCollection
NGitLab.Mock.Project.Pipelines.get -> NGitLab.Mock.PipelineCollection
NGitLab.Mock.Project.PipelineSchedules.get -> NGitLab.Mock.PipelineScheduleCollection
NGitLab.Mock.Project.Project() -> void
NGitLab.Mock.Project.Project(string name) -> void
NGitLab.Mock.Project.Project(string name, string path) -> void
Expand Down Expand Up @@ -1253,6 +1285,7 @@ override NGitLab.Mock.MilestoneCollection.Add(NGitLab.Mock.Milestone item) -> vo
override NGitLab.Mock.NonTextFile.Content.get -> byte[]
override NGitLab.Mock.NoteCollection<T>.Add(T item) -> void
override NGitLab.Mock.PipelineCollection.Add(NGitLab.Mock.Pipeline pipeline) -> void
override NGitLab.Mock.PipelineScheduleCollection.Add(NGitLab.Mock.PipelineSchedule schedule) -> void
override NGitLab.Mock.ProjectCollection.Add(NGitLab.Mock.Project project) -> void
override NGitLab.Mock.ProjectHookCollection.Add(NGitLab.Mock.ProjectHook item) -> void
override NGitLab.Mock.ProjectIssueNote.NoteableType.get -> string
Expand Down
3 changes: 3 additions & 0 deletions NGitLab/GitLabClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ public IPipelineClient GetPipelines(int projectId)
public IPipelineClient GetPipelines(ProjectId projectId)
=> new PipelineClient(_api, projectId);

public IPipelineScheduleClient GetPipelineSchedules(ProjectId projectId)
=> new PipelineScheduleClient(_api, projectId);

public ITriggerClient GetTriggers(int projectId)
=> GetTriggers((long)projectId);

Expand Down
2 changes: 2 additions & 0 deletions NGitLab/IGitLabClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ public interface IGitLabClient

IPipelineClient GetPipelines(ProjectId projectId);

IPipelineScheduleClient GetPipelineSchedules(ProjectId projectId);

[EditorBrowsable(EditorBrowsableState.Never)]
ITriggerClient GetTriggers(int projectId);

Expand Down
43 changes: 43 additions & 0 deletions NGitLab/IPipelineScheduleClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using NGitLab.Models;

namespace NGitLab;

public interface IPipelineScheduleClient
{
/// <summary>
/// Gets all the pipeline schedules of the project
/// </summary>
IEnumerable<PipelineScheduleBasic> All { get; }

/// <summary>
/// Details of single schedule
/// </summary>
/// <param name="id">Schedule Id</param>
/// <returns></returns>
PipelineSchedule this[int id] { get; }

/// <summary>
/// Gets the details of single schedule
/// </summary>
/// <param name="id">Schedule Id</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<PipelineSchedule> GetByIdAsync(int id, CancellationToken cancellationToken = default);

/// <summary>
/// Gets all the pipeline schedules of the project
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
GitLabCollectionResponse<PipelineScheduleBasic> GetAllAsync();

/// <summary>
/// Gets all pipelines triggered by a pipeline schedule in a project.
/// </summary>
/// <param name="id">Schedule Id</param>
/// <returns></returns>
GitLabCollectionResponse<PipelineBasic> GetAllSchedulePipelinesAsync(int id);
}
Loading

0 comments on commit d78dcb9

Please sign in to comment.