Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee39e29269 | ||
|
|
d6c7792a6c | ||
|
|
c92e6f5ee9 | ||
|
|
8d56dbf2b3 | ||
|
|
1d127cadd3 | ||
|
|
97e81c3af4 | ||
|
|
071aa73015 |
@@ -4,6 +4,8 @@ name: Create and publish a Docker image
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds.
|
||||
env:
|
||||
|
||||
+41
-12
@@ -23,11 +23,6 @@ public class App : IApp
|
||||
ServerCertificateCustomValidationCallback = (_, _, _, _) => true
|
||||
};
|
||||
_settings = new Settings();
|
||||
if (string.IsNullOrEmpty(_settings.GitlabUrl))
|
||||
{
|
||||
Console.WriteLine("CI_SERVER_URL is not defined.");
|
||||
return;
|
||||
}
|
||||
_client = new GitLabClient(_settings.GitlabUrl, _settings.GitlabToken, httpHandler);
|
||||
_customClient = new GitlabCustomClient(_settings.GitlabUrl, _settings.GitlabToken, httpHandler);
|
||||
}
|
||||
@@ -44,11 +39,37 @@ public class App : IApp
|
||||
Console.WriteLine("Not in MergeRequest. Exiting.");
|
||||
return 0;
|
||||
}
|
||||
var approversDict = ParseApprovers();
|
||||
if (approversDict is null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
var mrId = int.Parse(_settings.MrPath.Split('!')[1]);
|
||||
|
||||
var mergeRequest = await _client.MergeRequests.GetAsync(_settings.ProjectId, mrId);
|
||||
var commit = await _client.Commits.GetAsync(_settings.ProjectId, mergeRequest.Sha);
|
||||
if (!await IsApproved(mergeRequest, commit))
|
||||
|
||||
var mrsToSameRelease = await _customClient.GetMergeRequestsByTargetBranch(mergeRequest.TargetBranch);
|
||||
var sameMrs = mrsToSameRelease.Where(f => f.SourceBranch == mergeRequest.SourceBranch &&
|
||||
f.TargetBranch == mergeRequest.TargetBranch &&
|
||||
f.State == MergeRequestState.Merged).ToArray();
|
||||
if (sameMrs.Any())
|
||||
{
|
||||
var mrUrls = string.Join("\r\n", sameMrs.Select(f=>f.WebUrl));
|
||||
var message = $"Аналогичный MR ({sameMrs.First().WebUrl}) уже был одобрен и влит, автоматически одобряю текущий:\r\n{mrUrls}";
|
||||
|
||||
await _client.MergeRequests.CreateNoteAsync(mergeRequest.ProjectId, mergeRequest.Iid,
|
||||
new CreateMergeRequestNoteRequest(message));
|
||||
return 0;
|
||||
}
|
||||
|
||||
var isCodeFreezePeriod = _settings.ReleaseCodeFreeze != "true";
|
||||
var periodDescription = isCodeFreezePeriod ? "Code-Freeze. Restrictions may apply" : "Normal";
|
||||
Console.WriteLine($"Current period is {periodDescription}.");
|
||||
|
||||
approversDict = FilterApprovers(approversDict, isCodeFreezePeriod);
|
||||
if (!await IsApproved(mergeRequest, commit, approversDict))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
@@ -56,13 +77,8 @@ public class App : IApp
|
||||
return 0;
|
||||
}
|
||||
|
||||
private async Task<bool> IsApproved(MergeRequest mergeRequest, Commit commit)
|
||||
private async Task<bool> IsApproved(MergeRequest mergeRequest, Commit commit, Dictionary<string, ApproversDto> approversDict)
|
||||
{
|
||||
var approversDict = ParseApprovers();
|
||||
if (approversDict is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
var emojis = await _client.MergeRequests.GetAwardEmojisAsync(_settings.ProjectId, mergeRequest.Iid);
|
||||
|
||||
var sb = new StringBuilder();
|
||||
@@ -130,4 +146,17 @@ public class App : IApp
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<string, ApproversDto> FilterApprovers(Dictionary<string, ApproversDto> approvers, bool isCodeFreezePeriod)
|
||||
{
|
||||
var result = new Dictionary<string, ApproversDto>();
|
||||
foreach (var approversDto in approvers)
|
||||
{
|
||||
if (approversDto.Value.ForCodeFreeze == isCodeFreezePeriod)
|
||||
{
|
||||
result.Add(approversDto.Key, approversDto.Value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ namespace Approve.Checker.Gitlab;
|
||||
|
||||
public class ApproversDto
|
||||
{
|
||||
public bool? ForCodeFreeze { get; set; }
|
||||
public int CountApprovers { get; set; } = 1;
|
||||
public List<string> Users { get; set; }
|
||||
public List<string> Users { get; set; } = new();
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
using GitLabApiClient.Models.Issues.Responses;
|
||||
using GitLabApiClient.Models.MergeRequests.Responses;
|
||||
using GitLabApiClient.Models.Milestones.Responses;
|
||||
using GitLabApiClient.Models.Pipelines.Responses;
|
||||
using GitLabApiClient.Models;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
#pragma warning disable CS8618
|
||||
|
||||
namespace Approve.Checker.Gitlab.Dto
|
||||
{
|
||||
public sealed class CustomMergeRequest
|
||||
{
|
||||
[JsonProperty("iid")]
|
||||
public int Iid { get; set; }
|
||||
|
||||
[JsonProperty("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
[JsonProperty("created_at")]
|
||||
public DateTime CreatedAt { get; set; }
|
||||
|
||||
[JsonProperty("updated_at")]
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
|
||||
[JsonProperty("labels")]
|
||||
public List<string> Labels { get; } = new List<string>();
|
||||
|
||||
[JsonProperty("source_branch")]
|
||||
public string SourceBranch { get; set; }
|
||||
|
||||
[JsonProperty("downvotes")]
|
||||
public int Downvotes { get; set; }
|
||||
|
||||
[JsonProperty("author")]
|
||||
public Assignee Author { get; set; }
|
||||
|
||||
[JsonProperty("assignee")]
|
||||
public Assignee Assignee { get; set; }
|
||||
|
||||
[JsonProperty("description")]
|
||||
public string Description { get; set; }
|
||||
|
||||
[JsonProperty("force_remove_source_branch")]
|
||||
public bool? ForceRemoveSourceBranch { get; set; }
|
||||
|
||||
[JsonProperty("milestone")]
|
||||
public Milestone Milestone { get; set; }
|
||||
|
||||
[JsonProperty("merge_status")]
|
||||
public MergeStatus Status { get; set; }
|
||||
|
||||
[JsonProperty("merge_commit_sha")]
|
||||
public string MergeCommitSha { get; set; }
|
||||
|
||||
[JsonProperty("merge_when_pipeline_succeeds")]
|
||||
public bool MergeWhenPipelineSucceeds { get; set; }
|
||||
|
||||
[JsonProperty("sha")]
|
||||
public string Sha { get; set; }
|
||||
|
||||
[JsonProperty("project_id")]
|
||||
public string ProjectId { get; set; }
|
||||
|
||||
[JsonProperty("should_remove_source_branch")]
|
||||
public bool? ShouldRemoveSourceBranch { get; set; }
|
||||
|
||||
[JsonProperty("target_project_id")]
|
||||
public int TargetProjectId { get; set; }
|
||||
|
||||
[JsonProperty("state")]
|
||||
public MergeRequestState State { get; set; }
|
||||
|
||||
[JsonProperty("source_project_id")]
|
||||
public int SourceProjectId { get; set; }
|
||||
|
||||
[JsonProperty("closed_at")]
|
||||
public DateTime? ClosedAt { get; set; }
|
||||
|
||||
[JsonProperty("closed_by")]
|
||||
public ClosedBy ClosedBy { get; set; }
|
||||
|
||||
[JsonProperty("target_branch")]
|
||||
public string TargetBranch { get; set; }
|
||||
|
||||
[JsonProperty("upvotes")]
|
||||
public int Upvotes { get; set; }
|
||||
|
||||
[JsonProperty("web_url")]
|
||||
public string WebUrl { get; set; }
|
||||
|
||||
[JsonProperty("title")]
|
||||
public string Title { get; set; }
|
||||
|
||||
[JsonProperty("user_notes_count")]
|
||||
public int UserNotesCount { get; set; }
|
||||
|
||||
[JsonProperty("work_in_progress")]
|
||||
public bool WorkInProgress { get; set; }
|
||||
|
||||
[JsonProperty("time_stats")]
|
||||
public MergeRequestTimeStatistic TimeStats { get; set; }
|
||||
|
||||
[JsonProperty("pipeline")]
|
||||
public Pipeline Pipeline { get; set; }
|
||||
|
||||
[JsonProperty("merged_by")]
|
||||
public Assignee MergedBy { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Net.Http.Json;
|
||||
using System.Text;
|
||||
using Approve.Checker.Gitlab.Dto;
|
||||
using GitLabApiClient.Models.Job.Responses;
|
||||
using GitLabApiClient.Models.MergeRequests.Responses;
|
||||
using Newtonsoft.Json;
|
||||
@@ -54,7 +55,7 @@ public class GitlabCustomClient : IGitlabCustomClient
|
||||
return responseObj!;
|
||||
}
|
||||
|
||||
public async Task<MergeRequest[]> GetMergeRequestsByTargetBranch(string targetBranch)
|
||||
public async Task<CustomMergeRequest[]> GetMergeRequestsByTargetBranch(string targetBranch)
|
||||
{
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, $"{_url}/api/v4/merge_requests?target_branch={targetBranch}&scope=all&per_page=1000");
|
||||
request.Headers.Add("PRIVATE-TOKEN", _token);
|
||||
@@ -62,7 +63,7 @@ public class GitlabCustomClient : IGitlabCustomClient
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
var responseStr = await response.Content.ReadAsStringAsync();
|
||||
var responseObj = JsonConvert.DeserializeObject<MergeRequest[]>(responseStr)!;
|
||||
var responseObj = JsonConvert.DeserializeObject<CustomMergeRequest[]>(responseStr)!;
|
||||
return responseObj;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using GitLabApiClient.Models.Job.Responses;
|
||||
using Approve.Checker.Gitlab.Dto;
|
||||
using GitLabApiClient.Models.Job.Responses;
|
||||
using GitLabApiClient.Models.MergeRequests.Responses;
|
||||
using ReleaseScripts.ExternalSystems.Gitlab.CustomClient.Dto;
|
||||
using ReleaseScripts.ExternalSystems.Gitlab.CustomClient.Dto.ApprovalState;
|
||||
@@ -10,7 +11,7 @@ public interface IGitlabCustomClient
|
||||
Task<Reviewers[]> GetReviewers(string projectId, int Iid);
|
||||
Task<ApprovalStateResponse> GetApprovals(string projectId, int Iid);
|
||||
Task<ApprovalStateResponse> GetDiscussions(string projectId, int Iid);
|
||||
Task<MergeRequest[]> GetMergeRequestsByTargetBranch(string targetBranch);
|
||||
Task<CustomMergeRequest[]> GetMergeRequestsByTargetBranch(string targetBranch);
|
||||
Task<Job[]> GetPipelineTriggers(string projectId, int pipelineId);
|
||||
Task RestartJob(string projectId, int failedJobId);
|
||||
Task<MergeRequest[]> GetMergeRequestsBySourceBranch(string targetBranch);
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Approve.Checker.Gitlab
|
||||
namespace Approve.Checker.Gitlab
|
||||
{
|
||||
public class Settings
|
||||
{
|
||||
@@ -13,6 +7,7 @@ namespace Approve.Checker.Gitlab
|
||||
public string MrPath = Environment.GetEnvironmentVariable("CI_OPEN_MERGE_REQUESTS")!;
|
||||
public string ProjectId = Environment.GetEnvironmentVariable("CI_PROJECT_ID") ?? CheckAndThrow("CI_PROJECT_ID");
|
||||
public string Approvers = Environment.GetEnvironmentVariable("APPROVERS_FILEPATH") ?? CheckAndThrow("APPROVERS_FILEPATH");
|
||||
public string ReleaseCodeFreeze = Environment.GetEnvironmentVariable("RELEASE_CODEFREEZE") ?? "false";
|
||||
|
||||
private static string CheckAndThrow(string name)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user