Skip to content

Commit 63c1b98

Browse files
author
Calin Lupas
authored
Merge pull request #45 from DevExcelerate/feature/update-repo
Feature/update repo
2 parents 65e1b0d + 72c0cd8 commit 63c1b98

10 files changed

Lines changed: 350 additions & 61 deletions

src/DevExcelerateApi/Core/Extensions/GitHubClientExtensions.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,15 @@ public static async Task<PullRequest> CreatePullRequestAsync(this IGitHubClient
172172

173173
if (pullRequests.Any())
174174
{
175-
// If a pull request already exists, return the first one
176-
return pullRequests[0];
175+
// If a pull request already exists, update its title and body
176+
var existingPr = pullRequests[0];
177+
var update = new PullRequestUpdate
178+
{
179+
Title = title,
180+
Body = body
181+
};
182+
var updatedPr = await gitHubClient.PullRequest.Update(owner, repo, existingPr.Number, update);
183+
return updatedPr;
177184
}
178185

179186
// Step 2: Create a new pull request if none exists

src/DevExcelerateApi/Models/Constants.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,16 @@ public static class Constants
1212
public const string GitHubDefaultBranch = "main";
1313
public const string GitHubPullRequestTitleIssueNumber = "Issue#";
1414

15-
// Constants for the different types of messages that can be sent
16-
15+
// Constants for the different types of messages that can be sent
16+
1717
// Repository related constants
1818
public const string ERROR_REPO_CREATION = "ERROR_REPO_CREATION";
1919
public const string ERROR_REPO_EXISTS = "ERROR_REPO_EXISTS";
2020
public const string ERROR_REPO_TEAM_DOES_NOT_EXISTS = "ERROR_REPO_TEAM_DOES_NOT_EXISTS";
2121
public const string ERROR_REPO_RULESET_DOES_NOT_EXISTS = "ERROR_REPO_RULESET_DOES_NOT_EXISTS";
2222
public const string ERROR_INVAILD_REPO_NAME = "ERROR_INVAILD_REPO_NAME";
23+
public const string ERROR_REPO_DOES_NOT_EXIST = "ERROR_REPO_DOES_NOT_EXIST";
24+
public const string ERROR_USER_NOT_REPO_MAINTAINER = "ERROR_USER_NOT_REPO_MAINTAINER";
2325

2426
// Repository PR related constants
2527
public const string ERROR_PR_CREATION = "ERROR_PR_CREATION";

src/DevExcelerateApi/Models/RepositoryRequestModel.cs

Lines changed: 107 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@ namespace DevExcelerateApi.Models
66
{
77
public class RepositoryRequestModel : DevExIssueRequestModel
88
{
9-
[YamlMember(Alias = "owner", Order = 10)]
9+
[YamlMember(Alias = "owner", Order = 9)]
1010
public string? RepositoryOwner { get; set; } // will be inherited from issue
1111

12-
[YamlMember(Alias = "repository_name", Order = 11)]
12+
[YamlMember(Alias = "repository_name", Order = 10)]
1313
public string? RepositoryName { get; set; }
1414

15+
[YamlMember(Alias = "new_repository_name", Order = 11)]
16+
public string? NewRepositoryName { get; set; }
17+
1518
[YamlMember(Alias = "visibility", Order = 12)]
1619
public string? RepositoryVisibility { get; set; }
1720

@@ -42,42 +45,53 @@ public class RepositoryRequestModel : DevExIssueRequestModel
4245
[YamlMember(Alias = "contributors", Order = 18)]
4346
public List<string>? ContributorList { get; set; }
4447

48+
[YamlIgnore]
49+
public string? RemoveRepositoryMembers { get; set; }
50+
51+
[YamlMember(Alias = "remove_members", Order = 19)]
52+
public List<string>? RemoveMemberList { get; set; }
53+
4554
[YamlIgnore]
4655
public string? RepositoryRulesets { get; set; }
4756

48-
[YamlMember(Alias = "rulesets", Order = 19)]
57+
[YamlMember(Alias = "rulesets", Order = 20)]
4958
public List<string>? RulesetList { get; set; }
5059

5160
public static new RepositoryRequestModel Parse(IDictionary<string, object?> values)
5261
{
5362
ArgumentNullException.ThrowIfNull(values);
5463

5564
values.TryGetValue("repository_name", out var repositoryName);
65+
values.TryGetValue("new_repository_name", out var newRepositoryName);
5666
values.TryGetValue("repository_visibility", out var repositoryVisibility);
5767
values.TryGetValue("repository_classification", out var repositoryClassification);
5868
values.TryGetValue("repository_description", out var repositoryDescription);
5969
values.TryGetValue("repository_maintainers", out var repositoryMaintainers);
6070
values.TryGetValue("repository_readers", out var repositoryReaders);
6171
values.TryGetValue("repository_contributors", out var repositoryContributors);
6272
values.TryGetValue("repository_rulesets", out var repositoryRulesets);
73+
values.TryGetValue("remove_repository_members", out var removeRepositoryMembers);
6374

6475
if (repositoryName == null)
6576
{
6677
// Fallback to the localized string if the default key is not found
6778
values.TryGetValue(LocalizationExtensions.GetLocalizedString("repository_name"), out repositoryName);
79+
values.TryGetValue(LocalizationExtensions.GetLocalizedString("new_repository_name"), out newRepositoryName);
6880
values.TryGetValue(LocalizationExtensions.GetLocalizedString("repository_visibility"), out repositoryVisibility);
6981
values.TryGetValue(LocalizationExtensions.GetLocalizedString("repository_classification"), out repositoryClassification);
7082
values.TryGetValue(LocalizationExtensions.GetLocalizedString("repository_description"), out repositoryDescription);
7183
values.TryGetValue(LocalizationExtensions.GetLocalizedString("repository_maintainers"), out repositoryMaintainers);
7284
values.TryGetValue(LocalizationExtensions.GetLocalizedString("repository_readers"), out repositoryReaders);
7385
values.TryGetValue(LocalizationExtensions.GetLocalizedString("repository_contributors"), out repositoryContributors);
7486
values.TryGetValue(LocalizationExtensions.GetLocalizedString("repository_rulesets"), out repositoryRulesets);
87+
values.TryGetValue(LocalizationExtensions.GetLocalizedString("remove_repository_members"), out removeRepositoryMembers);
7588
}
7689

7790
return new RepositoryRequestModel
7891
{
7992
RequestType = DevExIssueRequestModel.Parse(values).RequestType,
8093
RepositoryName = repositoryName?.ToString()?.SanitizeResourceName(),
94+
NewRepositoryName = newRepositoryName?.ToString()?.SanitizeResourceName(),
8195
RepositoryVisibility = repositoryVisibility?.ToString(),
8296
RepositoryClassification = repositoryClassification?.ToString(),
8397
RepositoryDescription = repositoryDescription?.ToString(),
@@ -87,21 +101,44 @@ public class RepositoryRequestModel : DevExIssueRequestModel
87101
ReaderList = repositoryReaders?.ToString().ConvertCsvToList(),
88102
RepositoryContributors = repositoryContributors?.ToString(),
89103
ContributorList = repositoryContributors?.ToString().ConvertCsvToList(),
104+
RemoveRepositoryMembers = removeRepositoryMembers?.ToString(),
105+
RemoveMemberList = removeRepositoryMembers?.ToString().ConvertCsvToList(),
90106
RepositoryRulesets = repositoryRulesets?.ToString(),
91107
RulesetList = repositoryRulesets?.ToString().ConvertCsvToList()
92108
};
93109
}
94110

95-
public bool IsValid()
111+
public bool IsValid => IsValidCreate() || IsValidUpdate();
112+
113+
public bool IsValidCreate()
96114
{
97-
return !string.IsNullOrEmpty(RepositoryName) &&
115+
return RequestType == RequestType.CREATE_REPOSITORY &&
116+
!string.IsNullOrEmpty(RepositoryName) &&
98117
!string.IsNullOrEmpty(RepositoryVisibility) &&
99118
!string.IsNullOrEmpty(RepositoryClassification) &&
100119
!string.IsNullOrEmpty(RepositoryDescription) &&
101120
ContributorList?.Count > 0 &&
102121
RulesetList?.Count > 0;
103122
}
104123

124+
public bool IsValidUpdate()
125+
{
126+
return RequestType == RequestType.UPDATE_REPOSITORY &&
127+
!string.IsNullOrEmpty(RepositoryName) &&
128+
// At least one change
129+
(
130+
!string.IsNullOrEmpty(NewRepositoryName) ||
131+
!string.IsNullOrEmpty(RepositoryDescription) ||
132+
!string.IsNullOrEmpty(RepositoryVisibility) ||
133+
!string.IsNullOrEmpty(RepositoryClassification) ||
134+
!string.IsNullOrEmpty(RepositoryMaintainers) ||
135+
!string.IsNullOrEmpty(RepositoryReaders) ||
136+
!string.IsNullOrEmpty(RepositoryContributors) ||
137+
!string.IsNullOrEmpty(RemoveRepositoryMembers) ||
138+
!string.IsNullOrEmpty(RepositoryRulesets)
139+
);
140+
}
141+
105142
public string SerializeToYaml()
106143
{
107144
return YamlHelpers.Serialize(this);
@@ -112,5 +149,70 @@ public static RepositoryRequestModel DeserializeFromYaml(string yamlContent)
112149
ArgumentNullException.ThrowIfNull(yamlContent);
113150
return YamlHelpers.Deserialize<RepositoryRequestModel>(yamlContent);
114151
}
152+
153+
public void Update(RepositoryRequestModel model)
154+
{
155+
if (string.IsNullOrEmpty(RepositoryDescription)) RepositoryDescription = model.RepositoryDescription;
156+
if (string.IsNullOrEmpty(RepositoryVisibility)) RepositoryVisibility = model.RepositoryVisibility;
157+
if (string.IsNullOrEmpty(RepositoryClassification)) RepositoryClassification = model.RepositoryClassification;
158+
159+
if (MaintainerList == null || MaintainerList.Count == 0)
160+
{
161+
MaintainerList = model.MaintainerList ?? [];
162+
}
163+
else
164+
{
165+
MaintainerList.AddRange(model.MaintainerList ?? []);
166+
}
167+
168+
if (ReaderList == null || ReaderList.Count == 0)
169+
{
170+
ReaderList = model.ReaderList ?? [];
171+
}
172+
else
173+
{
174+
ReaderList.AddRange(model.ReaderList ?? []);
175+
}
176+
177+
if (ContributorList == null || ContributorList.Count == 0)
178+
{
179+
ContributorList = model.ContributorList ?? [];
180+
}
181+
else
182+
{
183+
ContributorList.AddRange(model.ContributorList ?? []);
184+
}
185+
186+
if (RemoveMemberList?.Count > 0)
187+
{
188+
foreach (var member in RemoveMemberList)
189+
{
190+
if (MaintainerList?.Contains(member) == true)
191+
{
192+
MaintainerList.Remove(member);
193+
}
194+
195+
if (ReaderList?.Contains(member) == true)
196+
{
197+
ReaderList.Remove(member);
198+
}
199+
200+
if (ContributorList?.Contains(member) == true)
201+
{
202+
ContributorList.Remove(member);
203+
}
204+
}
205+
}
206+
207+
if (RulesetList == null || RulesetList.Count == 0)
208+
{
209+
RulesetList = model.RulesetList ?? [];
210+
}
211+
212+
MaintainerList = MaintainerList?.Distinct().ToList();
213+
ReaderList = ReaderList?.Distinct().ToList();
214+
ContributorList = ContributorList?.Distinct().ToList();
215+
RulesetList = RulesetList?.Distinct().ToList();
216+
}
115217
}
116218
}

src/DevExcelerateApi/Parsers/GitHubIssueFormParser.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public static ParsedBody ParseIssue(string? issue)
5656
public static bool IsEmptyResponse(string value)
5757
{
5858
return string.Equals(value, "_None_", StringComparison.OrdinalIgnoreCase) ||
59+
string.Equals(value, "None", StringComparison.Ordinal) ||
5960
string.Equals(value, "_No response_", StringComparison.OrdinalIgnoreCase) ||
6061
string.IsNullOrEmpty(value);
6162
}

src/DevExcelerateApi/Resources/Services.LocalizationService.fr.resx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,12 @@
153153
<data name="ERROR_REPO_TEAM_DOES_NOT_EXISTS" xml:space="preserve">
154154
<value>L'équipe ou le membre '{0}' n'existe pas.</value>
155155
</data>
156+
<data name="ERROR_REPO_DOES_NOT_EXIST" xml:space="preserve">
157+
<value>Le dépôt '{0}' n'existe pas.</value>
158+
</data>
159+
<data name="ERROR_USER_NOT_REPO_MAINTAINER" xml:space="preserve">
160+
<value>Seuls les responsables désignés du dépôt sont autorisés à mettre à jour le dépôt '{1}'. L'utilisateur '{0}' n'est pas un responsable.</value>
161+
</data>
156162
<data name="APPROVED" xml:space="preserve">
157163
<value>Approuvé</value>
158164
</data>
@@ -262,7 +268,7 @@
262268
<value>description_du_dépôt</value>
263269
</data>
264270
<data name="repository_maintainers" xml:space="preserve">
265-
<value>responsables_du_dépôt</value>
271+
<value>mainteneurs_du_dépôt</value>
266272
</data>
267273
<data name="repository_readers" xml:space="preserve">
268274
<value>lecteurs_du_dépôt</value>
@@ -282,4 +288,10 @@
282288
<data name="Private" xml:space="preserve">
283289
<value>Privé</value>
284290
</data>
291+
<data name="new_repository_name" xml:space="preserve">
292+
<value>nouveau_nom_du_dépôt</value>
293+
</data>
294+
<data name="remove_repository_members" xml:space="preserve">
295+
<value>retirer_des_membres_du_dépôt</value>
296+
</data>
285297
</root>

src/DevExcelerateApi/Resources/Services.LocalizationService.resx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,15 @@
149149
</data>
150150
<data name="ERROR_REPO_RULESET_DOES_NOT_EXISTS" xml:space="preserve">
151151
<value>The '{0}' ruleset does not exist. </value>
152-
</data>
153-
<data name="ERROR_REPO_TEAM_DOES_NOT_EXISTS" xml:space="preserve">
152+
</data> <data name="ERROR_REPO_TEAM_DOES_NOT_EXISTS" xml:space="preserve">
154153
<value>The '{0}' team or member does not exist.</value>
155154
</data>
155+
<data name="ERROR_REPO_DOES_NOT_EXIST" xml:space="preserve">
156+
<value>The repository '{0}' does not exist.</value>
157+
</data>
158+
<data name="ERROR_USER_NOT_REPO_MAINTAINER" xml:space="preserve">
159+
<value>Only designated repository maintainers have permission to update repository '{1}'. User '{0}' is not a maintainer.</value>
160+
</data>
156161
<data name="APPROVED" xml:space="preserve">
157162
<value>Approved</value>
158163
</data>
@@ -282,4 +287,10 @@
282287
<data name="Private" xml:space="preserve">
283288
<value>Private</value>
284289
</data>
290+
<data name="new_repository_name" xml:space="preserve">
291+
<value>new_repository_name</value>
292+
</data>
293+
<data name="remove_repository_members" xml:space="preserve">
294+
<value>remove_repository_members</value>
295+
</data>
285296
</root>

src/DevExcelerateApi/Services/DevExIssuesEventProcessorService.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ private async Task ValidateIssue(IssuesEvent issuesEvent)
126126
switch (type.RequestType)
127127
{
128128
case RequestType.CREATE_REPOSITORY:
129+
case RequestType.UPDATE_REPOSITORY:
129130
// Check ticket status => From Approved to Validated or Failed
130131
// From Failed -> Validated (if action = edited)
131132
if (

src/DevExcelerateApi/Services/DevExPullRequestEventProcessorService.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@ private async Task ValidatePullRequestApproval(PullRequestEvent pullRequestEvent
5858
// Determine the request type from the PR title
5959
var prTitle = pullRequestEvent?.PullRequest.Title;
6060

61-
if (prTitle != null && prTitle.StartsWith(RequestType.CREATE_REPOSITORY.ToString(), StringComparison.OrdinalIgnoreCase))
61+
if (prTitle != null &&
62+
( prTitle.StartsWith(RequestType.CREATE_REPOSITORY.ToString(), StringComparison.OrdinalIgnoreCase)
63+
|| prTitle.StartsWith(RequestType.UPDATE_REPOSITORY.ToString(), StringComparison.OrdinalIgnoreCase)
64+
))
6265
{
6366
await _repositoryService.SaveRepository(pullRequestEvent!);
6467
}

0 commit comments

Comments
 (0)