Skip to content

Commit 97f4572

Browse files
committed
Added support for group and project variables (#330).
1 parent 7a08a31 commit 97f4572

File tree

7 files changed

+448
-23
lines changed

7 files changed

+448
-23
lines changed

src/main/java/org/gitlab4j/api/GroupApi.java

Lines changed: 167 additions & 22 deletions
Large diffs are not rendered by default.

src/main/java/org/gitlab4j/api/ProjectApi.java

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import org.gitlab4j.api.models.ProjectUser;
5050
import org.gitlab4j.api.models.PushRules;
5151
import org.gitlab4j.api.models.Snippet;
52+
import org.gitlab4j.api.models.Variable;
5253
import org.gitlab4j.api.models.Visibility;
5354

5455
/**
@@ -2395,4 +2396,152 @@ public Project setProjectAvatar(Object projectIdOrPath, File avatarFile) throws
23952396
Response response = putUpload(Response.Status.OK, "avatar", avatarFile, "projects", getProjectIdOrPath(projectIdOrPath));
23962397
return (response.readEntity(Project.class));
23972398
}
2399+
2400+
/**
2401+
* Get list of a project's variables.
2402+
*
2403+
* <pre><code>GitLab Endpoint: GET /groups/:id/variables</code></pre>
2404+
*
2405+
* @param projectIdOrPath projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance, required
2406+
* @return a list of variables belonging to the specified project
2407+
* @throws GitLabApiException if any exception occurs
2408+
*/
2409+
public List<Variable> getVariables(Object projectIdOrPath) throws GitLabApiException {
2410+
return (getVariables(projectIdOrPath, getDefaultPerPage()).all());
2411+
}
2412+
2413+
/**
2414+
* Get a list of variables for the specified project in the specified page range.
2415+
*
2416+
* <pre><code>GitLab Endpoint: GET /projects/:id/variables</code></pre>
2417+
*
2418+
* @param projectIdOrPath projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance, required
2419+
* @param page the page to get
2420+
* @param perPage the number of Variable instances per page
2421+
* @return a list of variables belonging to the specified project in the specified page range
2422+
* @throws GitLabApiException if any exception occurs
2423+
*/
2424+
public List<Variable> getVariables(Object projectIdOrPath, int page, int perPage) throws GitLabApiException {
2425+
Response response = get(Response.Status.OK, getPageQueryParams(page, perPage), "projects", getProjectIdOrPath(projectIdOrPath), "variables");
2426+
return (response.readEntity(new GenericType<List<Variable>>() {}));
2427+
}
2428+
2429+
/**
2430+
* Get a Pager of variables belonging to the specified project.
2431+
*
2432+
* <pre><code>GitLab Endpoint: GET /projects/:id/variables</code></pre>
2433+
*
2434+
* @param projectIdOrPath projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance, required
2435+
* @param itemsPerPage the number of Variable instances that will be fetched per page
2436+
* @return a Pager of variables belonging to the specified project
2437+
* @throws GitLabApiException if any exception occurs
2438+
*/
2439+
public Pager<Variable> getVariables(Object projectIdOrPath, int itemsPerPage) throws GitLabApiException {
2440+
return (new Pager<Variable>(this, Variable.class, itemsPerPage, null, "projects", getProjectIdOrPath(projectIdOrPath), "variables"));
2441+
}
2442+
2443+
/**
2444+
* Get a Stream of variables belonging to the specified project.
2445+
*
2446+
* <pre><code>GitLab Endpoint: GET /projects/:id/variables</code></pre>
2447+
*
2448+
* @param projectIdOrPath projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance, required
2449+
* @return a Stream of variables belonging to the specified project
2450+
* @throws GitLabApiException if any exception occurs
2451+
*/
2452+
public Stream<Variable> getVariablesStream(Object projectIdOrPath) throws GitLabApiException {
2453+
return (getVariables(projectIdOrPath, getDefaultPerPage()).stream());
2454+
}
2455+
2456+
/**
2457+
* Get the details of a project variable.
2458+
*
2459+
* <pre><code>GitLab Endpoint: GET /projects/:id/variables/:key</code></pre>
2460+
*
2461+
* @param projectIdOrPath projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance, required
2462+
* @param key the key of an existing variable, required
2463+
* @return the Variable instance for the specified variable
2464+
* @throws GitLabApiException if any exception occurs
2465+
*/
2466+
public Variable getVariable(Object projectIdOrPath, String key) throws GitLabApiException {
2467+
Response response = get(Response.Status.OK, null, "projects", getProjectIdOrPath(projectIdOrPath), "variables", key);
2468+
return (response.readEntity(Variable.class));
2469+
}
2470+
2471+
/**
2472+
* Get the details of a variable as an Optional instance.
2473+
*
2474+
* <pre><code>GitLab Endpoint: GET /projects/:id/variables/:key</code></pre>
2475+
*
2476+
* @param projectIdOrPath projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance, required
2477+
* @param key the key of an existing variable, required
2478+
* @return the Variable for the specified variable as an Optional instance
2479+
*/
2480+
public Optional<Variable> getOptionalVariable(Object projectIdOrPath, String key) {
2481+
try {
2482+
return (Optional.ofNullable(getVariable(projectIdOrPath, key)));
2483+
} catch (GitLabApiException glae) {
2484+
return (GitLabApi.createOptionalFromException(glae));
2485+
}
2486+
}
2487+
2488+
/**
2489+
* Create a new project variable.
2490+
*
2491+
* <pre><code>GitLab Endpoint: POST /projects/:id/variables</code></pre>
2492+
*
2493+
* @param projectIdOrPath projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance, required
2494+
* @param key the key of a variable; must have no more than 255 characters; only A-Z, a-z, 0-9, and _ are allowed, required
2495+
* @param value the value for the variable, required
2496+
* @param isProtected whether the variable is protected, optional
2497+
* @param environmentScope the environment_scope of the variable, optional
2498+
* @return a Variable instance with the newly created variable
2499+
* @throws GitLabApiException if any exception occurs during execution
2500+
*/
2501+
public Variable createVariable(Object projectIdOrPath, String key, String value, Boolean isProtected, String environmentScope) throws GitLabApiException {
2502+
2503+
GitLabApiForm formData = new GitLabApiForm()
2504+
.withParam("key", key, true)
2505+
.withParam("value", value, true)
2506+
.withParam("protected", isProtected)
2507+
.withParam("environment_scope", environmentScope);
2508+
Response response = post(Response.Status.CREATED, formData, "projects", getProjectIdOrPath(projectIdOrPath), "variables");
2509+
return (response.readEntity(Variable.class));
2510+
}
2511+
2512+
/**
2513+
* Update a project variable.
2514+
*
2515+
* <pre><code>GitLab Endpoint: PUT /projects/:id/variables/:key</code></pre>
2516+
*
2517+
* @param projectIdOrPath projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance, required
2518+
* @param key the key of an existing variable, required
2519+
* @param value the value for the variable, required
2520+
* @param isProtected whether the variable is protected, optional
2521+
* @param environmentScope the environment_scope of the variable, optional
2522+
* @return a Variable instance with the updated variable
2523+
* @throws GitLabApiException if any exception occurs during execution
2524+
*/
2525+
public Variable updateVariable(Object projectIdOrPath, String key, String value, Boolean isProtected, String environmentScope) throws GitLabApiException {
2526+
2527+
GitLabApiForm formData = new GitLabApiForm()
2528+
.withParam("value", value, true)
2529+
.withParam("protected", isProtected)
2530+
.withParam("environment_scope", environmentScope);
2531+
Response response = putWithFormData(Response.Status.OK, formData, "projects", getProjectIdOrPath(projectIdOrPath), "variables", key);
2532+
return (response.readEntity(Variable.class));
2533+
}
2534+
2535+
/**
2536+
* Deletes a project variable.
2537+
*
2538+
* <pre><code>DELETE /projects/:id/variables/:key</code></pre>
2539+
*
2540+
* @param projectIdOrPath projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance, required
2541+
* @param key the key of an existing variable, required
2542+
* @throws GitLabApiException if any exception occurs
2543+
*/
2544+
public void deleteVariable(Object projectIdOrPath, String key) throws GitLabApiException {
2545+
delete(Response.Status.NO_CONTENT, null, "projects", getProjectIdOrPath(projectIdOrPath), "variables", key);
2546+
}
23982547
}

src/main/java/org/gitlab4j/api/models/Variable.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,19 @@
44
import javax.xml.bind.annotation.XmlAccessorType;
55
import javax.xml.bind.annotation.XmlRootElement;
66

7+
import org.gitlab4j.api.utils.JacksonJson;
8+
9+
import com.fasterxml.jackson.annotation.JsonProperty;
10+
711
@XmlRootElement
812
@XmlAccessorType(XmlAccessType.FIELD)
913
public class Variable {
1014

1115
private String key;
1216
private String value;
17+
@JsonProperty("protected")
18+
private Boolean isProtected;
19+
private String environmentScope;
1320

1421
public String getKey() {
1522
return key;
@@ -26,4 +33,25 @@ public String getValue() {
2633
public void setValue(String value) {
2734
this.value = value;
2835
}
36+
37+
public Boolean getProtected() {
38+
return isProtected;
39+
}
40+
41+
public void setProtected(Boolean isProtected) {
42+
this.isProtected = isProtected;
43+
}
44+
45+
public String getEnvironmentScope() {
46+
return environmentScope;
47+
}
48+
49+
public void setEnvironmentScope(String environmentScope) {
50+
this.environmentScope = environmentScope;
51+
}
52+
53+
@Override
54+
public String toString() {
55+
return (JacksonJson.toJsonString(this));
56+
}
2957
}

src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@
7979
import org.gitlab4j.api.models.Tag;
8080
import org.gitlab4j.api.models.TreeItem;
8181
import org.gitlab4j.api.models.User;
82+
import org.gitlab4j.api.models.Variable;
8283
import org.gitlab4j.api.services.JiraService;
8384
import org.gitlab4j.api.services.SlackService;
8485
import org.gitlab4j.api.systemhooks.ProjectSystemHookEvent;
@@ -243,6 +244,12 @@ public void testPipelineSchedule() throws Exception {
243244
assertTrue(compareJson(pipelineSchedule, "pipeline-schedule.json"));
244245
}
245246

247+
@Test
248+
public void testProjectVariables() throws Exception {
249+
List<Variable> variables = unmarshalResourceList(Variable.class, "project-variables.json");
250+
assertTrue(compareJson(variables, "project-variables.json"));
251+
}
252+
246253
@Test
247254
public void testJob() throws Exception {
248255
Job job = unmarshalResource(Job.class, "job.json");

src/test/java/org/gitlab4j/api/TestProjectApi.java

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,23 @@
2626
import static org.junit.Assert.assertEquals;
2727
import static org.junit.Assert.assertFalse;
2828
import static org.junit.Assert.assertNotNull;
29+
import static org.junit.Assert.assertNull;
2930
import static org.junit.Assert.assertTrue;
3031
import static org.junit.Assume.assumeTrue;
3132

3233
import java.util.Arrays;
3334
import java.util.List;
3435
import java.util.Map;
3536
import java.util.Optional;
37+
import java.util.stream.Stream;
3638

3739
import javax.ws.rs.core.Response;
3840

3941
import org.gitlab4j.api.GitLabApi.ApiVersion;
4042
import org.gitlab4j.api.models.AccessLevel;
4143
import org.gitlab4j.api.models.Group;
4244
import org.gitlab4j.api.models.Project;
45+
import org.gitlab4j.api.models.Variable;
4346
import org.gitlab4j.api.models.Visibility;
4447
import org.junit.AfterClass;
4548
import org.junit.Before;
@@ -87,6 +90,7 @@ public class TestProjectApi {
8790
private static final String TEST_PROJECT_NAME_2 = "test-gitlab4j-create-project-2";
8891
private static final String TEST_PROJECT_NAME_UPDATE = "test-gitlab4j-create-project-update";
8992
private static final String TEST_XFER_PROJECT_NAME = "test-gitlab4j-xfer-project";
93+
private static final String TEST_VARIABLE_KEY_PREFIX = "TEST_VARIABLE_KEY_";
9094
private static GitLabApi gitLabApi;
9195

9296
public TestProjectApi() {
@@ -150,7 +154,18 @@ private static void deleteAllTestProjects() {
150154
Project project = gitLabApi.getProjectApi().getProject(TEST_NAMESPACE, TEST_PROJECT_NAME);
151155
List<Group> groups = gitLabApi.getGroupApi().getGroups(TEST_GROUP);
152156
gitLabApi.getProjectApi().unshareProject(project.getId(), groups.get(0).getId());
153-
} catch (GitLabApiException ignore) {}
157+
158+
List<Variable> variables = gitLabApi.getProjectApi().getVariables(project);
159+
if (variables != null) {
160+
161+
for (Variable variable : variables) {
162+
if (variable.getKey().startsWith(TEST_VARIABLE_KEY_PREFIX)) {
163+
gitLabApi.getProjectApi().deleteVariable(project, variable.getKey());
164+
}
165+
}
166+
}
167+
} catch (GitLabApiException ignore) {
168+
}
154169
}
155170

156171
if (TEST_GROUP != null && TEST_GROUP_PROJECT != null) {
@@ -589,4 +604,44 @@ public void testTransferProject() throws GitLabApiException {
589604
Project transferedProject = gitLabApi.getProjectApi().transferProject(projectToTransfer, TEST_XFER_NAMESPACE);
590605
assertNotNull(transferedProject);
591606
}
607+
608+
@Test
609+
public void testVariables() throws GitLabApiException {
610+
611+
Project project = gitLabApi.getProjectApi().getProject(TEST_NAMESPACE, TEST_PROJECT_NAME);
612+
assertNotNull(project);
613+
614+
String key = TEST_VARIABLE_KEY_PREFIX + TestUtils.getRandomInt() + "_" + TestUtils.getRandomInt();
615+
String value = "TEST_VARIABLE_VALUE_" + TestUtils.getRandomInt() + "_" + TestUtils.getRandomInt();
616+
Variable variable = gitLabApi.getProjectApi().createVariable(project, key, value, null, null);
617+
618+
assertNotNull(variable);
619+
assertEquals(key, variable.getKey());
620+
assertEquals(value, variable.getValue());
621+
622+
Stream<Variable> variables = gitLabApi.getProjectApi().getVariablesStream(project);
623+
assertNotNull(variables);
624+
625+
Variable matchingVariable = variables.filter(v -> v.getKey().equals(key)).findAny().orElse(null);
626+
assertNotNull(matchingVariable);
627+
assertEquals(key, matchingVariable.getKey());
628+
assertEquals(value, matchingVariable.getValue());
629+
assertFalse(matchingVariable.getProtected());
630+
assertNull(matchingVariable.getEnvironmentScope());
631+
632+
gitLabApi.getProjectApi().updateVariable(project, key, "NONE", true, "DEV");
633+
variable = gitLabApi.getProjectApi().getVariable(project, key);
634+
635+
assertNotNull(variable);
636+
assertEquals(key, variable.getKey());
637+
assertEquals("NONE", variable.getValue());
638+
assertTrue(variable.getProtected());
639+
640+
gitLabApi.getProjectApi().deleteVariable(project, key);
641+
variables = gitLabApi.getProjectApi().getVariablesStream(project);
642+
assertNotNull(variables);
643+
644+
matchingVariable = variables.filter(v -> v.getKey().equals(key)).findAny().orElse(null);
645+
assertNull(matchingVariable);
646+
}
592647
}

src/test/java/org/gitlab4j/api/TestUtils.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,23 @@ public static String getReaderContentAsString(Reader reader) throws IOException
6262
public static final String getProperty(String key) {
6363
return (testProperties.getProperty(key));
6464
}
65+
66+
/**
67+
* Get a random integer between 1 and the specified value (inclusive).
68+
*
69+
* @param maxValue the maximum value to return
70+
* @return a random integer between 1 and the specified value (inclusive)
71+
*/
72+
public static final int getRandomInt(int maxValue) {
73+
return ((int)(Math.random() * maxValue + 1));
74+
}
75+
76+
/**
77+
* Get a random integer between 1 and Integer.MAX_VALUE (inclusive).
78+
*
79+
* @return a random integer between 1 and Integer.MAX_VALUE (inclusive)
80+
*/
81+
public static final int getRandomInt() {
82+
return (getRandomInt(Integer.MAX_VALUE));
83+
}
6584
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[
2+
{
3+
"key": "TEST_VARIABLE_1",
4+
"value": "TEST_1",
5+
"protected": true,
6+
"environment_scope": "*"
7+
},
8+
{
9+
"key": "TEST_VARIABLE_2",
10+
"value": "TEST_2",
11+
"protected": false
12+
},
13+
{
14+
"key": "TEST_VARIABLE_3",
15+
"value": "TEST_3",
16+
"environment_scope": "DEV"
17+
},
18+
{
19+
"key": "TEST_VARIABLE_4",
20+
"value": "TEST_4"
21+
}
22+
]

0 commit comments

Comments
 (0)