Skip to content

Commit

Permalink
add project variables support (#72)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>
Co-authored-by: Joseph Petersen <[email protected]>
  • Loading branch information
3 people committed Oct 22, 2019
1 parent baa9da1 commit 3d6844b
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using Newtonsoft.Json;

namespace GitLabApiClient.Models.Variables.Request
{
public class CreateVariableRequest
{
/// <summary>
/// The type of a variable.
/// Available types are: env_var (default) and file
/// </summary>
[JsonProperty("variable_type")]
public string VariableType { get; set; }

/// <summary>
/// The key of a variable
/// </summary>
[JsonProperty("key")]
public string Key { get; set; }

/// <summary>
/// The value of a variable
/// </summary>
[JsonProperty("value")]
public string Value { get; set; }

/// <summary>
/// Whether the variable is protected
/// </summary>
[JsonProperty("protected")]
public bool? Protected { get; set; }

/// <summary>
/// Whether the variable is masked
/// </summary>
[JsonProperty("masked")]
public bool? Masked { get; set; }

/// <summary>
/// The environment_scope of the variable
/// </summary>
[JsonProperty("environment_scope")]
public string EnvironmentScope { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using Newtonsoft.Json;

namespace GitLabApiClient.Models.Variables.Request
{
public class UpdateProjectVariableRequest
{
/// <summary>
/// The type of a variable.
/// Available types are: env_var (default) and file
/// </summary>
[JsonProperty("variable_type")]
public string VariableType { get; set; }

/// <summary>
/// The key of a variable
/// </summary>
[JsonProperty("key")]
public string Key { get; set; }

/// <summary>
/// The value of a variable
/// </summary>
[JsonProperty("value")]
public string Value { get; set; }

/// <summary>
/// Whether the variable is protected
/// </summary>
[JsonProperty("protected")]
public bool? Protected { get; set; }

/// <summary>
/// Whether the variable is masked
/// </summary>
[JsonProperty("masked")]
public bool? Masked { get; set; }

/// <summary>
/// The environment_scope of the variable
/// </summary>
[JsonProperty("environment_scope")]
public string EnvironmentScope { get; set; }
}
}
44 changes: 44 additions & 0 deletions src/GitLabApiClient/Models/Variables/Response/Variable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using Newtonsoft.Json;

namespace GitLabApiClient.Models.Variables.Response
{
public sealed class Variable
{
/// <summary>
/// The type of a variable.
/// Available types are: env_var (default) and file
/// </summary>
[JsonProperty("variable_type")]
public string VariableType { get; set; }

/// <summary>
/// The key of a variable
/// </summary>
[JsonProperty("key")]
public string Key { get; set; }

/// <summary>
/// The value of a variable
/// </summary>
[JsonProperty("value")]
public string Value { get; set; }

/// <summary>
/// Whether the variable is protected
/// </summary>
[JsonProperty("protected")]
public bool Protected { get; set; }

/// <summary>
/// Whether the variable is masked
/// </summary>
[JsonProperty("masked")]
public bool Masked { get; set; }

/// <summary>
/// The environment_scope of the variable
/// </summary>
[JsonProperty("environment_scope")]
public string EnvironmentScope { get; set; }
}
}
41 changes: 41 additions & 0 deletions src/GitLabApiClient/ProjectsClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
using GitLabApiClient.Models.Projects.Requests;
using GitLabApiClient.Models.Projects.Responses;
using GitLabApiClient.Models.Users.Responses;
using GitLabApiClient.Models.Variables.Request;
using GitLabApiClient.Models.Variables.Response;

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

/// <summary>
/// Retrieves project variables by its id.
/// </summary>
/// <param name="projectId">Id of the project.</param>
public async Task<IList<Variable>> GetVariablesAsync(int projectId) =>
await _httpFacade.GetPagedList<Variable>($"projects/{projectId}/variables");

/// <summary>
/// Get the labels list of a project.
/// </summary>
Expand Down Expand Up @@ -112,6 +121,18 @@ public async Task<Label> CreateLabelAsync(ProjectId projectId, CreateProjectLabe
return await _httpFacade.Post<Label>($"projects/{projectId}/labels", request);
}

/// <summary>
/// Creates new project variable.
/// </summary>
/// <param name="projectId">The ID, path or <see cref="Project"/> of the project.</param>
/// <param name="request">Create variable request.</param>
/// <returns>Newly created variable.</returns>
public async Task<Variable> CreateVariableAsync(ProjectId projectId, CreateVariableRequest request)
{
Guard.NotNull(request, nameof(request));
return await _httpFacade.Post<Variable>($"projects/{projectId}/variables", request);
}

/// <summary>
/// Creates new project milestone.
/// </summary>
Expand Down Expand Up @@ -161,6 +182,18 @@ public async Task<Milestone> UpdateMilestoneAsync(ProjectId projectId, int miles
return await _httpFacade.Put<Milestone>($"projects/{projectId}/milestones/{milestoneId}", request);
}

/// <summary>
/// Updates an existing project variable.
/// </summary>
/// <param name="projectId">The ID, path or <see cref="Project"/> of the project.</param>
/// <param name="request">Update variable request.</param>
/// <returns>Newly modified variable.</returns>
public async Task<Variable> UpdateVariableAsync(ProjectId projectId, UpdateProjectVariableRequest request)
{
Guard.NotNull(request, nameof(request));
return await _httpFacade.Put<Variable>($"projects/{projectId}/variables/{request.Key}", request);
}

/// <summary>
/// Deletes project.
/// </summary>
Expand All @@ -184,6 +217,14 @@ public async Task DeleteLabelAsync(ProjectId projectId, string name) =>
public async Task DeleteMilestoneAsync(ProjectId projectId, int milestoneId) =>
await _httpFacade.Delete($"projects/{projectId}/milestones/{milestoneId}");

/// <summary>
/// Deletes project variable
/// </summary>
/// <param name="projectId">The ID, path or <see cref="Project"/> of the project.</param>
/// <param name="key">The Key ID of the variable.</param>
public async Task DeleteVariableAsync(ProjectId projectId, string key) =>
await _httpFacade.Delete($"projects/{projectId}/variables/{key}");

/// <summary>
/// Archive project.
/// </summary>
Expand Down
100 changes: 100 additions & 0 deletions test/GitLabApiClient.Test/ProjectsClientTest.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using FluentAssertions;
using GitLabApiClient.Internal.Queries;
using GitLabApiClient.Models.Milestones.Requests;
using GitLabApiClient.Models.Milestones.Responses;
using GitLabApiClient.Models.Projects.Requests;
using GitLabApiClient.Models.Projects.Responses;
using GitLabApiClient.Models.Variables.Request;
using GitLabApiClient.Models.Variables.Response;
using GitLabApiClient.Test.Utilities;
using Xunit;

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

private readonly ProjectsClient _sut = new ProjectsClient(
GitLabApiHelper.GetFacade(),
Expand Down Expand Up @@ -71,6 +75,37 @@ public async Task ProjectMilestonesRetrieved()
m.Description == "description1");
}

[Fact]
public async Task ProjectVariablesRetrieved()
{
//arrange
var createdVariable = await _sut.CreateVariableAsync(GitLabApiHelper.TestProjectId, new CreateVariableRequest
{
VariableType = "env_var",
Key = "SOME_VAR_KEY_RETRIEVE",
Value = "VALUE_VAR",
EnvironmentScope = "*",
Masked = true,
Protected = true
});

VariableIdsToClean.Add(createdVariable.Key);

//act
var variables = await _sut.GetVariablesAsync(GitLabApiHelper.TestProjectId);
var variable = variables.First(v => v.Key == createdVariable.Key);

//assert
variables.Should().NotBeEmpty();
variable.Should().Match<Variable>(v =>
v.VariableType == createdVariable.VariableType &&
v.Key == createdVariable.Key &&
v.Value == createdVariable.Value &&
v.EnvironmentScope == createdVariable.EnvironmentScope &&
v.Masked == createdVariable.Masked &&
v.Protected == createdVariable.Protected);
}

[Fact]
public async Task ProjectRetrievedByName()
{
Expand Down Expand Up @@ -113,6 +148,31 @@ public async Task ProjectCreated()
ProjectIdsToClean.Add(project.Id);
}

[Fact]
public async Task ProjectVariablesCreated()
{
var request = new CreateVariableRequest
{
VariableType = "env_var",
Key = "SOME_VAR_KEY_CREATED",
Value = "VALUE_VAR",
EnvironmentScope = "*",
Masked = true,
Protected = true
};

var variable = await _sut.CreateVariableAsync(GitLabApiHelper.TestProjectId, request);

variable.Should().Match<Variable>(v => v.VariableType == request.VariableType
&& v.Key == request.Key
&& v.Value == request.Value
&& v.EnvironmentScope == request.EnvironmentScope
&& v.Masked == request.Masked
&& v.Protected == request.Protected);

VariableIdsToClean.Add(request.Key);
}

[Fact]
public async Task CreatedProjectCanBeUpdated()
{
Expand Down Expand Up @@ -219,6 +279,43 @@ public async Task CreatedProjectMilestoneCanBeUpdated()
m.Description == "description22");
}

[Fact]
public async Task ProjectVariableCanBeUpdated()
{
var request = new CreateVariableRequest
{
VariableType = "env_var",
Key = "SOME_VAR_KEY_TO_UPDATE",
Value = "VALUE_VAR",
EnvironmentScope = "*",
Masked = true,
Protected = true
};

var variable = await _sut.CreateVariableAsync(GitLabApiHelper.TestProjectId, request);

VariableIdsToClean.Add(request.Key);

var updateRequest = new UpdateProjectVariableRequest
{
VariableType = "file",
Key = request.Key,
Value = "UpdatedValue",
EnvironmentScope = "*",
Masked = request.Masked,
Protected = request.Protected,
};

var variableUpdated = await _sut.UpdateVariableAsync(GitLabApiHelper.TestProjectId, updateRequest);

variableUpdated.Should().Match<Variable>(v => v.VariableType == updateRequest.VariableType
&& v.Key == updateRequest.Key
&& v.Value == updateRequest.Value
&& v.EnvironmentScope == updateRequest.EnvironmentScope
&& v.Masked == updateRequest.Masked
&& v.Protected == updateRequest.Protected);
}

[Fact]
public async Task CreatedProjectMilestoneCanBeClosed()
{
Expand Down Expand Up @@ -253,6 +350,9 @@ private async Task CleanupProjects()

foreach (int projectId in ProjectIdsToClean)
await _sut.DeleteAsync(projectId);

foreach (string variableId in VariableIdsToClean)
await _sut.DeleteVariableAsync(GitLabApiHelper.TestProjectId, variableId);
}

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

0 comments on commit 3d6844b

Please sign in to comment.