Attempt to set up updater for gitea
ci/woodpecker/push/docs Pipeline was successful Details
ci/woodpecker/push/woodpecker Pipeline was successful Details

This commit is contained in:
Johannes Frohnmeyer 2022-11-03 17:07:55 +01:00
parent 182d65a442
commit 11a40975d9
Signed by: Johannes
GPG Key ID: E76429612C2929F4
21 changed files with 93 additions and 362 deletions

View File

@ -72,3 +72,19 @@ pipeline:
strip_prefix: public/
when:
- branch: master
publishRelease:
image: woodpeckerci/plugin-s3
settings:
bucket: pages
region: nebula
path_style: true
endpoint: https://s3.frohnmeyer-wds.de
access_key: pages
secret_key:
from_secret: pages_secret
source: public/**/*
target: /${CI_REPO}/stable
strip_prefix: public/
when:
- event: tag
branch: master

View File

@ -21,6 +21,7 @@ val flavor: String by extra(if (flavorProp != "custom") flavorProp else OS.TYPE.
val isPublic by extra(project.hasProperty("public"))
val isRelease by extra(project.hasProperty("release"))
val buildTime by extra(System.currentTimeMillis())
val wrapperVersion by extra(1)
tasks.register("exportMetadata") {
@ -30,6 +31,7 @@ tasks.register("exportMetadata") {
{
"wrapperVersion": $wrapperVersion,
"version": "$version",
"buildTime": $buildTime,
"isPublic": $isPublic,
"isRelease": $isRelease,
"jvm": ${project(":common").extra["javaVersion"]},

View File

@ -18,9 +18,9 @@ sourceSets {
generate(project) {
`class`("io.gitlab.jfronny.inceptum.common", "BuildMetadata") {
val modifiers = "public static final"
import("io.gitlab.jfronny.commons.ComparableVersion")
fieldRaw("VERSION", "ComparableVersion", "new ComparableVersion(\"$version\")", modifiers)
field("VERSION", versionS, modifiers)
field("BUILD_TIME", rootProject.extra["buildTime"] as Long, modifiers)
field("IS_PUBLIC", rootProject.extra["isPublic"] as Boolean, modifiers)
field("IS_RELEASE", rootProject.extra["isRelease"] as Boolean, modifiers)
field("VM_VERSION", javaVersion.majorVersion.toInt(), modifiers)

View File

@ -1,10 +1,7 @@
package io.gitlab.jfronny.inceptum.common;
import io.gitlab.jfronny.commons.ComparableVersion;
import io.gitlab.jfronny.commons.OSUtils;
import io.gitlab.jfronny.inceptum.common.api.GitlabApi;
import io.gitlab.jfronny.inceptum.common.api.MavenApi;
import io.gitlab.jfronny.inceptum.common.model.gitlab.*;
import io.gitlab.jfronny.inceptum.common.model.inceptum.*;
import io.gitlab.jfronny.inceptum.common.model.maven.*;
import org.jetbrains.annotations.Nullable;
@ -22,9 +19,12 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Updater {
private static final String ARTIFACTS_URL = "https://pages.frohnmeyer-wds.de/JfMods/Inceptum/artifacts/";
private static final String STABLE_URL = "https://pages.frohnmeyer-wds.de/JfMods/Inceptum/stable/";
public static final String PROJECT_MAVEN = "https://maven.frohnmeyer-wds.de/artifacts/";
public static UpdateMetadata getUpdate() {
return Updater.check(InceptumConfig.channel, BuildMetadata.VERSION, channel -> {
return Updater.check(InceptumConfig.channel, true, channel -> {
Utils.LOGGER.error("No stable version was found, switching to experimental channel");
InceptumConfig.channel = channel;
InceptumConfig.saveConfig();
@ -113,7 +113,7 @@ public class Updater {
private static DependencyNode downloadLibrary(Set<String> repositories, final String artifact, Set<String> libraries) throws IOException, URISyntaxException {
List<Exception> exceptions = new LinkedList<>();
for (String repository : Stream.concat(Stream.of(GitlabApi.PROJECT_MAVEN), repositories.stream()).toList()) {
for (String repository : Stream.concat(Stream.of(PROJECT_MAVEN), repositories.stream()).toList()) {
Pom pom;
try {
pom = MavenApi.getPom(repository, artifact);
@ -128,7 +128,7 @@ public class Updater {
dependencies.add(downloadLibrary(repositories, mvnName, libraries));
}
}
MavenApi.downloadLibrary(repository, artifact);
MavenApi.downloadLibrary(repository, pom);
libraries.add(artifact);
return new DependencyNode(pom, dependencies);
}
@ -143,44 +143,14 @@ public class Updater {
return MetaHolder.LIBRARIES_DIR.resolve(MavenApi.mavenNotationToJarPath(artifact)).toAbsolutePath();
}
public static @Nullable UpdateMetadata check(UpdateChannel channel, ComparableVersion current, Consumer<UpdateChannel> channelInvalid) {
public static @Nullable UpdateMetadata check(UpdateChannel channel, boolean versionCompare, Consumer<UpdateChannel> channelInvalid) {
try {
int jvm = Runtime.version().feature();
GitlabProject project = GitlabApi.getProject(GitlabApi.PROJECT_ID);
UpdateMetadata experimental = null;
UpdateMetadata experimental = Net.downloadObject(ARTIFACTS_URL + "version.json", GC_UpdateMetadata::read);
UpdateMetadata stable = null;
packageLoop:for (GitlabPackage info : GitlabApi.getPackages(project)) {
if (info.status.equals("default") && info.name.equals("io/gitlab/jfronny/inceptum/Inceptum")) {
for (GitlabPipeline pipeline : info.pipelines) {
if (!pipeline.ref.equals("master")) continue;
if (!pipeline.status.equals("success")) {
Utils.LOGGER.warn("Skipping failed CI build");
continue;
}
for (GitlabJob job : GitlabApi.getJobs(project, pipeline.id)) {
if (!job.name.equals("build_test")) continue;
try {
UpdateMetadata update = Net.downloadObject(GitlabApi.PROJECTS + project.id + "/jobs/" + job.id + "/artifacts/version.json", GC_UpdateMetadata::read);
if (update.jvm > jvm) {
Utils.LOGGER.error("A newer JVM is required to use the latest inceptum version. Please update!");
continue packageLoop;
}
if (experimental == null || experimental.version.compareTo(update.version) < 0) {
experimental = update;
}
if (!info.version.contains("-") && (stable == null || stable.version.compareTo(update.version) < 0)) {
stable = update;
}
} catch (IOException e) {
continue packageLoop;
}
}
}
}
}
if (experimental == null) {
throw new IOException("No version could be found");
} else if (stable == null && channel == UpdateChannel.Stable) {
try {
stable = Net.downloadObject(STABLE_URL + "version.json", GC_UpdateMetadata::read);
} catch (Throwable ignored) {}
if (stable == null && channel == UpdateChannel.Stable) {
channel = UpdateChannel.CI;
channelInvalid.accept(channel);
}
@ -188,19 +158,29 @@ public class Updater {
case CI -> experimental;
case Stable -> stable;
};
Utils.LOGGER.info("Latest version is " + info.version + ", current is " + current);
if (current.compareTo(info.version) >= 0) {
Utils.LOGGER.info("Up-to-date");
if (info.jvm > Runtime.version().feature()) {
//TODO visual indication for this
Utils.LOGGER.error("A newer JVM is required to use the latest inceptum version. Please update!");
return null;
}
if (versionCompare) {
Utils.LOGGER.info("Latest version is " + info.version + ", current is " + BuildMetadata.VERSION);
if (BuildMetadata.BUILD_TIME >= info.buildTime) {
Utils.LOGGER.info("Up-to-date");
return null;
}
}
return info;
} catch (IOException | URISyntaxException e) {
} catch (IOException e) {
Utils.LOGGER.error("Could not check for updates", e);
}
return null;
}
public static String getShadowJarUrl(UpdateMetadata metadata) {
return GitlabApi.PROJECT_MAVEN + "io/gitlab/jfronny/inceptum/Inceptum/" + metadata.version + "/Inceptum-" + metadata.version + "-" + Utils.getCurrentFlavor() + ".jar";
public static String getShadowJarUrl(UpdateChannel channel) {
return switch (channel) {
case CI -> ARTIFACTS_URL;
case Stable -> STABLE_URL;
} + "/Inceptum-" + Utils.getCurrentFlavor() + ".jar";
}
}

View File

@ -1,53 +0,0 @@
package io.gitlab.jfronny.inceptum.common.api;
import io.gitlab.jfronny.commons.HttpUtils;
import io.gitlab.jfronny.gson.compile.util.GList;
import io.gitlab.jfronny.gson.stream.JsonReader;
import io.gitlab.jfronny.inceptum.common.model.gitlab.*;
import java.io.IOException;
import java.io.Reader;
import java.net.URISyntaxException;
import java.util.List;
import java.util.function.Predicate;
public class GitlabApi {
public static final String PROJECTS = "https://gitlab.com/api/v4/projects/";
public static final long PROJECT_ID = 30862253L;
public static final String PROJECT_MAVEN = "https://gitlab.com/api/v4/projects/" + PROJECT_ID + "/packages/maven/";
public static GitlabProject getProject(Long projectId) throws IOException, URISyntaxException {
try (Reader r = HttpUtils.get(PROJECTS + projectId).sendReader()) {
return GC_GitlabProject.read(r);
}
}
public static List<GitlabPackage> getPackages(GitlabProject project) throws IOException, URISyntaxException {
try (JsonReader r = new JsonReader(HttpUtils.get(PROJECTS + project.id + "/packages?order_by=created_at&sort=desc").sendReader())) {
return GList.read(r, GC_GitlabPackage::read);
}
}
public static List<GitlabJob> getJobs(GitlabProject project, Long pipelineId) throws IOException, URISyntaxException {
try (JsonReader r = new JsonReader(HttpUtils.get(PROJECTS + project.id + "/pipelines/" + pipelineId + "/jobs").sendReader())) {
List<GitlabJob> list = GList.read(r, GC_GitlabJob::read);
list.sort((left, right) -> right.created_at.compareTo(left.created_at));
return list;
}
}
public static GitlabPackageFile getFile(GitlabProject project, GitlabPackage packageInfo, Predicate<GitlabPackageFile> isValid) throws IOException, URISyntaxException {
int page = 0;
while (true) {
try (JsonReader r = new JsonReader(HttpUtils.get(PROJECTS + project.id + "/packages/" + packageInfo.id + "/package_files?per_page=100&page=" + ++page).sendReader())) {
List<GitlabPackageFile> files = GList.read(r, GC_GitlabPackageFile::read);
if (files.isEmpty()) return null;
for (GitlabPackageFile file : files) {
if (isValid.test(file))
return file;
}
}
}
}
}

View File

@ -28,10 +28,20 @@ public class MavenApi {
}
}
public static Path downloadLibrary(String repo, String artifact) throws IOException, URISyntaxException {
String path = mavenNotationToJarPath(artifact);
Path res = MetaHolder.LIBRARIES_DIR.resolve(path);
Net.downloadFile(Utils.join("/", repo, path), res);
public static Path downloadLibrary(String repo, Pom pom) throws IOException, URISyntaxException {
String artifact = pom.groupId + ':' + pom.artifactId + ':' + pom.version;
String rawArtifact = artifact;
if (pom.classifier != null || pom.snapshotVersion != null) {
artifact += ':';
if (pom.snapshotVersion != null) artifact += pom.snapshotVersion;
if (pom.classifier != null) {
if (pom.snapshotVersion != null) artifact += '-';
artifact += pom.classifier;
}
}
if (pom.classifier != null) rawArtifact += ':' + pom.classifier;
Path res = MetaHolder.LIBRARIES_DIR.resolve(mavenNotationToJarPath(rawArtifact));
Net.downloadFile(Utils.join("/", repo, mavenNotationToJarPath(artifact)), res);
return res;
}
@ -94,6 +104,25 @@ public class MavenApi {
}
}
}
case "classifier" -> result.classifier = node.getTextContent();
case "versioning" -> {
for (Node node1 : iterable(node.getChildNodes())) {
if (node1.getNodeName().equals("snapshot")) {
String timestamp = null;
String buildNumber = null;
for (Node node2 : iterable(node1.getChildNodes())) {
switch (node2.getNodeName()) {
case "timestamp" -> timestamp = node2.getTextContent();
case "buildNumber" -> buildNumber = node2.getTextContent();
default -> {}
}
}
if (timestamp == null) throw new IOException("Pom snapshots lack timestamp");
if (buildNumber == null) throw new IOException("Pom snapshots lack buildNumber");
result.snapshotVersion = timestamp + '-' + buildNumber;
}
}
}
default -> {}
}
}

View File

@ -1,11 +0,0 @@
package io.gitlab.jfronny.inceptum.common.model.gitlab;
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
@GSerializable
public class GitlabArtifact {
public String file_type;
public Long size;
public String filename;
public String file_format;
}

View File

@ -1,23 +0,0 @@
package io.gitlab.jfronny.inceptum.common.model.gitlab;
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
import java.util.Date;
import java.util.List;
@GSerializable
public class GitlabCommit {
public String id;
public String short_id;
public Date created_at;
public List<String> parent_ids;
public String title;
public String message;
public String author_name;
public String author_email;
public Date authored_date;
public String committer_name;
public String committer_email;
public Date committed_date;
public String web_url;
}

View File

@ -1,29 +0,0 @@
package io.gitlab.jfronny.inceptum.common.model.gitlab;
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
import java.util.Date;
import java.util.List;
@GSerializable
public class GitlabJob {
public Long id;
public String status;
public String stage;
public String name;
public String ref;
public Boolean tag;
public Boolean allow_failure;
public Date created_at;
public Date started_at;
public Date finished_at;
public Double duration;
public Double queued_duration;
public GitlabUser user;
public GitlabCommit commit;
public GitlabPipeline pipeline;
public String web_url;
public List<GitlabArtifact> artifacts;
public GitlabRunner runner;
public Date artifacts_expire_at;
}

View File

@ -1,17 +0,0 @@
package io.gitlab.jfronny.inceptum.common.model.gitlab;
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
import java.util.Date;
import java.util.List;
@GSerializable
public class GitlabPackage {
public Long id;
public String name;
public String version;
public String package_type;
public String status;
public Date created_at;
public List<GitlabPipeline> pipelines;
}

View File

@ -1,19 +0,0 @@
package io.gitlab.jfronny.inceptum.common.model.gitlab;
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
import java.util.Date;
import java.util.List;
@GSerializable
public class GitlabPackageFile {
public Long id;
public Long package_id;
public Date created_at;
public String file_name;
public Integer size;
public String file_md5;
public String file_sha1;
public String file_sha256;
public List<GitlabPipeline> pipelines;
}

View File

@ -1,19 +0,0 @@
package io.gitlab.jfronny.inceptum.common.model.gitlab;
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
import java.util.Date;
@GSerializable
public class GitlabPipeline {
public long id;
public long project_id;
public String sha;
public String ref;
public String status;
public String source;
public Date created_at;
public Date updated_at;
public String web_url;
public GitlabUser user;
}

View File

@ -1,89 +0,0 @@
package io.gitlab.jfronny.inceptum.common.model.gitlab;
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
import java.util.Date;
@GSerializable
public class GitlabProject {
public Long id;
public String description;
public String name;
public String name_with_namespace;
public String path;
public String path_with_namespace;
public String created_at;
public String default_branch;
public String ssh_url_to_repo;
public String http_url_to_repo;
public String web_url;
public String readme_url;
public String avatar_url;
public Integer forks_count;
public Integer star_count;
public Date last_activity_at;
public Boolean packages_enabled;
public Boolean empty_repo;
public Boolean archived;
public String visibility;
public GitlabUser owner;
public Boolean resolve_outdated_diff_discussions;
public Boolean issues_enabled;
public Boolean merge_requests_enabled;
public Boolean wiki_enabled;
public Boolean jobs_enabled;
public Boolean snippets_enabled;
public Boolean container_registry_enabled;
public Boolean service_desk_enabled;
public String service_desk_address;
public Boolean can_create_merge_request_in;
public String issues_access_level;
public String repository_access_level;
public String merge_request_access_level;
public String forking_access_level;
public String wiki_access_level;
public String builds_access_level;
public String snippets_access_level;
public String pages_access_level;
public String operations_access_level;
public String analytics_access_level;
public String container_registry_access_level;
public Boolean emails_disabled;
public Boolean shared_runners_enabled;
public Boolean lfs_enabled;
public Long creator_id;
public String import_status;
public Integer open_issues_count;
public String runners_token;
public Integer ci_default_git_depth;
public Boolean ci_forward_deployment_enabled;
public Boolean ci_job_token_scope_enabled;
public Boolean public_jobs;
public String build_git_strategy;
public Integer build_timeout;
public String auto_cancel_pending_pipelines;
public String build_coverage_regex;
public String ci_config_path;
public Boolean only_allow_merge_if_pipeline_succeeds;
public Boolean restrict_user_defined_variables;
public Boolean request_access_enabled;
public Boolean only_allow_merge_if_all_discussions_are_resolved;
public Boolean remove_source_branch_after_merge;
public Boolean printing_merge_request_link_enabled;
public String merge_method;
public String squash_option;
public String suggestion_commit_message;
public Boolean auto_devops_enabled;
public String auto_devops_strategy;
public Boolean autoclose_referenced_issues;
public Boolean keep_latest_artifact;
public Integer approvals_before_merge;
public Boolean mirror;
public String external_authorization_classification_label;
public Integer requirements_enabled;
public Integer security_and_compliance_enabled;
public String issues_template;
public String merge_requests_template;
public Boolean merge_pipelines_enabled;
public Boolean merge_trains_enabled;
}

View File

@ -1,16 +0,0 @@
package io.gitlab.jfronny.inceptum.common.model.gitlab;
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
@GSerializable
public class GitlabRunner {
public Long id;
public String description;
public String ip_address;
public Boolean active;
public Boolean is_shared;
public String runner_type;
public String name;
public Boolean online;
public String deprecated_rest_status;
}

View File

@ -1,13 +0,0 @@
package io.gitlab.jfronny.inceptum.common.model.gitlab;
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
@GSerializable
public class GitlabUser {
public long id;
public String name;
public String username;
public String state;
public String avatar_url;
public String web_url;
}

View File

@ -1,6 +1,5 @@
package io.gitlab.jfronny.inceptum.common.model.inceptum;
import io.gitlab.jfronny.commons.ComparableVersion;
import io.gitlab.jfronny.gson.compile.annotations.GSerializable;
import java.util.*;
@ -8,18 +7,11 @@ import java.util.*;
@GSerializable
public class UpdateMetadata {
public Integer wrapperVersion;
public ComparableVersion version;
public String version;
public Long buildTime;
public Boolean isPublic;
public Boolean isRelease;
public Integer jvm;
public Set<String> repositories;
public Map<String, Set<String>> natives;
// For serialization
public String getVersion() {
return version == null ? null : version.toString();
}
public void setVersion(String version) {
this.version = new ComparableVersion(version);
}
}

View File

@ -9,6 +9,8 @@ public class Pom {
public String groupId;
public String artifactId;
public String version;
public String classifier;
public String snapshotVersion;
@Nullable public String packaging;
@Nullable public List<MavenDependency> dependencies;
}

View File

@ -1,11 +1,11 @@
# CLI
Inceptum provides a CLI which performs similar functions to the GUI. If you have feature requests, [open an issue](https://gitlab.com/jfmods/inceptum/-/issues)
Inceptum provides a CLI which performs similar functions to the GUI. If you have feature requests, [open an issue](https://helpdesk.frohnmeyer-wds.de/issue?repo=Inceptum&owner=JfMods)
To view up-to-date information on the commands provided by Inceptum, run `inceptum help` or `inceptum help <command>`, this page is intended to explain more advanced features
## The inceptum wrapper
Inceptum Wrapper looks through the libraries dir and launches the latest available Inceptum version.
If it doesn't find a usable version, it will download the latest from GitLab.
If it doesn't find a usable version, it will download the latest available version automatically.
Launching is performed through a custom ClassLoader and an internal flag is set to inform the launched version about the wrappers' presence.
## The "batch" command

View File

@ -77,7 +77,7 @@ public class GuiMain {
} else {
LauncherEnv.showOkCancel("An update was found. Automatic installs are not supported without the wrapper but you can download it nonetheless", "Update found", () -> {
try {
Utils.openWebBrowser(new URI(Updater.getShadowJarUrl(update)));
Utils.openWebBrowser(new URI(Updater.getShadowJarUrl(InceptumConfig.channel)));
exit();
} catch (URISyntaxException e) {
LauncherEnv.showError("Could not download update", e);

View File

@ -2,14 +2,15 @@ package io.gitlab.jfronny.inceptum.launcher.system.setup.steps;
import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.inceptum.common.*;
import io.gitlab.jfronny.inceptum.common.api.GitlabApi;
import io.gitlab.jfronny.inceptum.common.api.MavenApi;
import io.gitlab.jfronny.inceptum.launcher.model.inceptum.ArtifactInfo;
import io.gitlab.jfronny.inceptum.launcher.model.mojang.VersionInfo;
import io.gitlab.jfronny.inceptum.launcher.system.setup.Step;
import io.gitlab.jfronny.inceptum.launcher.util.*;
import io.gitlab.jfronny.inceptum.launcher.system.setup.SetupStepInfo;
import org.xml.sax.SAXException;
import javax.xml.stream.XMLStreamException;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.*;
@ -52,8 +53,8 @@ public class DownloadLibrariesStep implements Step {
String artifact = getLaunchWrapperArtifact();
if (!Files.exists(MetaHolder.LIBRARIES_DIR.resolve(MavenApi.mavenNotationToJarPath(artifact)))) {
try {
MavenApi.downloadLibrary(GitlabApi.PROJECT_MAVEN, artifact);
} catch (URISyntaxException e) {
MavenApi.downloadLibrary(Updater.PROJECT_MAVEN, MavenApi.getPom(Updater.PROJECT_MAVEN, artifact));
} catch (URISyntaxException | XMLStreamException | SAXException e) {
throw new IOException("Could not download launchwrapper", e);
}
}

View File

@ -1,7 +1,5 @@
package io.gitlab.jfronny.inceptum.wrapper;
import io.gitlab.jfronny.commons.ComparableVersion;
import io.gitlab.jfronny.commons.io.JFiles;
import io.gitlab.jfronny.inceptum.common.*;
import io.gitlab.jfronny.inceptum.common.model.inceptum.*;
@ -18,7 +16,7 @@ public class Wrapper {
System.out.println("Loading from " + MetaHolder.BASE_PATH);
InceptumEnvironmentInitializer.initialize();
if (!Files.exists(MetaHolder.WRAPPER_CONFIG_PATH)) {
UpdateMetadata update = Updater.check(UpdateChannel.Stable, new ComparableVersion("0"), R::nop);
UpdateMetadata update = Updater.check(UpdateChannel.Stable, false, R::nop);
if (update == null) {
throw new FileNotFoundException("Could not identify a valid inceptum version. Are you connected to the internet?");
}