Skip to content

Commit

Permalink
Allow repository creation in the Gitea DevService (#156)
Browse files Browse the repository at this point in the history
* feat: allow repository creation in Gitea

* Optional repositories

---------

Co-authored-by: George Gastaldi <gegastaldi@gmail.com>
  • Loading branch information
iocanel and gastaldi authored Oct 23, 2024
1 parent 360c730 commit 362aebe
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import static org.testcontainers.containers.wait.strategy.Wait.forListeningPorts;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.jboss.logging.Logger;
import org.testcontainers.containers.GenericContainer;
Expand All @@ -15,10 +18,10 @@ class GiteaContainer extends GenericContainer<GiteaContainer> {
* Logger which will be used to capture container STDOUT and STDERR.
*/
private static final Logger log = Logger.getLogger(GiteaContainer.class);

private static final int HTTP_PORT = 3000;

private JGitBuildTimeConfig.DevService devServiceConfig;
private List<String> repositories = new ArrayList<>();

GiteaContainer(JGitBuildTimeConfig.DevService devServiceConfig) {
super("gitea/gitea:latest-rootless");
Expand All @@ -41,6 +44,9 @@ protected void containerIsStarted(InspectContainerResponse containerInfo, boolea
if (!reused) {
try {
createAdminUser();
for (String repository : devServiceConfig.repositories().orElse(Collections.emptyList())) {
createRepository(this, repository);
}
} catch (IOException | InterruptedException e) {
throw new RuntimeException("Failed to create admin user", e);
}
Expand Down Expand Up @@ -70,11 +76,46 @@ private void createAdminUser() throws IOException, InterruptedException {
}
}

private void createRepository(GiteaContainer giteaContainer, String repository)
throws UnsupportedOperationException, IOException, InterruptedException {
String httpUrl = "http://localhost:" + GiteaContainer.HTTP_PORT;
String data = """
{"name":"%s", "private":false, "auto_init":true, "readme":"Default"}
"""
.formatted(repository);

String[] cmd = {
"/usr/bin/curl",
"-X",
"POST",
"--user",
devServiceConfig.adminUsername() + ":" + devServiceConfig.adminPassword(),
"-H",
"Content-Type: application/json",
"-d",
data,
httpUrl + "/api/v1/user/repos"
};

log.debug(String.join(" ", cmd));
ExecResult execResult = giteaContainer.execInContainer(cmd);
log.info(execResult.getStdout());
if (execResult.getExitCode() != 0) {
throw new RuntimeException("Failed to create repository: " + repository + ":" + execResult.getStderr());
}
repositories.add(repository);
log.info("Created repository: " + repository);
}

public String getHttpUrl() {
return "http://" + getHost() + ":" + getHttpPort();
}

public int getHttpPort() {
return getMappedPort(HTTP_PORT);
}

public List<String> getRepositories() {
return repositories;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.quarkus.jgit.deployment;

import java.util.List;

import io.quarkus.builder.item.SimpleBuildItem;

/**
Expand All @@ -11,12 +13,15 @@ public final class GiteaDevServiceInfoBuildItem extends SimpleBuildItem {
private final int httpPort;
private final String adminUsername;
private final String adminPassword;
private final List<String> repositories;

public GiteaDevServiceInfoBuildItem(String host, int httpPort, String adminUsername, String adminPassword) {
public GiteaDevServiceInfoBuildItem(String host, int httpPort, String adminUsername, String adminPassword,
List<String> repositories) {
this.host = host;
this.httpPort = httpPort;
this.adminUsername = adminUsername;
this.adminPassword = adminPassword;
this.repositories = repositories;
}

public int httpPort() {
Expand All @@ -35,4 +40,7 @@ public String adminPassword() {
return adminPassword;
}

public List<String> repositories() {
return repositories;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.quarkus.jgit.deployment;

import java.util.List;
import java.util.Optional;
import java.util.OptionalInt;

import io.quarkus.runtime.annotations.ConfigPhase;
Expand Down Expand Up @@ -46,6 +48,12 @@ interface DevService {
@WithDefault("quarkus")
String adminPassword();

/**
* Repositories to be created when the Dev Service starts.
*/
@WithDefault("${quarkus.application.name}")
Optional<List<String>> repositories();

/**
* Should the container be reused?
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ DevServicesResultBuildItem createContainer(JGitBuildTimeConfig config,
gitServer.getHost(),
gitServer.getHttpPort(),
config.devservices().adminUsername(),
config.devservices().adminPassword()));
config.devservices().adminPassword(),
gitServer.getRepositories()));
return devService.toBuildItem();
}

Expand Down
17 changes: 17 additions & 0 deletions docs/modules/ROOT/pages/includes/quarkus-jgit.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,23 @@ endif::add-copy-button-to-env-var[]
|string
|`quarkus`

a|icon:lock[title=Fixed at build time] [[quarkus-jgit_quarkus-jgit-devservices-repositories]] [.property-path]##link:#quarkus-jgit_quarkus-jgit-devservices-repositories[`quarkus.jgit.devservices.repositories`]##

[.description]
--
Repositories to be created when the Dev Service starts.


ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++QUARKUS_JGIT_DEVSERVICES_REPOSITORIES+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++QUARKUS_JGIT_DEVSERVICES_REPOSITORIES+++`
endif::add-copy-button-to-env-var[]
--
|list of string
|`${quarkus.application.name}`

a|icon:lock[title=Fixed at build time] [[quarkus-jgit_quarkus-jgit-devservices-reuse]] [.property-path]##link:#quarkus-jgit_quarkus-jgit-devservices-reuse[`quarkus.jgit.devservices.reuse`]##

[.description]
Expand Down
17 changes: 17 additions & 0 deletions docs/modules/ROOT/pages/includes/quarkus-jgit_quarkus.jgit.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,23 @@ endif::add-copy-button-to-env-var[]
|string
|`quarkus`

a|icon:lock[title=Fixed at build time] [[quarkus-jgit_quarkus-jgit-devservices-repositories]] [.property-path]##link:#quarkus-jgit_quarkus-jgit-devservices-repositories[`quarkus.jgit.devservices.repositories`]##

[.description]
--
Repositories to be created when the Dev Service starts.


ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++QUARKUS_JGIT_DEVSERVICES_REPOSITORIES+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++QUARKUS_JGIT_DEVSERVICES_REPOSITORIES+++`
endif::add-copy-button-to-env-var[]
--
|list of string
|`${quarkus.application.name}`

a|icon:lock[title=Fixed at build time] [[quarkus-jgit_quarkus-jgit-devservices-reuse]] [.property-path]##link:#quarkus-jgit_quarkus-jgit-devservices-reuse[`quarkus.jgit.devservices.reuse`]##

[.description]
Expand Down
3 changes: 2 additions & 1 deletion integration-tests/src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
quarkus.native.resources.includes=repos/**
quarkus.jgit.devservices.enabled=true
quarkus.jgit.devservices.http-port=8089
quarkus.jgit.devservices.show-logs=true
quarkus.jgit.devservices.show-logs=false
quarkus.jgit.devservices.repositories=${quarkus.application.name},extra-repo1,extra-repo2
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

import io.gitea.ApiClient;
import io.gitea.Configuration;
Expand Down Expand Up @@ -63,10 +65,16 @@ public void serviceRunning() {
.statusCode(200);
}

@Test
public void shouldCloneFromDevService(@TempDir Path tempDir) throws Exception {
@ParameterizedTest
@ValueSource(strings = {
"test-repo", // The repository created in the @BeforeAll method
"quarkus-jgit-integration-tests", //The project repository created by the Dev Service
"extra-repo1", // An extra repository created by the Dev Service
"extra-repo2" // An other extra repository created by the Dev Service
})
public void shouldCloneFromDevService(String repositoryName, @TempDir Path tempDir) throws Exception {
try (Git git = Git.cloneRepository().setDirectory(tempDir.toFile())
.setURI(config.devservices().httpUrl().get() + "/quarkus/test-repo.git").call()) {
.setURI(config.devservices().httpUrl().get() + "/quarkus/" + repositoryName + ".git").call()) {
assertThat(tempDir.resolve("README.md")).isRegularFile();
assertThat(git.log().call()).extracting(RevCommit::getFullMessage).map(String::trim).contains("Initial commit");
}
Expand Down

0 comments on commit 362aebe

Please sign in to comment.