Skip to content

Commit 3d6844b

Browse files
tellespallabobCristian Ramon Garciajetersen
committed
add project variables support (#72)
* add project environment variables support * increase coverage project environment variable * initialize fields explicitely * use new projectId and fix tests Co-authored-by: Cristian Ramon Garcia <Cristian.RamonGarcia@vistaprint.com> Co-authored-by: Joseph Petersen <josephp90@gmail.com>
1 parent baa9da1 commit 3d6844b

File tree

5 files changed

+273
-0
lines changed

5 files changed

+273
-0
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using Newtonsoft.Json;
2+
3+
namespace GitLabApiClient.Models.Variables.Request
4+
{
5+
public class CreateVariableRequest
6+
{
7+
/// <summary>
8+
/// The type of a variable.
9+
/// Available types are: env_var (default) and file
10+
/// </summary>
11+
[JsonProperty("variable_type")]
12+
public string VariableType { get; set; }
13+
14+
/// <summary>
15+
/// The key of a variable
16+
/// </summary>
17+
[JsonProperty("key")]
18+
public string Key { get; set; }
19+
20+
/// <summary>
21+
/// The value of a variable
22+
/// </summary>
23+
[JsonProperty("value")]
24+
public string Value { get; set; }
25+
26+
/// <summary>
27+
/// Whether the variable is protected
28+
/// </summary>
29+
[JsonProperty("protected")]
30+
public bool? Protected { get; set; }
31+
32+
/// <summary>
33+
/// Whether the variable is masked
34+
/// </summary>
35+
[JsonProperty("masked")]
36+
public bool? Masked { get; set; }
37+
38+
/// <summary>
39+
/// The environment_scope of the variable
40+
/// </summary>
41+
[JsonProperty("environment_scope")]
42+
public string EnvironmentScope { get; set; }
43+
}
44+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using Newtonsoft.Json;
2+
3+
namespace GitLabApiClient.Models.Variables.Request
4+
{
5+
public class UpdateProjectVariableRequest
6+
{
7+
/// <summary>
8+
/// The type of a variable.
9+
/// Available types are: env_var (default) and file
10+
/// </summary>
11+
[JsonProperty("variable_type")]
12+
public string VariableType { get; set; }
13+
14+
/// <summary>
15+
/// The key of a variable
16+
/// </summary>
17+
[JsonProperty("key")]
18+
public string Key { get; set; }
19+
20+
/// <summary>
21+
/// The value of a variable
22+
/// </summary>
23+
[JsonProperty("value")]
24+
public string Value { get; set; }
25+
26+
/// <summary>
27+
/// Whether the variable is protected
28+
/// </summary>
29+
[JsonProperty("protected")]
30+
public bool? Protected { get; set; }
31+
32+
/// <summary>
33+
/// Whether the variable is masked
34+
/// </summary>
35+
[JsonProperty("masked")]
36+
public bool? Masked { get; set; }
37+
38+
/// <summary>
39+
/// The environment_scope of the variable
40+
/// </summary>
41+
[JsonProperty("environment_scope")]
42+
public string EnvironmentScope { get; set; }
43+
}
44+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using Newtonsoft.Json;
2+
3+
namespace GitLabApiClient.Models.Variables.Response
4+
{
5+
public sealed class Variable
6+
{
7+
/// <summary>
8+
/// The type of a variable.
9+
/// Available types are: env_var (default) and file
10+
/// </summary>
11+
[JsonProperty("variable_type")]
12+
public string VariableType { get; set; }
13+
14+
/// <summary>
15+
/// The key of a variable
16+
/// </summary>
17+
[JsonProperty("key")]
18+
public string Key { get; set; }
19+
20+
/// <summary>
21+
/// The value of a variable
22+
/// </summary>
23+
[JsonProperty("value")]
24+
public string Value { get; set; }
25+
26+
/// <summary>
27+
/// Whether the variable is protected
28+
/// </summary>
29+
[JsonProperty("protected")]
30+
public bool Protected { get; set; }
31+
32+
/// <summary>
33+
/// Whether the variable is masked
34+
/// </summary>
35+
[JsonProperty("masked")]
36+
public bool Masked { get; set; }
37+
38+
/// <summary>
39+
/// The environment_scope of the variable
40+
/// </summary>
41+
[JsonProperty("environment_scope")]
42+
public string EnvironmentScope { get; set; }
43+
}
44+
}

src/GitLabApiClient/ProjectsClient.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
using GitLabApiClient.Models.Projects.Requests;
1212
using GitLabApiClient.Models.Projects.Responses;
1313
using GitLabApiClient.Models.Users.Responses;
14+
using GitLabApiClient.Models.Variables.Request;
15+
using GitLabApiClient.Models.Variables.Response;
1416

1517
namespace GitLabApiClient
1618
{
@@ -60,6 +62,13 @@ public async Task<IList<Project>> GetAsync(Action<ProjectQueryOptions> options =
6062
public async Task<IList<User>> GetUsersAsync(ProjectId projectId) =>
6163
await _httpFacade.GetPagedList<User>($"projects/{projectId}/users");
6264

65+
/// <summary>
66+
/// Retrieves project variables by its id.
67+
/// </summary>
68+
/// <param name="projectId">Id of the project.</param>
69+
public async Task<IList<Variable>> GetVariablesAsync(int projectId) =>
70+
await _httpFacade.GetPagedList<Variable>($"projects/{projectId}/variables");
71+
6372
/// <summary>
6473
/// Get the labels list of a project.
6574
/// </summary>
@@ -112,6 +121,18 @@ public async Task<Label> CreateLabelAsync(ProjectId projectId, CreateProjectLabe
112121
return await _httpFacade.Post<Label>($"projects/{projectId}/labels", request);
113122
}
114123

124+
/// <summary>
125+
/// Creates new project variable.
126+
/// </summary>
127+
/// <param name="projectId">The ID, path or <see cref="Project"/> of the project.</param>
128+
/// <param name="request">Create variable request.</param>
129+
/// <returns>Newly created variable.</returns>
130+
public async Task<Variable> CreateVariableAsync(ProjectId projectId, CreateVariableRequest request)
131+
{
132+
Guard.NotNull(request, nameof(request));
133+
return await _httpFacade.Post<Variable>($"projects/{projectId}/variables", request);
134+
}
135+
115136
/// <summary>
116137
/// Creates new project milestone.
117138
/// </summary>
@@ -161,6 +182,18 @@ public async Task<Milestone> UpdateMilestoneAsync(ProjectId projectId, int miles
161182
return await _httpFacade.Put<Milestone>($"projects/{projectId}/milestones/{milestoneId}", request);
162183
}
163184

185+
/// <summary>
186+
/// Updates an existing project variable.
187+
/// </summary>
188+
/// <param name="projectId">The ID, path or <see cref="Project"/> of the project.</param>
189+
/// <param name="request">Update variable request.</param>
190+
/// <returns>Newly modified variable.</returns>
191+
public async Task<Variable> UpdateVariableAsync(ProjectId projectId, UpdateProjectVariableRequest request)
192+
{
193+
Guard.NotNull(request, nameof(request));
194+
return await _httpFacade.Put<Variable>($"projects/{projectId}/variables/{request.Key}", request);
195+
}
196+
164197
/// <summary>
165198
/// Deletes project.
166199
/// </summary>
@@ -184,6 +217,14 @@ public async Task DeleteLabelAsync(ProjectId projectId, string name) =>
184217
public async Task DeleteMilestoneAsync(ProjectId projectId, int milestoneId) =>
185218
await _httpFacade.Delete($"projects/{projectId}/milestones/{milestoneId}");
186219

220+
/// <summary>
221+
/// Deletes project variable
222+
/// </summary>
223+
/// <param name="projectId">The ID, path or <see cref="Project"/> of the project.</param>
224+
/// <param name="key">The Key ID of the variable.</param>
225+
public async Task DeleteVariableAsync(ProjectId projectId, string key) =>
226+
await _httpFacade.Delete($"projects/{projectId}/variables/{key}");
227+
187228
/// <summary>
188229
/// Archive project.
189230
/// </summary>

test/GitLabApiClient.Test/ProjectsClientTest.cs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
using System.Collections.Generic;
22
using System.IO;
3+
using System.Linq;
34
using System.Threading.Tasks;
45
using FluentAssertions;
56
using GitLabApiClient.Internal.Queries;
67
using GitLabApiClient.Models.Milestones.Requests;
78
using GitLabApiClient.Models.Milestones.Responses;
89
using GitLabApiClient.Models.Projects.Requests;
910
using GitLabApiClient.Models.Projects.Responses;
11+
using GitLabApiClient.Models.Variables.Request;
12+
using GitLabApiClient.Models.Variables.Response;
1013
using GitLabApiClient.Test.Utilities;
1114
using Xunit;
1215

@@ -18,6 +21,7 @@ public class ProjectsClientTest : IAsyncLifetime
1821
{
1922
private List<int> ProjectIdsToClean { get; } = new List<int>();
2023
private List<int> MilestoneIdsToClean { get; } = new List<int>();
24+
private List<string> VariableIdsToClean { get; } = new List<string>();
2125

2226
private readonly ProjectsClient _sut = new ProjectsClient(
2327
GitLabApiHelper.GetFacade(),
@@ -71,6 +75,37 @@ public async Task ProjectMilestonesRetrieved()
7175
m.Description == "description1");
7276
}
7377

78+
[Fact]
79+
public async Task ProjectVariablesRetrieved()
80+
{
81+
//arrange
82+
var createdVariable = await _sut.CreateVariableAsync(GitLabApiHelper.TestProjectId, new CreateVariableRequest
83+
{
84+
VariableType = "env_var",
85+
Key = "SOME_VAR_KEY_RETRIEVE",
86+
Value = "VALUE_VAR",
87+
EnvironmentScope = "*",
88+
Masked = true,
89+
Protected = true
90+
});
91+
92+
VariableIdsToClean.Add(createdVariable.Key);
93+
94+
//act
95+
var variables = await _sut.GetVariablesAsync(GitLabApiHelper.TestProjectId);
96+
var variable = variables.First(v => v.Key == createdVariable.Key);
97+
98+
//assert
99+
variables.Should().NotBeEmpty();
100+
variable.Should().Match<Variable>(v =>
101+
v.VariableType == createdVariable.VariableType &&
102+
v.Key == createdVariable.Key &&
103+
v.Value == createdVariable.Value &&
104+
v.EnvironmentScope == createdVariable.EnvironmentScope &&
105+
v.Masked == createdVariable.Masked &&
106+
v.Protected == createdVariable.Protected);
107+
}
108+
74109
[Fact]
75110
public async Task ProjectRetrievedByName()
76111
{
@@ -113,6 +148,31 @@ public async Task ProjectCreated()
113148
ProjectIdsToClean.Add(project.Id);
114149
}
115150

151+
[Fact]
152+
public async Task ProjectVariablesCreated()
153+
{
154+
var request = new CreateVariableRequest
155+
{
156+
VariableType = "env_var",
157+
Key = "SOME_VAR_KEY_CREATED",
158+
Value = "VALUE_VAR",
159+
EnvironmentScope = "*",
160+
Masked = true,
161+
Protected = true
162+
};
163+
164+
var variable = await _sut.CreateVariableAsync(GitLabApiHelper.TestProjectId, request);
165+
166+
variable.Should().Match<Variable>(v => v.VariableType == request.VariableType
167+
&& v.Key == request.Key
168+
&& v.Value == request.Value
169+
&& v.EnvironmentScope == request.EnvironmentScope
170+
&& v.Masked == request.Masked
171+
&& v.Protected == request.Protected);
172+
173+
VariableIdsToClean.Add(request.Key);
174+
}
175+
116176
[Fact]
117177
public async Task CreatedProjectCanBeUpdated()
118178
{
@@ -219,6 +279,43 @@ public async Task CreatedProjectMilestoneCanBeUpdated()
219279
m.Description == "description22");
220280
}
221281

282+
[Fact]
283+
public async Task ProjectVariableCanBeUpdated()
284+
{
285+
var request = new CreateVariableRequest
286+
{
287+
VariableType = "env_var",
288+
Key = "SOME_VAR_KEY_TO_UPDATE",
289+
Value = "VALUE_VAR",
290+
EnvironmentScope = "*",
291+
Masked = true,
292+
Protected = true
293+
};
294+
295+
var variable = await _sut.CreateVariableAsync(GitLabApiHelper.TestProjectId, request);
296+
297+
VariableIdsToClean.Add(request.Key);
298+
299+
var updateRequest = new UpdateProjectVariableRequest
300+
{
301+
VariableType = "file",
302+
Key = request.Key,
303+
Value = "UpdatedValue",
304+
EnvironmentScope = "*",
305+
Masked = request.Masked,
306+
Protected = request.Protected,
307+
};
308+
309+
var variableUpdated = await _sut.UpdateVariableAsync(GitLabApiHelper.TestProjectId, updateRequest);
310+
311+
variableUpdated.Should().Match<Variable>(v => v.VariableType == updateRequest.VariableType
312+
&& v.Key == updateRequest.Key
313+
&& v.Value == updateRequest.Value
314+
&& v.EnvironmentScope == updateRequest.EnvironmentScope
315+
&& v.Masked == updateRequest.Masked
316+
&& v.Protected == updateRequest.Protected);
317+
}
318+
222319
[Fact]
223320
public async Task CreatedProjectMilestoneCanBeClosed()
224321
{
@@ -253,6 +350,9 @@ private async Task CleanupProjects()
253350

254351
foreach (int projectId in ProjectIdsToClean)
255352
await _sut.DeleteAsync(projectId);
353+
354+
foreach (string variableId in VariableIdsToClean)
355+
await _sut.DeleteVariableAsync(GitLabApiHelper.TestProjectId, variableId);
256356
}
257357

258358
private static string GetRandomProjectName() => "test-gitlabapiclient" + Path.GetRandomFileName();

0 commit comments

Comments
 (0)