diff --git a/pom.xml b/pom.xml index 221b48bb05b994f0f88df1b2e0315ed4cd602e98..009b7dc57a6dcadbd10e59183d58c93a0fda2365 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ 1.59 - 11.10.4-ce.0 + 11.11.2-ce.0 true true 8090 diff --git a/src/main/java/org/gitlab4j/api/GitLabApi.java b/src/main/java/org/gitlab4j/api/GitLabApi.java index 93052e01f95adf44830ef935aef94522faa56da9..7889c6c27fdb0a68961e0765eeabbc28d8015838 100644 --- a/src/main/java/org/gitlab4j/api/GitLabApi.java +++ b/src/main/java/org/gitlab4j/api/GitLabApi.java @@ -63,6 +63,7 @@ public class GitLabApi { private EventsApi eventsApi; private GroupApi groupApi; private HealthCheckApi healthCheckApi; + private ImportExportApi importExportApi; private IssuesApi issuesApi; private JobApi jobApi; private LabelsApi labelsApi; @@ -1123,11 +1124,30 @@ public class GitLabApi { return (healthCheckApi); } + /** + * Gets the ImportExportApi instance owned by this GitLabApi instance. The ImportExportApi is used + * to perform all project import/export related API calls. + * + * @return the ImportExportApi instance owned by this GitLabApi instance + */ + public ImportExportApi getImportExportApi() { + + if (importExportApi == null) { + synchronized (this) { + if (importExportApi == null) { + importExportApi = new ImportExportApi(this); + } + } + } + + return (importExportApi); + } + /** * Gets the IssuesApi instance owned by this GitLabApi instance. The IssuesApi is used - * to perform all iossue related API calls. + * to perform all issue related API calls. * - * @return the CommitsApi instance owned by this GitLabApi instance + * @return the IssuesApi instance owned by this GitLabApi instance */ public IssuesApi getIssuesApi() { diff --git a/src/main/java/org/gitlab4j/api/ImportExportApi.java b/src/main/java/org/gitlab4j/api/ImportExportApi.java new file mode 100644 index 0000000000000000000000000000000000000000..44881bda6fc5534907325bd993c45e6031ff1e24 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/ImportExportApi.java @@ -0,0 +1,218 @@ +package org.gitlab4j.api; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; +import java.util.Map; + +import javax.ws.rs.core.Form; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.gitlab4j.api.models.ExportStatus; +import org.gitlab4j.api.models.ImportStatus; +import org.gitlab4j.api.models.Project; + +/** + * This class provides an entry point to all the GitLab API project import/export calls. + * @see Project import/export API at GitLab + */ +public class ImportExportApi extends AbstractApi { + + public ImportExportApi(GitLabApi gitLabApi) { + super(gitLabApi); + } + + /** + * Schedule an export. + * + *
GitLab Endpoint: POST /projects/:id/export
+ * + * @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance + * @throws GitLabApiException if any exception occurs + */ + public void scheduleExport(Object projectIdOrPath) throws GitLabApiException { + scheduleExport(projectIdOrPath, null, null, null, null); + } + + /** + * Schedule an export. + * + *
GitLab Endpoint: POST /projects/:id/export
+ * + * @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance + * @param description overrides the project description, optional + * @throws GitLabApiException if any exception occurs + */ + public void scheduleExport(Object projectIdOrPath, String description) throws GitLabApiException { + scheduleExport(projectIdOrPath, description, null, null, null); + } + + /** + * Schedule an export. + * + *
GitLab Endpoint: POST /projects/:id/export
+ * + * @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance + * @param description overrides the project description, optional + * @param upload Mao that contains the information to upload the exported project to a web server + * @param uploadUrl the URL to upload the project + * @param uploadHttpMethod the HTTP method to upload the exported project. + * Only PUT and POST methods allowed. Default is PUT + * @throws GitLabApiException if any exception occurs + */ + public void scheduleExport(Object projectIdOrPath, String description, + Map upload, String uploadUrl, String uploadHttpMethod) throws GitLabApiException { + + Form formData = new GitLabApiForm() + .withParam("description", description) + .withParam("upload", upload) + .withParam("upload[url]", uploadUrl) + .withParam("upload[http_method]", uploadHttpMethod); + post(Response.Status.ACCEPTED, formData, "projects", getProjectIdOrPath(projectIdOrPath), "export"); + } + + /** + * Get the status of export. + * + *
GitLab Endpoint: GET /projects/:id/export
+ * + * @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance + * @return an ExportStatus instance holding information on the export status + * @throws GitLabApiException if any exception occurs + */ + public ExportStatus getExportStatus(Object projectIdOrPath) throws GitLabApiException { + Response response = get(Response.Status.OK, null, "projects", getProjectIdOrPath(projectIdOrPath), "export"); + return (response.readEntity(ExportStatus.class)); + } + + /** + * Download the finished export. + * + *
GitLab Endpoint: GET /projects/:id/export/download
+ * + * @param projectIdOrPath the project in the form of an Integer(ID), String(path), or Project instance + * @param directory the File instance of the directory to save the export file to, if null will use "java.io.tmpdir" + * @return a File instance pointing to the download of the project export file + * @throws GitLabApiException if any exception occurs + */ + public File downloadExport(Object projectIdOrPath, File directory) throws GitLabApiException { + + Response response = getWithAccepts(Response.Status.OK, null, MediaType.MEDIA_TYPE_WILDCARD, + "projects", getProjectIdOrPath(projectIdOrPath), "export", "download"); + try { + + if (directory == null) + directory = new File(System.getProperty("java.io.tmpdir")); + + String disposition = response.getHeaderString("Content-Disposition"); + String filename = disposition.replaceFirst("(?i)^.*filename=\"?([^\"]+)\"?.*$", "$1"); + File file = new File(directory, filename); + + InputStream in = response.readEntity(InputStream.class); + Files.copy(in, file.toPath(), StandardCopyOption.REPLACE_EXISTING); + return (file); + + } catch (IOException ioe) { + throw new GitLabApiException(ioe); + } + } + + /** + *

Import an exported project. The following properties on the Project instance + * are utilized in the creation of the new project:

+ * + *
GitLab Endpoint: POST /projects/import
+ * + * @param namespaceIdOrPath the ID or path of the namespace that the project will be imported to. Defaults to the current user’s namespace + * @param exportFile the project export file to be imported + * @param path the name and path for the new project + * @param overwrite if there is a project with the same path the import will overwrite it. Defaults to false + * @param overrideParams overriding project params, supports all fields defined by the ProjectApi, optional + * @return an Importstatus instance with info for the project being imported to + * @throws GitLabApiException if any exception occurs + */ + public ImportStatus startImport(Object namespaceIdOrPath, File exportFile, String path, Boolean overwrite, Project overrideParams) throws GitLabApiException { + + URL url; + try { + url = getApiClient().getApiUrl("projects", "import"); + } catch (IOException ioe) { + throw new GitLabApiException(ioe); + } + + GitLabApiForm formData = new GitLabApiForm() + .withParam("path", path, true) + .withParam("namespace", namespaceIdOrPath) + .withParam("overwrite", overwrite); + + if (overrideParams != null) { + formData.withParam("default_branch", overrideParams.getDefaultBranch()) + .withParam("description", overrideParams.getDescription()) + .withParam("issues_enabled", overrideParams.getIssuesEnabled()) + .withParam("merge_method", overrideParams.getMergeMethod()) + .withParam("merge_requests_enabled", overrideParams.getMergeRequestsEnabled()) + .withParam("jobs_enabled", overrideParams.getJobsEnabled()) + .withParam("wiki_enabled", overrideParams.getWikiEnabled()) + .withParam("container_registry_enabled", overrideParams.getContainerRegistryEnabled()) + .withParam("snippets_enabled", overrideParams.getSnippetsEnabled()) + .withParam("shared_runners_enabled", overrideParams.getSharedRunnersEnabled()) + .withParam("public_jobs", overrideParams.getPublicJobs()) + .withParam("visibility_level", overrideParams.getVisibilityLevel()) + .withParam("only_allow_merge_if_pipeline_succeeds", overrideParams.getOnlyAllowMergeIfPipelineSucceeds()) + .withParam("only_allow_merge_if_all_discussions_are_resolved", overrideParams.getOnlyAllowMergeIfAllDiscussionsAreResolved()) + .withParam("lfs_enabled", overrideParams.getLfsEnabled()) + .withParam("request_access_enabled", overrideParams.getRequestAccessEnabled()) + .withParam("repository_storage", overrideParams.getRepositoryStorage()) + .withParam("approvals_before_merge", overrideParams.getApprovalsBeforeMerge()) + .withParam("printing_merge_request_link_enabled", overrideParams.getPrintingMergeRequestLinkEnabled()) + .withParam("resolve_outdated_diff_discussions", overrideParams.getResolveOutdatedDiffDiscussions()) + .withParam("initialize_with_readme", overrideParams.getInitializeWithReadme()) + .withParam("packages_enabled", overrideParams.getPackagesEnabled()); + } + + Response response = upload(Response.Status.CREATED, "file", exportFile, null, formData, url); + return (response.readEntity(ImportStatus.class)); + } + + /** + * Get the status of an import. + * + *
GitLab Endpoint: GET /projects/:id/import
+ * + * @param projectIdOrPath the new (imported) project identifier in the form of an Integer(ID), String(path), or Project instance + * @return an ImportStatus instance holding information on the import status + * @throws GitLabApiException if any exception occurs + */ + public ImportStatus getImportStatus(Object projectIdOrPath) throws GitLabApiException { + Response response = get(Response.Status.OK, null, "projects", getProjectIdOrPath(projectIdOrPath), "import"); + return (response.readEntity(ImportStatus.class)); + } +} diff --git a/src/main/java/org/gitlab4j/api/models/ExportStatus.java b/src/main/java/org/gitlab4j/api/models/ExportStatus.java new file mode 100644 index 0000000000000000000000000000000000000000..6efb892750c3601d83d6b26a254abc4a30a26a03 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/models/ExportStatus.java @@ -0,0 +1,145 @@ +package org.gitlab4j.api.models; + +import java.util.Date; +import java.util.Map; + +import org.gitlab4j.api.utils.JacksonJson; +import org.gitlab4j.api.utils.JacksonJsonEnumHelper; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonValue; + +public class ExportStatus { + + /** + * Enum representing the status of the export. + */ + public enum Status { + + NONE, STARTED, FINISHED, + + /** + * Represents that the export process has been completed successfully and the platform is + * performing some actions on the resulted file. For example, sending an email notifying + * the user to download the file, uploading the exported file to a web server, etc. + */ + AFTER_EXPORT_ACTION; + + private static JacksonJsonEnumHelper enumHelper = new JacksonJsonEnumHelper<>(Status.class); + + @JsonCreator + public static Status forValue(String value) { + return enumHelper.forValue(value); + } + + @JsonValue + public String toValue() { + return (enumHelper.toString(this)); + } + + @Override + public String toString() { + return (enumHelper.toString(this)); + } + } + + private Integer id; + private String description; + private String name; + private String nameWithNamespace; + private String path; + private String pathWithNamespace; + private Date createdAt; + private Status exportStatus; + + @JsonProperty("_links") + private Map links; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNameWithNamespace() { + return nameWithNamespace; + } + + public void setNameWithNamespace(String nameWithNamespace) { + this.nameWithNamespace = nameWithNamespace; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getPathWithNamespace() { + return pathWithNamespace; + } + + public void setPathWithNamespace(String pathWithNamespace) { + this.pathWithNamespace = pathWithNamespace; + } + + public Date getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public Status getExportStatus() { + return exportStatus; + } + + public void setExportStatus(Status exportStatus) { + this.exportStatus = exportStatus; + } + + public Map getLinks() { + return links; + } + + public void setLinks(Map links) { + this.links = links; + } + + @JsonIgnore + public String getLinkByName(String name) { + if (links == null || links.isEmpty()) { + return (null); + } + + return (links.get(name)); + } + + @Override + public String toString() { + return (JacksonJson.toJsonString(this)); + } +} diff --git a/src/main/java/org/gitlab4j/api/models/ImportStatus.java b/src/main/java/org/gitlab4j/api/models/ImportStatus.java new file mode 100644 index 0000000000000000000000000000000000000000..5945456b4a31410e953449e44a540514e1c80d33 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/models/ImportStatus.java @@ -0,0 +1,124 @@ +package org.gitlab4j.api.models; + +import java.util.Date; + +import org.gitlab4j.api.utils.JacksonJson; +import org.gitlab4j.api.utils.JacksonJsonEnumHelper; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public class ImportStatus { + + /** + * Enum representing the status of the import. + */ + public enum Status { + + NONE, SCHEDULED, FAILED, STARTED, FINISHED; + + private static JacksonJsonEnumHelper enumHelper = new JacksonJsonEnumHelper<>(Status.class); + + @JsonCreator + public static Status forValue(String value) { + return enumHelper.forValue(value); + } + + @JsonValue + public String toValue() { + return (enumHelper.toString(this)); + } + + @Override + public String toString() { + return (enumHelper.toString(this)); + } + } + + private Integer id; + private String description; + private String name; + private String nameWithNamespace; + private String path; + private String pathWithNamespace; + private Date createdAt; + private Status importStatus; + private String importError; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getNameWithNamespace() { + return nameWithNamespace; + } + + public void setNameWithNamespace(String nameWithNamespace) { + this.nameWithNamespace = nameWithNamespace; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getPathWithNamespace() { + return pathWithNamespace; + } + + public void setPathWithNamespace(String pathWithNamespace) { + this.pathWithNamespace = pathWithNamespace; + } + + public Date getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public Status getImportStatus() { + return importStatus; + } + + public void setImportStatus(Status importStatus) { + this.importStatus = importStatus; + } + + public String getImportError() { + return importError; + } + + public void setImportError(String importError) { + this.importError = importError; + } + + @Override + public String toString() { + return (JacksonJson.toJsonString(this)); + } +} diff --git a/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java b/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java index facefe57a55b37564db823dfc6c389a32eb08efd..735a6565550d793e0a4239a156e78b68aa033143 100644 --- a/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java +++ b/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java @@ -51,10 +51,12 @@ import org.gitlab4j.api.models.Email; import org.gitlab4j.api.models.Epic; import org.gitlab4j.api.models.EpicIssue; import org.gitlab4j.api.models.Event; +import org.gitlab4j.api.models.ExportStatus; import org.gitlab4j.api.models.FileUpload; import org.gitlab4j.api.models.Group; import org.gitlab4j.api.models.HealthCheckInfo; import org.gitlab4j.api.models.ImpersonationToken; +import org.gitlab4j.api.models.ImportStatus; import org.gitlab4j.api.models.Issue; import org.gitlab4j.api.models.Job; import org.gitlab4j.api.models.Key; @@ -192,6 +194,12 @@ public class TestGitLabApiBeans { assertTrue(compareJson(event, "event.json")); } + @Test + public void testExportStatus() throws Exception { + ExportStatus exportStatus = unmarshalResource(ExportStatus.class, "export-status.json"); + assertTrue(compareJson(exportStatus, "export-status.json")); + } + @Test public void testFileUpload() throws Exception { FileUpload fileUpload = unmarshalResource(FileUpload.class, "file-upload.json"); @@ -210,6 +218,12 @@ public class TestGitLabApiBeans { assertTrue(compareJson(healthCheck, "health-check.json")); } + @Test + public void testImportStatus() throws Exception { + ImportStatus importStatus = unmarshalResource(ImportStatus.class, "import-status.json"); + assertTrue(compareJson(importStatus, "import-status.json")); + } + @Test public void testIssue() throws Exception { Issue issue = unmarshalResource(Issue.class, "issue.json"); diff --git a/src/test/java/org/gitlab4j/api/TestImportExportApi.java b/src/test/java/org/gitlab4j/api/TestImportExportApi.java new file mode 100644 index 0000000000000000000000000000000000000000..df675589b246eb9456270aa7807c94168208a291 --- /dev/null +++ b/src/test/java/org/gitlab4j/api/TestImportExportApi.java @@ -0,0 +1,200 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2017 Greg Messner + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package org.gitlab4j.api; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeNotNull; + +import java.io.File; +import java.util.Optional; + +import org.gitlab4j.api.models.ExportStatus; +import org.gitlab4j.api.models.ImportStatus; +import org.gitlab4j.api.models.Project; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runners.MethodSorters; + +/** + * In order for these tests to run you must set the following properties in ~/test-gitlab4j.properties + * + * TEST_NAMESPACE + * TEST_PROJECT_NAME + * TEST_HOST_URL + * TEST_PRIVATE_TOKEN + * + * If any of the above are NULL, all tests in this class will be skipped. + */ +@Category(IntegrationTest.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestImportExportApi extends AbstractIntegrationTest { + + private static final String TEST_IMPORT_PROJECT_NAME = "test-import-project"; + private static GitLabApi gitLabApi; + private static Project testProject; + + public TestImportExportApi() { + super(); + } + + @BeforeClass + public static void setup() { + + // Must setup the connection to the GitLab test server + gitLabApi = baseTestSetup(); + testProject = getTestProject(); + + deleteAllTestProjects(); + } + + @AfterClass + public static void teardown() throws GitLabApiException { + deleteAllTestProjects(); + } + + private static void deleteAllTestProjects() { + if (gitLabApi == null) { + return; + } + + try { + Project project = gitLabApi.getProjectApi().getProject(TEST_NAMESPACE, TEST_IMPORT_PROJECT_NAME); + gitLabApi.getProjectApi().deleteProject(project); + } catch (GitLabApiException ignore) {} + } + + @Before + public void beforeMethod() { + assumeNotNull(gitLabApi); + } + + + @Test + public void testScheduleExport() throws GitLabApiException { + + // Arrange + assumeNotNull(testProject); + + // Act + gitLabApi.getImportExportApi().scheduleExport(testProject); + ExportStatus exportStatus = gitLabApi.getImportExportApi().getExportStatus(testProject); + + // Assert + assertNotNull(exportStatus); + ExportStatus.Status status = exportStatus.getExportStatus(); + assertNotEquals(ExportStatus.Status.NONE, status); + } + + @Test + public void testExportDownloadAndImport() throws GitLabApiException { + + // Arrange + assumeNotNull(testProject); + + // Act + gitLabApi.getImportExportApi().scheduleExport(testProject); + + // Wait up to 20 seconds for the export to complete + System.out.print("Waiting for export to complete"); + int retries = 0; + while (true) { + + System.out.print("."); + ExportStatus exportStatus = gitLabApi.getImportExportApi().getExportStatus(testProject); + if (exportStatus.getExportStatus() == ExportStatus.Status.FINISHED) { + System.out.println("done"); + break; + } + + if (retries >= 20) { + System.out.println("aborting!"); + fail("Project export is taking too long, failing test."); + } + + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } + + retries++; + } + + File exportDownload = null; + try { + + System.out.println("Downloading exported project"); + exportDownload = gitLabApi.getImportExportApi().downloadExport(testProject, null); + assertNotNull(exportDownload); + assertTrue(exportDownload.length() > 10000); + + ImportStatus importStatus = gitLabApi.getImportExportApi().startImport(null, exportDownload, + TEST_IMPORT_PROJECT_NAME, true, null); + assertNotNull(importStatus); + Integer newProjectId = importStatus.getId(); + + // Wait up to 20 seconds for the import to complete + System.out.print("Waiting for import to complete"); + retries = 0; + while (true) { + + System.out.print("."); + importStatus = gitLabApi.getImportExportApi().getImportStatus(newProjectId); + if (importStatus.getImportStatus() == ImportStatus.Status.FINISHED) { + System.out.println("done"); + break; + } + + if (retries >= 20) { + System.out.println("aborting!"); + fail("Project import is taking too long, failing test."); + } + + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } + + retries++; + } + + Optional newProject = gitLabApi.getProjectApi().getOptionalProject(newProjectId); + assertTrue(newProject.isPresent()); + assertEquals(newProjectId, newProject.get().getId()); + assertEquals(TEST_IMPORT_PROJECT_NAME, newProject.get().getName()); + + } finally { + if (exportDownload != null) { + exportDownload.delete(); + } + } + } +} diff --git a/src/test/resources/org/gitlab4j/api/export-status.json b/src/test/resources/org/gitlab4j/api/export-status.json new file mode 100644 index 0000000000000000000000000000000000000000..0d3dfb5e6015805182bbad7560ab57fcec388ac4 --- /dev/null +++ b/src/test/resources/org/gitlab4j/api/export-status.json @@ -0,0 +1,14 @@ +{ + "id": 1, + "description": "Itaque perspiciatis minima aspernatur corporis consequatur.", + "name": "Gitlab Test", + "name_with_namespace": "Gitlab Org / Gitlab Test", + "path": "gitlab-test", + "path_with_namespace": "gitlab-org/gitlab-test", + "created_at": "2017-08-29T04:36:44.383Z", + "export_status": "finished", + "_links": { + "api_url": "https://gitlab.example.com/api/v4/projects/1/export/download", + "web_url": "https://gitlab.example.com/gitlab-org/gitlab-test/download_export" + } +} diff --git a/src/test/resources/org/gitlab4j/api/import-status.json b/src/test/resources/org/gitlab4j/api/import-status.json new file mode 100644 index 0000000000000000000000000000000000000000..ea1afc0ea0a231151bf7dd28da00d1ead979c463 --- /dev/null +++ b/src/test/resources/org/gitlab4j/api/import-status.json @@ -0,0 +1,9 @@ +{ + "id": 1, + "name": "api-project", + "name_with_namespace": "Administrator / api-project", + "path": "api-project", + "path_with_namespace": "root/api-project", + "created_at": "2018-02-13T09:05:58.023Z", + "import_status": "scheduled" +} \ No newline at end of file