44
55import java .io .IOException ;
66import java .util .ArrayList ;
7- import java .util .Collections ;
87import java .util .List ;
8+ import java .util .Optional ;
99
1010import org .jboss .logging .Logger ;
1111import org .testcontainers .containers .GenericContainer ;
12+ import org .testcontainers .containers .Network ;
1213
1314import com .github .dockerjava .api .command .InspectContainerResponse ;
1415
@@ -18,21 +19,34 @@ class GiteaContainer extends GenericContainer<GiteaContainer> {
1819 * Logger which will be used to capture container STDOUT and STDERR.
1920 */
2021 private static final Logger log = Logger .getLogger (GiteaContainer .class );
21- private static final int HTTP_PORT = 3000 ;
22+ static final int HTTP_PORT = 3000 ;
2223
2324 private JGitBuildTimeConfig .DevService devServiceConfig ;
25+ private Optional <GiteaDevServiceRequestBuildItem > devServiceRequest ;
26+
27+ private List <String > organizations = new ArrayList <>();
2428 private List <String > repositories = new ArrayList <>();
2529
26- GiteaContainer (JGitBuildTimeConfig .DevService devServiceConfig ) {
30+ GiteaContainer (JGitBuildTimeConfig .DevService devServiceConfig ,
31+ Optional <GiteaDevServiceRequestBuildItem > devServiceRequest ) {
2732 super ("gitea/gitea:latest-rootless" );
2833 this .devServiceConfig = devServiceConfig ;
34+ this .devServiceRequest = devServiceRequest ;
2935 withEnv ("GITEA__security__INSTALL_LOCK" , "true" );
3036 withEnv ("GITEA__server__DISABLE_SSH" , "true" );
3137 withExposedPorts (HTTP_PORT );
3238 withReuse (devServiceConfig .reuse ());
3339 waitingFor (forListeningPorts (HTTP_PORT ));
3440 // Needed for podman (see https://github.com/testcontainers/testcontainers-java/issues/7310)
3541 withStartupAttempts (2 );
42+
43+ Optional <String > networkAlias = devServiceConfig .networkAlias ()
44+ .or (() -> devServiceRequest .map (GiteaDevServiceRequestBuildItem ::getAlias ));
45+ networkAlias .ifPresent (alias -> {
46+ withNetworkAliases (alias );
47+ withNetwork (Network .SHARED );
48+ });
49+
3650 devServiceConfig .httpPort ().ifPresent (port -> addFixedExposedPort (port , HTTP_PORT ));
3751 if (devServiceConfig .showLogs ()) {
3852 withLogConsumer (new JBossLoggingConsumer (log ));
@@ -44,8 +58,23 @@ protected void containerIsStarted(InspectContainerResponse containerInfo, boolea
4458 if (!reused ) {
4559 try {
4660 createAdminUser ();
47- for (String repository : devServiceConfig .repositories ().orElse (Collections .emptyList ())) {
48- createRepository (this , repository );
61+ List <String > organizations = new ArrayList <>();
62+ List <String > repositories = new ArrayList <>();
63+
64+ devServiceConfig .organizations ().ifPresent (o -> organizations .addAll (o ));
65+ devServiceConfig .repositories ().ifPresent (r -> repositories .addAll (r ));
66+
67+ devServiceRequest .map (GiteaDevServiceRequestBuildItem ::getOrganizations )
68+ .ifPresent (o -> organizations .addAll (o ));
69+ devServiceRequest .map (GiteaDevServiceRequestBuildItem ::getRepositories )
70+ .ifPresent (r -> repositories .addAll (r ));
71+
72+ for (String org : organizations ) {
73+ createOrganization (org );
74+ }
75+
76+ for (String repository : repositories ) {
77+ createRepository (repository );
4978 }
5079 } catch (IOException | InterruptedException e ) {
5180 throw new RuntimeException ("Failed to create admin user" , e );
@@ -70,15 +99,56 @@ private void createAdminUser() throws IOException, InterruptedException {
7099 };
71100 log .debug (String .join (" " , cmd ));
72101 ExecResult execResult = execInContainer (cmd );
73- log .info (execResult .getStdout ());
102+ log .debug (execResult .getStdout ());
74103 if (execResult .getExitCode () != 0 ) {
75104 throw new RuntimeException ("Failed to create admin user: " + execResult .getStderr ());
76105 }
77106 }
78107
79- private void createRepository (GiteaContainer giteaContainer , String repository )
108+ private void createOrganization (String org )
109+ throws UnsupportedOperationException , IOException , InterruptedException {
110+ String httpUrl = "http://localhost:" + GiteaContainer .HTTP_PORT + "/api/v1/orgs" ;
111+ String data = """
112+ {"username":"%s"}
113+ """
114+ .formatted (org );
115+
116+ String [] cmd = {
117+ "/usr/bin/curl" ,
118+ "-X" ,
119+ "POST" ,
120+ "--user" ,
121+ devServiceConfig .adminUsername () + ":" + devServiceConfig .adminPassword (),
122+ "-H" ,
123+ "Content-Type: application/json" ,
124+ "-d" ,
125+ data ,
126+ httpUrl
127+ };
128+
129+ log .debug (String .join (" " , cmd ));
130+ ExecResult execResult = execInContainer (cmd );
131+ log .debug (execResult .getStdout ());
132+ if (execResult .getExitCode () != 0 ) {
133+ throw new RuntimeException ("Failed to create organization: " + org + ":" + execResult .getStderr ());
134+ }
135+ organizations .add (org );
136+ log .info ("Created organization: " + org );
137+ }
138+
139+ private void createRepository (String repository ) throws UnsupportedOperationException , IOException , InterruptedException {
140+ if (repository .contains ("/" )) {
141+ String orgName = repository .substring (0 , repository .indexOf ("/" ));
142+ String repoName = repository .substring (repository .indexOf ("/" ) + 1 );
143+ createOrgRepository (orgName , repoName );
144+ } else {
145+ createUserRepository (repository );
146+ }
147+ }
148+
149+ private void createUserRepository (String repository )
80150 throws UnsupportedOperationException , IOException , InterruptedException {
81- String httpUrl = "http://localhost:" + GiteaContainer .HTTP_PORT ;
151+ String httpUrl = "http://localhost:" + GiteaContainer .HTTP_PORT + "/api/v1/user/repos" ;
82152 String data = """
83153 {"name":"%s", "private":false, "auto_init":true, "readme":"Default"}
84154 """
@@ -94,17 +164,81 @@ private void createRepository(GiteaContainer giteaContainer, String repository)
94164 "Content-Type: application/json" ,
95165 "-d" ,
96166 data ,
97- httpUrl + "/api/v1/user/repos"
167+ httpUrl
98168 };
99169
100170 log .debug (String .join (" " , cmd ));
101- ExecResult execResult = giteaContainer . execInContainer (cmd );
102- log .info (execResult .getStdout ());
171+ ExecResult execResult = execInContainer (cmd );
172+ log .debug (execResult .getStdout ());
103173 if (execResult .getExitCode () != 0 ) {
104174 throw new RuntimeException ("Failed to create repository: " + repository + ":" + execResult .getStderr ());
105175 }
106176 repositories .add (repository );
107- log .info ("Created repository: " + repository );
177+ log .info ("Created user repository: " + repository );
178+ }
179+
180+ private void createOrgRepository (String org , String repository )
181+ throws UnsupportedOperationException , IOException , InterruptedException {
182+
183+ if (!organizationExists (org )) {
184+ createOrganization (org );
185+ }
186+
187+ String httpUrl = "http://localhost:" + GiteaContainer .HTTP_PORT + "/api/v1/orgs/" + org + "/repos" ;
188+ String data = """
189+ {"name":"%s", "private":false, "auto_init":true, "readme":"Default"}
190+ """
191+ .formatted (repository );
192+
193+ String [] cmd = {
194+ "/usr/bin/curl" ,
195+ "-X" ,
196+ "POST" ,
197+ "--user" ,
198+ devServiceConfig .adminUsername () + ":" + devServiceConfig .adminPassword (),
199+ "-H" ,
200+ "Content-Type: application/json" ,
201+ "-d" ,
202+ data ,
203+ httpUrl
204+ };
205+
206+ log .debug (String .join (" " , cmd ));
207+ ExecResult execResult = execInContainer (cmd );
208+ log .debug (execResult .getStdout ());
209+ if (execResult .getExitCode () != 0 ) {
210+ throw new RuntimeException ("Failed to create repository: " + repository + ":" + execResult .getStderr ());
211+ }
212+ repositories .add (org + "/" + repository );
213+ log .info ("Created org repository: " + org + "/" + repository );
214+ }
215+
216+ private boolean organizationExists (String org ) throws IOException , InterruptedException {
217+ String httpUrl = "http://localhost:" + GiteaContainer .HTTP_PORT + "/api/v1/orgs/" + org ;
218+
219+ String [] cmd = {
220+ "/usr/bin/curl" ,
221+ "-X" ,
222+ "GET" ,
223+ "--user" ,
224+ devServiceConfig .adminUsername () + ":" + devServiceConfig .adminPassword (),
225+ "-H" ,
226+ "Content-Type: application/json" ,
227+ httpUrl
228+ };
229+
230+ log .debug (String .join (" " , cmd ));
231+ ExecResult execResult = execInContainer (cmd );
232+
233+ if (execResult .getExitCode () == 0 ) {
234+ log .debug ("Organization exists: " + org );
235+ return true ;
236+ } else if (execResult .getExitCode () == 404 ) {
237+ log .debug ("Organization does not exist: " + org );
238+ return false ;
239+ } else {
240+ throw new RuntimeException ("Error checking organization existence: " + execResult .getStderr ());
241+ }
108242 }
109243
110244 public String getHttpUrl () {
@@ -118,4 +252,8 @@ public int getHttpPort() {
118252 public List <String > getRepositories () {
119253 return repositories ;
120254 }
255+
256+ public List <String > getOrganizations () {
257+ return organizations ;
258+ }
121259}
0 commit comments