Skip to content
Open
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
53 changes: 53 additions & 0 deletions NGitLab.Mock.Tests/MergeRequestsMockTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -437,4 +437,57 @@ public void Test_create_merge_request_without_target_project_id()

Assert.That(mergeRequest, Is.Not.Null);
}

[Test]
public void Test_create_merge_request_with_merge_after()
{
using var server = new GitLabConfig()
.WithUser("User1", isDefault: true)
.WithProject("Test", addDefaultUserAsMaintainer: true, configure: project => project
.WithCommit("Initial commit")
.WithCommit("Second commit", sourceBranch: "feature-branch", configure: commit => commit
.WithFile("file.txt", "content")))
.BuildServer();

var client = server.CreateClient();
var mergeAfter = new DateTime(2030, 1, 2, 3, 4, 5, DateTimeKind.Utc);

var mergeRequest = client
.GetMergeRequest(1)
.Create(new MergeRequestCreate
{
SourceBranch = "feature-branch",
TargetBranch = "main",
Title = "Merge request 1",
MergeAfter = mergeAfter,
});

Assert.That(mergeRequest.MergeAfter, Is.EqualTo(mergeAfter));
}

[Test]
public void Test_update_merge_request_with_merge_after()
{
using var server = new GitLabConfig()
.WithUser("User1", isDefault: true)
.WithProject("Test", addDefaultUserAsMaintainer: true, configure: project => project
.WithCommit("Initial commit")
.WithCommit("Second commit", sourceBranch: "feature-branch", configure: commit => commit
.WithFile("file.txt", "content")))
.BuildServer();

var mrClient = server.CreateClient().GetMergeRequest(1);
var mergeRequest = mrClient.Create(new MergeRequestCreate
{
SourceBranch = "feature-branch",
TargetBranch = "main",
Title = "Merge request 1",
});
var mergeAfter = new DateTime(2030, 1, 2, 3, 4, 5, DateTimeKind.Utc);

var updated = mrClient.Update(mergeRequest.Iid, new MergeRequestUpdate { MergeAfter = mergeAfter });

Assert.That(mergeRequest.MergeAfter, Is.Null);
Assert.That(updated.MergeAfter, Is.EqualTo(mergeAfter));
}
}
6 changes: 6 additions & 0 deletions NGitLab.Mock/Clients/MergeRequestClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ public Models.MergeRequest Create(MergeRequestCreate mergeRequestCreate)
mergeRequest.Description = mergeRequestCreate.Description;
mergeRequest.ShouldRemoveSourceBranch = mergeRequestCreate.RemoveSourceBranch;
mergeRequest.Squash = mergeRequestCreate.Squash;
mergeRequest.MergeAfter = mergeRequestCreate.MergeAfter;
SetLabels(mergeRequest, mergeRequestCreate.Labels, labelsToAdd: null, labelsToRemove: null);

return mergeRequest.ToMergeRequestClient();
Expand Down Expand Up @@ -714,6 +715,11 @@ public Models.MergeRequest Update(long mergeRequestIid, MergeRequestUpdate merge
mergeRequest.Title = mergeRequestUpdate.Title;
}

if (mergeRequestUpdate.MergeAfter != null)
{
mergeRequest.MergeAfter = mergeRequestUpdate.MergeAfter;
}

SetLabels(mergeRequest, mergeRequestUpdate.Labels, mergeRequestUpdate.AddLabels, mergeRequestUpdate.RemoveLabels);

mergeRequest.UpdatedAt = DateTimeOffset.UtcNow;
Expand Down
3 changes: 3 additions & 0 deletions NGitLab.Mock/MergeRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ public IReadOnlyList<Models.MergeRequestVersion> Versions

public DateTimeOffset? ClosedAt { get; set; }

public DateTimeOffset? MergeAfter { get; set; }

public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow;

public Sha1 Sha { get; private set; }
Expand Down Expand Up @@ -299,6 +301,7 @@ internal Models.MergeRequest ToMergeRequestClient()
UpdatedAt = UpdatedAt.UtcDateTime,
MergedAt = MergedAt?.UtcDateTime,
ClosedAt = ClosedAt?.UtcDateTime,
MergeAfter = MergeAfter?.UtcDateTime,
Description = Description,
Draft = Draft,
Id = Id,
Expand Down
2 changes: 2 additions & 0 deletions NGitLab.Mock/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,8 @@ NGitLab.Mock.MergeRequest.HeadSha.get -> string
NGitLab.Mock.MergeRequest.Id.get -> long
NGitLab.Mock.MergeRequest.Iid.get -> long
NGitLab.Mock.MergeRequest.Labels.get -> System.Collections.Generic.IList<string>
NGitLab.Mock.MergeRequest.MergeAfter.get -> System.DateTimeOffset?
NGitLab.Mock.MergeRequest.MergeAfter.set -> void
NGitLab.Mock.MergeRequest.MergeCommitSha.get -> NGitLab.Sha1?
NGitLab.Mock.MergeRequest.MergeCommitSha.set -> void
NGitLab.Mock.MergeRequest.MergedAt.get -> System.DateTimeOffset?
Expand Down
6 changes: 6 additions & 0 deletions NGitLab.Tests/Docker/GitLabTestContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,12 @@ public Group CreateSubgroup(long parentGroupId, string slug, string name = null,
configure?.Invoke(mergeRequestCreate);
var mr = client.GetMergeRequest(project.Id).Create(mergeRequestCreate);

// A merge request with a merge_after date more than a minute away will not become mergeable within the wait below.
if (mergeRequestCreate.MergeAfter?.ToUniversalTime() > DateTime.UtcNow.AddMinutes(1))
{
return (project, mr);
}

// GitLab computes diff data and merge status asynchronously after MR creation.
// Wait until the transient states resolve so callers can immediately query diffs or approvals.
var mrClient = client.GetMergeRequest(project.Id);
Expand Down
36 changes: 36 additions & 0 deletions NGitLab.Tests/MergeRequest/MergeRequestClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,35 @@ public async Task Test_cancel_merge_when_pipeline_succeeds()
AcceptAndCancelMergeRequest(mergeRequestClient, mergeRequest);
}

[Test]
[NGitLabRetry]
public async Task Test_create_merge_request_with_merge_after()
{
using var context = await GitLabTestContext.CreateAsync();
context.IgnoreTestIfGitLabVersionOutOfRange(VersionRange.Parse("[17.8,)"));
var mergeAfter = CreateMergeAfter();

var (_, mergeRequest) = await context.CreateMergeRequestAsync(mr => mr.MergeAfter = mergeAfter);

Assert.That(mergeRequest.MergeAfter?.ToUniversalTime(), Is.EqualTo(mergeAfter));
}

[Test]
[NGitLabRetry]
public async Task Test_update_merge_request_with_merge_after()
{
using var context = await GitLabTestContext.CreateAsync();
context.IgnoreTestIfGitLabVersionOutOfRange(VersionRange.Parse("[17.8,)"));
var (project, mergeRequest) = await context.CreateMergeRequestAsync();
var mergeRequestClient = context.Client.GetMergeRequest(project.Id);
var mergeAfter = CreateMergeAfter();

var updated = mergeRequestClient.Update(mergeRequest.Iid, new MergeRequestUpdate { MergeAfter = mergeAfter });

Assert.That(mergeRequest.MergeAfter, Is.Null);
Assert.That(updated.MergeAfter?.ToUniversalTime(), Is.EqualTo(mergeAfter));
}

[Test]
[NGitLabRetry]
public async Task Test_merge_request_head_pipeline()
Expand All @@ -297,6 +326,13 @@ public async Task Test_merge_request_head_pipeline()
Assert.That(mergeRequest.HeadPipeline?.ProjectId, Is.EqualTo(project.Id));
}

private static DateTime CreateMergeAfter()
{
// GitLab returns the timestamp with millisecond precision. Use whole seconds so the value round-trips.
var inOneWeek = DateTime.UtcNow.AddDays(7);
return new DateTime(inOneWeek.Year, inOneWeek.Month, inOneWeek.Day, inOneWeek.Hour, inOneWeek.Minute, inOneWeek.Second, DateTimeKind.Utc);
}

private static void ListMergeRequest(IMergeRequestClient mergeRequestClient, MergeRequest mergeRequest)
{
Assert.That(mergeRequestClient.All.Any(x => x.Id == mergeRequest.Id), Is.True, "Test 'All' accessor returns the merge request");
Expand Down
3 changes: 3 additions & 0 deletions NGitLab/Models/MergeRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ public class MergeRequest
[JsonPropertyName("detailed_merge_status")]
public DynamicEnum<DetailedMergeStatus> DetailedMergeStatus { get; set; }

[JsonPropertyName("merge_after")]
public DateTime? MergeAfter { get; set; }

[JsonPropertyName("merge_error")]
public string MergeError { get; set; }

Expand Down
6 changes: 5 additions & 1 deletion NGitLab/Models/MergeRequestCreate.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using System;
using System.Text.Json.Serialization;

namespace NGitLab.Models;

Expand Down Expand Up @@ -42,4 +43,7 @@ public class MergeRequestCreate

[JsonPropertyName("allow_collaboration")]
public bool? AllowCollaboration { get; set; }

[JsonPropertyName("merge_after")]
public DateTime? MergeAfter { get; set; }
}
6 changes: 5 additions & 1 deletion NGitLab/Models/MergeRequestUpdate.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text.Json.Serialization;
using System;
using System.Text.Json.Serialization;

namespace NGitLab.Models;

Expand Down Expand Up @@ -51,6 +52,9 @@ public class MergeRequestUpdate

[JsonPropertyName("squash_on_merge")]
public bool? SquashOnMerge { get; set; }

[JsonPropertyName("merge_after")]
public DateTime? MergeAfter { get; set; }
}

public class MergeRequestUpdateState
Expand Down
6 changes: 6 additions & 0 deletions NGitLab/PublicAPI/net10.0/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2892,6 +2892,8 @@ NGitLab.Models.MergeRequest.Iid.get -> long
NGitLab.Models.MergeRequest.Iid.set -> void
NGitLab.Models.MergeRequest.Labels.get -> string[]
NGitLab.Models.MergeRequest.Labels.set -> void
NGitLab.Models.MergeRequest.MergeAfter.get -> System.DateTime?
NGitLab.Models.MergeRequest.MergeAfter.set -> void
NGitLab.Models.MergeRequest.MergeCommitSha.get -> string
NGitLab.Models.MergeRequest.MergeCommitSha.set -> void
NGitLab.Models.MergeRequest.MergedAt.get -> System.DateTime?
Expand Down Expand Up @@ -3058,6 +3060,8 @@ NGitLab.Models.MergeRequestCreate.Description.get -> string
NGitLab.Models.MergeRequestCreate.Description.set -> void
NGitLab.Models.MergeRequestCreate.Labels.get -> string
NGitLab.Models.MergeRequestCreate.Labels.set -> void
NGitLab.Models.MergeRequestCreate.MergeAfter.get -> System.DateTime?
NGitLab.Models.MergeRequestCreate.MergeAfter.set -> void
NGitLab.Models.MergeRequestCreate.MergeRequestCreate() -> void
NGitLab.Models.MergeRequestCreate.MilestoneId.get -> long?
NGitLab.Models.MergeRequestCreate.MilestoneId.set -> void
Expand Down Expand Up @@ -3177,6 +3181,8 @@ NGitLab.Models.MergeRequestUpdate.Description.get -> string
NGitLab.Models.MergeRequestUpdate.Description.set -> void
NGitLab.Models.MergeRequestUpdate.Labels.get -> string
NGitLab.Models.MergeRequestUpdate.Labels.set -> void
NGitLab.Models.MergeRequestUpdate.MergeAfter.get -> System.DateTime?
NGitLab.Models.MergeRequestUpdate.MergeAfter.set -> void
NGitLab.Models.MergeRequestUpdate.MergeRequestUpdate() -> void
NGitLab.Models.MergeRequestUpdate.MilestoneId.get -> long?
NGitLab.Models.MergeRequestUpdate.MilestoneId.set -> void
Expand Down
6 changes: 6 additions & 0 deletions NGitLab/PublicAPI/net472/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2893,6 +2893,8 @@ NGitLab.Models.MergeRequest.Iid.get -> long
NGitLab.Models.MergeRequest.Iid.set -> void
NGitLab.Models.MergeRequest.Labels.get -> string[]
NGitLab.Models.MergeRequest.Labels.set -> void
NGitLab.Models.MergeRequest.MergeAfter.get -> System.DateTime?
NGitLab.Models.MergeRequest.MergeAfter.set -> void
NGitLab.Models.MergeRequest.MergeCommitSha.get -> string
NGitLab.Models.MergeRequest.MergeCommitSha.set -> void
NGitLab.Models.MergeRequest.MergedAt.get -> System.DateTime?
Expand Down Expand Up @@ -3059,6 +3061,8 @@ NGitLab.Models.MergeRequestCreate.Description.get -> string
NGitLab.Models.MergeRequestCreate.Description.set -> void
NGitLab.Models.MergeRequestCreate.Labels.get -> string
NGitLab.Models.MergeRequestCreate.Labels.set -> void
NGitLab.Models.MergeRequestCreate.MergeAfter.get -> System.DateTime?
NGitLab.Models.MergeRequestCreate.MergeAfter.set -> void
NGitLab.Models.MergeRequestCreate.MergeRequestCreate() -> void
NGitLab.Models.MergeRequestCreate.MilestoneId.get -> long?
NGitLab.Models.MergeRequestCreate.MilestoneId.set -> void
Expand Down Expand Up @@ -3178,6 +3182,8 @@ NGitLab.Models.MergeRequestUpdate.Description.get -> string
NGitLab.Models.MergeRequestUpdate.Description.set -> void
NGitLab.Models.MergeRequestUpdate.Labels.get -> string
NGitLab.Models.MergeRequestUpdate.Labels.set -> void
NGitLab.Models.MergeRequestUpdate.MergeAfter.get -> System.DateTime?
NGitLab.Models.MergeRequestUpdate.MergeAfter.set -> void
NGitLab.Models.MergeRequestUpdate.MergeRequestUpdate() -> void
NGitLab.Models.MergeRequestUpdate.MilestoneId.get -> long?
NGitLab.Models.MergeRequestUpdate.MilestoneId.set -> void
Expand Down
6 changes: 6 additions & 0 deletions NGitLab/PublicAPI/net8.0/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2892,6 +2892,8 @@ NGitLab.Models.MergeRequest.Iid.get -> long
NGitLab.Models.MergeRequest.Iid.set -> void
NGitLab.Models.MergeRequest.Labels.get -> string[]
NGitLab.Models.MergeRequest.Labels.set -> void
NGitLab.Models.MergeRequest.MergeAfter.get -> System.DateTime?
NGitLab.Models.MergeRequest.MergeAfter.set -> void
NGitLab.Models.MergeRequest.MergeCommitSha.get -> string
NGitLab.Models.MergeRequest.MergeCommitSha.set -> void
NGitLab.Models.MergeRequest.MergedAt.get -> System.DateTime?
Expand Down Expand Up @@ -3058,6 +3060,8 @@ NGitLab.Models.MergeRequestCreate.Description.get -> string
NGitLab.Models.MergeRequestCreate.Description.set -> void
NGitLab.Models.MergeRequestCreate.Labels.get -> string
NGitLab.Models.MergeRequestCreate.Labels.set -> void
NGitLab.Models.MergeRequestCreate.MergeAfter.get -> System.DateTime?
NGitLab.Models.MergeRequestCreate.MergeAfter.set -> void
NGitLab.Models.MergeRequestCreate.MergeRequestCreate() -> void
NGitLab.Models.MergeRequestCreate.MilestoneId.get -> long?
NGitLab.Models.MergeRequestCreate.MilestoneId.set -> void
Expand Down Expand Up @@ -3177,6 +3181,8 @@ NGitLab.Models.MergeRequestUpdate.Description.get -> string
NGitLab.Models.MergeRequestUpdate.Description.set -> void
NGitLab.Models.MergeRequestUpdate.Labels.get -> string
NGitLab.Models.MergeRequestUpdate.Labels.set -> void
NGitLab.Models.MergeRequestUpdate.MergeAfter.get -> System.DateTime?
NGitLab.Models.MergeRequestUpdate.MergeAfter.set -> void
NGitLab.Models.MergeRequestUpdate.MergeRequestUpdate() -> void
NGitLab.Models.MergeRequestUpdate.MilestoneId.get -> long?
NGitLab.Models.MergeRequestUpdate.MilestoneId.set -> void
Expand Down
6 changes: 6 additions & 0 deletions NGitLab/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2893,6 +2893,8 @@ NGitLab.Models.MergeRequest.Iid.get -> long
NGitLab.Models.MergeRequest.Iid.set -> void
NGitLab.Models.MergeRequest.Labels.get -> string[]
NGitLab.Models.MergeRequest.Labels.set -> void
NGitLab.Models.MergeRequest.MergeAfter.get -> System.DateTime?
NGitLab.Models.MergeRequest.MergeAfter.set -> void
NGitLab.Models.MergeRequest.MergeCommitSha.get -> string
NGitLab.Models.MergeRequest.MergeCommitSha.set -> void
NGitLab.Models.MergeRequest.MergedAt.get -> System.DateTime?
Expand Down Expand Up @@ -3059,6 +3061,8 @@ NGitLab.Models.MergeRequestCreate.Description.get -> string
NGitLab.Models.MergeRequestCreate.Description.set -> void
NGitLab.Models.MergeRequestCreate.Labels.get -> string
NGitLab.Models.MergeRequestCreate.Labels.set -> void
NGitLab.Models.MergeRequestCreate.MergeAfter.get -> System.DateTime?
NGitLab.Models.MergeRequestCreate.MergeAfter.set -> void
NGitLab.Models.MergeRequestCreate.MergeRequestCreate() -> void
NGitLab.Models.MergeRequestCreate.MilestoneId.get -> long?
NGitLab.Models.MergeRequestCreate.MilestoneId.set -> void
Expand Down Expand Up @@ -3178,6 +3182,8 @@ NGitLab.Models.MergeRequestUpdate.Description.get -> string
NGitLab.Models.MergeRequestUpdate.Description.set -> void
NGitLab.Models.MergeRequestUpdate.Labels.get -> string
NGitLab.Models.MergeRequestUpdate.Labels.set -> void
NGitLab.Models.MergeRequestUpdate.MergeAfter.get -> System.DateTime?
NGitLab.Models.MergeRequestUpdate.MergeAfter.set -> void
NGitLab.Models.MergeRequestUpdate.MergeRequestUpdate() -> void
NGitLab.Models.MergeRequestUpdate.MilestoneId.get -> long?
NGitLab.Models.MergeRequestUpdate.MilestoneId.set -> void
Expand Down
Loading