Skip to content

Commit

Permalink
Merge pull request #147 from Nookure/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
Angelillo15 authored Dec 28, 2024
2 parents 58802cf + 043483f commit 0c3aff4
Show file tree
Hide file tree
Showing 13 changed files with 299 additions and 0 deletions.
3 changes: 3 additions & 0 deletions NookureStaff-API/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ dependencies {
annotationProcessor(libs.auto.service)
annotationProcessor(libs.google.auto.value.processor)
implementation(libs.google.auto.value.annotations)

testImplementation(libs.guice)
testImplementation(libs.gson)
}

publishing {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,7 @@ public final class Constants {
public static final String JENKINS_BUILD_ID = "{{ jenkinsBuildId }}";
public static final String JENKINS_BUILD_URL = "{{ jenkinsBuildUrl }}";

public static final String JENKINS_JOB_NAME = "NookureStaff";

private Constants() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package com.nookure.staff.api.jenkins;

import com.google.auto.service.AutoService;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.inject.Singleton;
import com.nookure.staff.api.jenkins.json.JenkinsArtifact;
import com.nookure.staff.api.jenkins.json.JenkinsBuild;
import com.nookure.staff.api.jenkins.json.JenkinsJob;
import com.nookure.staff.api.jenkins.json.JenkinsRun;
import com.nookure.staff.api.jenkins.json.serializer.JenkinsArtifactDeserializer;
import com.nookure.staff.api.jenkins.json.serializer.JenkinsBuildDeserializer;
import com.nookure.staff.api.jenkins.json.serializer.JenkinsJobDeserializer;
import com.nookure.staff.api.jenkins.json.serializer.JenkinsRunDeserializer;
import org.jetbrains.annotations.NotNull;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;

@Singleton
@AutoService(JenkinsBaseClient.class)
public class JenkinsBaseClient {
private static final String agentName = "NookureStaff-API";

private final String jenkinsUrl;
private final URI jenkinsUri;
private final HttpClient httpClient;

private final Gson gson = new GsonBuilder()
.registerTypeAdapter(JenkinsBuild.class, new JenkinsBuildDeserializer())
.registerTypeAdapter(JenkinsArtifact.class, new JenkinsArtifactDeserializer())
.registerTypeAdapter(JenkinsRun.class, new JenkinsRunDeserializer())
.registerTypeAdapter(JenkinsJob.class, new JenkinsJobDeserializer())
.create();

public JenkinsBaseClient(@NotNull final String jenkinsUrl) {
this.jenkinsUrl = jenkinsUrl;
this.jenkinsUri = URI.create(jenkinsUrl);
this.httpClient = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.build();
}

public @NotNull CompletableFuture<JenkinsJob> getJob(@NotNull final String jobName) {
return httpClient.sendAsync(HttpRequest.newBuilder()
.uri(URI.create(jenkinsUrl + "/job/" + jobName + "/api/json"))
.header("User-Agent", agentName)
.build(), HttpResponse.BodyHandlers.ofString())
.thenApply(response -> gson.fromJson(response.body(), JenkinsJob.class));
}

public @NotNull CompletableFuture<JenkinsRun> getRun(@NotNull final String jobName, final int runNumber) {
return httpClient.sendAsync(HttpRequest.newBuilder()
.uri(URI.create(jenkinsUrl + "/job/" + jobName + "/" + runNumber + "/api/json"))
.header("User-Agent", agentName)
.build(), HttpResponse.BodyHandlers.ofString())
.thenApply(response -> gson.fromJson(response.body(), JenkinsRun.class));
}

public @NotNull CompletableFuture<JenkinsRun> getRun(@NotNull JenkinsJob job, final int runNumber) {
return getRun(job.name(), runNumber);
}

public @NotNull HttpClient getHttpClient() {
return httpClient;
}

public @NotNull String getJenkinsUrl() {
return jenkinsUrl;
}

public @NotNull URI getJenkinsUri() {
return jenkinsUri;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.nookure.staff.api.jenkins.json;

import org.jetbrains.annotations.NotNull;

public record JenkinsArtifact(
@NotNull String displayPath,
@NotNull String fileName,
@NotNull String relativePath
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.nookure.staff.api.jenkins.json;

import org.jetbrains.annotations.NotNull;

public record JenkinsBuild(
@NotNull String _class,
int number,
@NotNull String url
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.nookure.staff.api.jenkins.json;

public record JenkinsJob(
String displayName,
String fullDisplayName,
String name,
String url,
JenkinsBuild[] builds,
JenkinsBuild lastCompletedBuild,
JenkinsBuild lastStableBuild,
JenkinsBuild lastSuccessfulBuild
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.nookure.staff.api.jenkins.json;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public record JenkinsRun(
@NotNull String _class,
boolean building,
@Nullable String description,
long duration,
@NotNull String fullDisplayName,
@NotNull String url,
@NotNull JenkinsArtifact[] artifacts
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.nookure.staff.api.jenkins.json.serializer;

import com.google.common.base.Preconditions;
import com.google.gson.*;
import com.nookure.staff.api.jenkins.json.JenkinsArtifact;

import java.lang.reflect.Type;

public class JenkinsArtifactDeserializer implements JsonDeserializer<JenkinsArtifact> {
@Override
public JenkinsArtifact deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
final JsonObject jsonObject = jsonElement.getAsJsonObject();

final String displayPath = jsonObject.get("displayPath").getAsString();
final String fileName = jsonObject.get("fileName").getAsString();
final String relativePath = jsonObject.get("relativePath").getAsString();

Preconditions.checkNotNull(displayPath, "displayPath cannot be null");
Preconditions.checkNotNull(fileName, "fileName cannot be null");
Preconditions.checkNotNull(relativePath, "relativePath cannot be null");

return new JenkinsArtifact(displayPath, fileName, relativePath);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.nookure.staff.api.jenkins.json.serializer;

import com.google.gson.*;
import com.nookure.staff.api.jenkins.json.JenkinsBuild;

import java.lang.reflect.Type;

import static java.util.Objects.requireNonNull;

public class JenkinsBuildDeserializer implements JsonDeserializer<JenkinsBuild> {
@Override
public JenkinsBuild deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
JsonObject jsonObject = jsonElement.getAsJsonObject();

return new JenkinsBuild(
requireNonNull(jsonObject.get("_class").getAsString()),
jsonObject.get("number").getAsInt(),
requireNonNull(jsonObject.get("url").getAsString())
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.nookure.staff.api.jenkins.json.serializer;

import com.google.gson.*;
import com.nookure.staff.api.jenkins.json.JenkinsBuild;
import com.nookure.staff.api.jenkins.json.JenkinsJob;

import java.lang.reflect.Type;

import static java.util.Objects.requireNonNull;

public class JenkinsJobDeserializer implements JsonDeserializer<JenkinsJob> {
@Override
public JenkinsJob deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
JsonObject jsonObject = jsonElement.getAsJsonObject();

return new JenkinsJob(
requireNonNull(jsonObject.get("displayName").getAsString()),
requireNonNull(jsonObject.get("fullDisplayName").getAsString()),
requireNonNull(jsonObject.get("name").getAsString()),
requireNonNull(jsonObject.get("url").getAsString()),
jsonDeserializationContext.deserialize(jsonObject.get("builds"), JenkinsBuild[].class),
jsonDeserializationContext.deserialize(jsonObject.get("lastCompletedBuild"), JenkinsBuild.class),
jsonDeserializationContext.deserialize(jsonObject.get("lastStableBuild"), JenkinsBuild.class),
jsonDeserializationContext.deserialize(jsonObject.get("lastSuccessfulBuild"), JenkinsBuild.class)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.nookure.staff.api.jenkins.json.serializer;

import com.google.gson.*;
import com.nookure.staff.api.jenkins.json.JenkinsArtifact;
import com.nookure.staff.api.jenkins.json.JenkinsRun;

import java.lang.reflect.Type;

import static java.util.Objects.requireNonNull;

public class JenkinsRunDeserializer implements JsonDeserializer<JenkinsRun> {
@Override
public JenkinsRun deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
JsonObject jsonObject = jsonElement.getAsJsonObject();

String description = jsonObject.has("description") && !jsonObject.get("description").isJsonNull()
? jsonObject.get("description").getAsString()
: null;

return new JenkinsRun(
requireNonNull(jsonObject.get("_class").getAsString()),
jsonObject.get("building").getAsBoolean(),
description,
jsonObject.get("duration").getAsLong(),
requireNonNull(jsonObject.get("fullDisplayName").getAsString()),
requireNonNull(jsonObject.get("url").getAsString()),
jsonDeserializationContext.deserialize(jsonObject.get("artifacts"), JenkinsArtifact[].class)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.nookure.staff.api.jenkins;

import com.nookure.staff.Constants;
import com.nookure.staff.api.jenkins.json.JenkinsJob;
import com.nookure.staff.api.jenkins.json.JenkinsRun;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIf;

public class JenkinsTest {
private final String host = System.getenv("JENKINS_HOST") != null ? System.getenv("JENKINS_HOST") : "https://ci.nookure.com";
private final JenkinsBaseClient jenkinsBaseClient = new JenkinsBaseClient(host);

@Test
@EnabledIf("canRun")
public void testGetJob() {
final JenkinsJob jenkinsJob = jenkinsBaseClient.getJob("NookureStaff").join();
assert jenkinsJob != null;
}

@Test
@EnabledIf("canRun")
public void testGetRun() {
final JenkinsJob jenkinsJob = jenkinsBaseClient.getJob(Constants.JENKINS_JOB_NAME).join();
final JenkinsRun jenkinsRun = jenkinsBaseClient.getRun(jenkinsJob, jenkinsJob.lastCompletedBuild().number()).join();

assert jenkinsRun != null;
}

public static boolean canRun() {
return System.getenv("JENKINS_HOST") != null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.nookure.staff.api.Logger;
import com.nookure.staff.api.NookureStaffPlatform;
import com.nookure.staff.api.command.Command;
import com.nookure.staff.api.jenkins.JenkinsBaseClient;
import com.nookure.staff.api.util.ServerUtils;
import com.nookure.staff.lib.DefaultLibRepo;
import com.nookure.staff.paper.NookureStaff;
Expand All @@ -27,6 +28,7 @@
public class StaffBootstrapper extends JavaPlugin implements NookureStaffPlatform<JavaPlugin> {
public static final boolean isPaper;
public static final boolean isMock;
public static final String JENKINS_URL;

static {
isPaper = ServerUtils.isPaper;
Expand All @@ -41,6 +43,8 @@ public class StaffBootstrapper extends JavaPlugin implements NookureStaffPlatfor
}

isMock = isMockTemp;

JENKINS_URL = System.getProperty("nkStaffJenkinsHost") != null ? System.getProperty("nkStaffJenkinsHost") : "https://ci.nookure.com";
}

private boolean debug = false;
Expand Down Expand Up @@ -70,6 +74,7 @@ public void onEnable() {
loadLogger();
loadDependencies();
checkMAStaff();
checkVersion();

loadInjector();
loadPlugin();
Expand All @@ -78,6 +83,35 @@ public void onEnable() {
plugin.onEnable();
}

public void checkVersion() {
if (Constants.JENKINS_BUILD_NUMBER == -1) {
getLogger().warning("You are using a development build. Please, consider this before reporting any issue.");
return;
}

JenkinsBaseClient jenkinsBaseClient = new JenkinsBaseClient(JENKINS_URL);

jenkinsBaseClient.getJob(Constants.JENKINS_JOB_NAME).thenAccept(jenkinsJob -> {
if (jenkinsJob == null) {
getLogger().warning("Couldn't get the latest version from Jenkins.");
return;
}

if (jenkinsJob.lastCompletedBuild() == null) {
getLogger().warning("Couldn't get the latest version from Jenkins.");
return;
}

if (jenkinsJob.lastCompletedBuild().number() > Constants.JENKINS_BUILD_NUMBER) {
getLogger().warning("There is a new version available! Please update to the latest version.");
getLogger().warning("You can download it from here: " + jenkinsJob.lastCompletedBuild().url());
}
}).exceptionally(throwable -> {
getLogger().warning("Couldn't get the latest version from Jenkins.");
return null;
});
}

public void checkMAStaff() {
if (Bukkit.getPluginManager().getPlugin("MAStaff") != null) {
sendComponent(Component.text("MAStaff detected!").color(NamedTextColor.RED));
Expand Down

0 comments on commit 0c3aff4

Please sign in to comment.