Skip to content

Commit

Permalink
Getting the production client to launch
Browse files Browse the repository at this point in the history
  • Loading branch information
shartte committed Nov 24, 2024
1 parent 6c6cb46 commit b5c9fb1
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 41 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/build-prs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ jobs:
- name: Build with Gradle
run: ./gradlew assemble checkFormatting

- name: Test Production Client
run: ./gradlew testProductionClient

- name: Run JCC
if: ${{ ! startsWith(github.event.pull_request.head.ref, 'port/') && ! startsWith(github.ref_name, 'port/') && ! startsWith(github.event.pull_request.base.ref, 'port/') }}
run: ./gradlew checkJarCompatibility
Expand Down
16 changes: 13 additions & 3 deletions buildSrc/src/main/java/net/neoforged/neodev/NeoDevPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import net.neoforged.moddevgradle.tasks.JarJar;
import net.neoforged.neodev.e2e.InstallProductionClient;
import net.neoforged.neodev.e2e.RunProductionClient;
import net.neoforged.neodev.e2e.TestProductionClient;
import net.neoforged.neodev.installer.CreateArgsFile;
import net.neoforged.neodev.installer.CreateInstallerProfile;
import net.neoforged.neodev.installer.CreateLauncherProfile;
Expand Down Expand Up @@ -35,6 +36,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

public class NeoDevPlugin implements Plugin<Project> {
static final String GROUP = "neoforge development";
Expand Down Expand Up @@ -567,15 +569,23 @@ private void setupEndToEndTesting(Project project,
task.getInstallationDir().set(destinationDir);
});

var runClient = project.getTasks().register("runProductionClient", RunProductionClient.class, task -> {
task.setGroup(INTERNAL_GROUP);
task.setDescription("Runs the production client installed by installProductionClient.");
Consumer<RunProductionClient> configureRunProductionClient = task -> {
task.getLibraryFiles().addAll(IdentifiedFile.listFromConfiguration(project, configurations.neoFormClasspath));
task.getLibraryFiles().addAll(IdentifiedFile.listFromConfiguration(project, configurations.launcherProfileClasspath));
task.getAssetPropertiesFile().set(downloadAssets.flatMap(DownloadAssets::getAssetPropertiesFile));
task.getMinecraftVersion().set(minecraftVersion);
task.getNeoForgeVersion().set(neoForgeVersion);
task.getInstallationDir().set(installClient.flatMap(InstallProductionClient::getInstallationDir));
};
project.getTasks().register("runProductionClient", RunProductionClient.class, task -> {
task.setGroup(INTERNAL_GROUP);
task.setDescription("Runs the production client installed by installProductionClient.");
configureRunProductionClient.accept(task);
});
project.getTasks().register("testProductionClient", TestProductionClient.class, task -> {
task.setGroup(INTERNAL_GROUP);
task.setDescription("Tests the production client installed by installProductionClient.");
configureRunProductionClient.accept(task);
});

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,15 @@ public void exec() {

execOperations.javaexec(spec -> {
// The JVM args at this point may include debugging options when started through IntelliJ
spec.jvmArgs(getAllJvmArgs());
spec.jvmArgs(getJvmArguments().get());
spec.environment(getEnvironment());
spec.debugOptions(debug -> {
debug.getEnabled().set(getDebugOptions().getEnabled());
debug.getPort().set(getDebugOptions().getPort());
debug.getSuspend().set(getDebugOptions().getSuspend());
debug.getServer().set(getDebugOptions().getServer());
debug.getHost().set(getDebugOptions().getHost());
});
applyVersionManifest(installDir, "neoforge-" + neoForgeVersion, placeholders, librariesDir, spec);
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package net.neoforged.neodev.e2e;

import org.gradle.api.GradleException;
import org.gradle.process.ExecOperations;

import javax.inject.Inject;
import java.io.File;
import java.time.Duration;
import java.time.temporal.ChronoUnit;

public abstract class TestProductionClient extends RunProductionClient {
@Inject
public TestProductionClient(ExecOperations execOperations) {
super(execOperations);

getTimeout().set(Duration.of(5, ChronoUnit.MINUTES));
}

@Override
public void exec() {
var selfTestReport = new File(getTemporaryDir(), "client_self_test.txt");

environment("NEOFORGE_CLIENT_SELFTEST", selfTestReport.getAbsolutePath());

super.exec();

if (!selfTestReport.exists()) {
throw new GradleException("Missing self test report file after running client: " + selfTestReport);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,16 @@
import net.neoforged.neoforge.common.ModConfigSpec;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.common.NeoForgeMod;
import net.neoforged.neoforge.common.util.SelfTest;
import net.neoforged.neoforge.internal.versions.neoforge.NeoForgeVersion;
import org.jetbrains.annotations.ApiStatus;

@ApiStatus.Internal
@Mod(value = "neoforge", dist = Dist.CLIENT)
public class ClientNeoForgeMod {
public ClientNeoForgeMod(IEventBus modEventBus, ModContainer container) {
SelfTest.initClient();

ClientCommandHandler.init();
TagConventionLogWarningClient.init();

Expand Down
39 changes: 2 additions & 37 deletions src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,9 @@
import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.EnumSet;
import java.util.List;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.UUID;
import java.util.function.Function;
Expand Down Expand Up @@ -83,7 +79,6 @@
import net.neoforged.fml.config.ModConfigs;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.neoforged.fml.event.lifecycle.FMLLoadCompleteEvent;
import net.neoforged.fml.loading.FMLLoader;
import net.neoforged.fml.loading.progress.StartupNotificationManager;
import net.neoforged.neoforge.capabilities.CapabilityHooks;
import net.neoforged.neoforge.common.advancements.critereon.ItemAbilityPredicate;
Expand Down Expand Up @@ -127,6 +122,7 @@
import net.neoforged.neoforge.common.loot.CanItemPerformAbility;
import net.neoforged.neoforge.common.loot.IGlobalLootModifier;
import net.neoforged.neoforge.common.loot.LootTableIdCondition;
import net.neoforged.neoforge.common.util.SelfTest;
import net.neoforged.neoforge.common.world.BiomeModifier;
import net.neoforged.neoforge.common.world.BiomeModifiers;
import net.neoforged.neoforge.common.world.BiomeModifiers.AddFeaturesBiomeModifier;
Expand All @@ -139,7 +135,6 @@
import net.neoforged.neoforge.common.world.StructureModifiers;
import net.neoforged.neoforge.data.event.GatherDataEvent;
import net.neoforged.neoforge.event.server.ServerStoppingEvent;
import net.neoforged.neoforge.event.tick.ServerTickEvent;
import net.neoforged.neoforge.fluids.BaseFlowingFluid;
import net.neoforged.neoforge.fluids.CauldronFluidContent;
import net.neoforged.neoforge.fluids.FluidType;
Expand Down Expand Up @@ -531,7 +526,7 @@ public NeoForgeMod(IEventBus modEventBus, Dist dist, ModContainer container) {
LOGGER.info(NEOFORGEMOD, "NeoForge mod loading, version {}, for MC {}", NeoForgeVersion.getVersion(), DetectedVersion.BUILT_IN.getName());
ForgeSnapshotsMod.logStartupWarning();

handleSelfTest();
SelfTest.initCommon();

CrashReportCallables.registerCrashCallable("Crash Report UUID", () -> {
final UUID uuid = UUID.randomUUID();
Expand Down Expand Up @@ -694,36 +689,6 @@ private static boolean isPRBuild(String neoVersion) {
return neoVersion.matches("\\d+\\.\\d+\\.\\d+(-beta)?-pr-\\d+-[\\w-]+");
}

private static void handleSelfTest() {
String selfTestDestination = System.getenv("NEOFORGE_DEDICATED_SERVER_SELFTEST");
if (selfTestDestination != null) {
if (FMLLoader.getDist() != Dist.DEDICATED_SERVER) {
LOGGER.error("The server self-test ran with a dist of {} instead of dedicated server!", FMLLoader.getDist());
System.exit(1);
}
NeoForge.EVENT_BUS.addListener((ServerTickEvent.Pre e) -> writeSelfTestReport(selfTestDestination));
}
}

/**
* This is used by our GitHub Actions pipeline to run an E2E test for PRs.
* It writes a small self-test report to the file indicated by the system property and exits.
*/
private static void writeSelfTestReport(String path) {
try (var out = new FileOutputStream(path)) {
Properties p = new Properties();
p.setProperty("neoforge_version", NeoForgeVersion.getVersion());
p.setProperty("minecraft_version", DetectedVersion.BUILT_IN.getName());
p.store(out, "");
} catch (IOException e) {
LOGGER.error("Failed to write self-test to '{}'", path, e);
System.exit(1);
}

LOGGER.info("Exiting after writing self-test to '{}'", path);
System.exit(0);
}

public static boolean isPRBuild() {
return isPRBuild;
}
Expand Down
79 changes: 79 additions & 0 deletions src/main/java/net/neoforged/neoforge/common/util/SelfTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforge.common.util;

import net.minecraft.DetectedVersion;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.LoadingOverlay;
import net.minecraft.client.gui.screens.Overlay;
import net.minecraft.server.dedicated.DedicatedServer;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.fml.loading.FMLLoader;
import net.neoforged.neoforge.client.event.ClientTickEvent;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.event.tick.ServerTickEvent;
import net.neoforged.neoforge.internal.versions.neoforge.NeoForgeVersion;
import org.jetbrains.annotations.ApiStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

@ApiStatus.Internal
public final class SelfTest {
private static final Logger LOGGER = LoggerFactory.getLogger(SelfTest.class);

private SelfTest() {
}

public static void initClient() {
var clientSelfTestDestination = System.getenv("NEOFORGE_CLIENT_SELFTEST");
if (clientSelfTestDestination != null) {
NeoForge.EVENT_BUS.addListener((ClientTickEvent.Pre e) -> {
if (Minecraft.getInstance().getOverlay() instanceof LoadingOverlay) {
return;
}
writeSelfTestReport(clientSelfTestDestination);
Minecraft.getInstance().getSoundManager().emergencyShutdown();
Minecraft.getInstance().stop();
});
}
}

public static void initCommon() {
var serverSelfTestDestination = System.getenv("NEOFORGE_DEDICATED_SERVER_SELFTEST");
if (serverSelfTestDestination != null) {
if (FMLLoader.getDist() != Dist.DEDICATED_SERVER) {
LOGGER.error("The server self-test ran with a dist of {} instead of dedicated server!", FMLLoader.getDist());
System.exit(1);
}
NeoForge.EVENT_BUS.addListener((ServerTickEvent.Pre e) -> {
writeSelfTestReport(serverSelfTestDestination);
});
}
}

/**
* This is used by our GitHub Actions pipeline to run an E2E test for PRs.
* It writes a small self-test report to the file indicated by the system property and exits.
*/
private static void writeSelfTestReport(String path) {
try (var out = new FileOutputStream(path)) {
Properties p = new Properties();
p.setProperty("neoforge_version", NeoForgeVersion.getVersion());
p.setProperty("minecraft_version", DetectedVersion.BUILT_IN.getName());
p.store(out, "");
} catch (IOException e) {
LOGGER.error("Failed to write self-test to '{}'", path, e);
System.exit(1);
}

LOGGER.info("Exiting after writing self-test to '{}'", path);
System.exit(0);
}
}

0 comments on commit b5c9fb1

Please sign in to comment.