diff --git a/build.gradle b/build.gradle index 5553e8ac4..a9facd392 100644 --- a/build.gradle +++ b/build.gradle @@ -1,3 +1,5 @@ +import io.izzel.arclight.gradle.tasks.UploadFilesTask + allprojects { apply plugin: 'java' @@ -56,3 +58,22 @@ tasks.register('collect', Copy) { from project(':bootstrap').tasks.neoforgeJar.outputs from project(':bootstrap').tasks.fabricJar.outputs } + +def gitBranch() { + def stdout = new ByteArrayOutputStream() + exec { + commandLine 'git', 'rev-parse', '--abbrev-ref', 'HEAD' + standardOutput = stdout + } + return stdout.toString().trim() +} + +tasks.register('uploadFiles', UploadFilesTask) { + mcVersion.set project.ext.minecraftVersion + version.set "${project.version}-${project.ext.gitHash}" + snapshot.set project.version.toString().endsWith("-SNAPSHOT") + gitHash.set project.ext.gitHash + branch.set gitBranch() + inputs.files tasks.collect.outputs.files + dependsOn(tasks.collect) +} diff --git a/buildSrc/src/main/groovy/io/izzel/arclight/gradle/Utils.groovy b/buildSrc/src/main/groovy/io/izzel/arclight/gradle/Utils.groovy index f40bda6b8..3b4db958d 100644 --- a/buildSrc/src/main/groovy/io/izzel/arclight/gradle/Utils.groovy +++ b/buildSrc/src/main/groovy/io/izzel/arclight/gradle/Utils.groovy @@ -2,6 +2,7 @@ package io.izzel.arclight.gradle import java.nio.file.Files import java.nio.file.StandardCopyOption +import java.security.MessageDigest import java.util.function.Consumer class Utils { @@ -29,4 +30,12 @@ class Utils { o.write(buf, 0, len) } } + + static String sha1(File file) { + MessageDigest md = MessageDigest.getInstance('SHA-1') + file.eachByte 4096, { bytes, size -> + md.update(bytes, 0 as byte, size) + } + return md.digest().collect { String.format "%02x", it }.join() + } } diff --git a/buildSrc/src/main/groovy/io/izzel/arclight/gradle/tasks/GenerateInstallerInfo.groovy b/buildSrc/src/main/groovy/io/izzel/arclight/gradle/tasks/GenerateInstallerInfo.groovy index 4313fb43a..4d50ea98c 100644 --- a/buildSrc/src/main/groovy/io/izzel/arclight/gradle/tasks/GenerateInstallerInfo.groovy +++ b/buildSrc/src/main/groovy/io/izzel/arclight/gradle/tasks/GenerateInstallerInfo.groovy @@ -10,7 +10,6 @@ import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskAction import java.nio.file.Files -import java.security.MessageDigest class GenerateInstallerInfo extends DefaultTask { @@ -93,13 +92,6 @@ class GenerateInstallerInfo extends DefaultTask { void run() { def libs = configurationDeps(this.configuration) def fabricLibs = configurationDeps(this.fabricExtra) - def sha1 = { file -> - MessageDigest md = MessageDigest.getInstance('SHA-1') - file.eachByte 4096, { bytes, size -> - md.update(bytes, 0 as byte, size) - } - return md.digest().collect { String.format "%02x", it }.join() - } def artifacts = { List arts -> def ret = new HashMap() def cfg = project.configurations.create("art_rev_" + System.currentTimeMillis()) @@ -123,7 +115,7 @@ class GenerateInstallerInfo extends DefaultTask { desc += ":${art.classifier}" if (art.extension != 'jar') desc += "@${art.extension}" - ret.put(desc.toString(), sha1(art.file)) + ret.put(desc.toString(), Utils.sha1(art.file)) } return arts.collectEntries { [(it.toString()): ret.get(it.toString())] } } @@ -140,11 +132,11 @@ class GenerateInstallerInfo extends DefaultTask { installer : [ minecraft : minecraftVersion, forge : forgeVersion, - forgeHash : sha1(tmpInstaller.toFile()), + forgeHash : Utils.sha1(tmpInstaller.toFile()), neoforge : neoforgeVersion, - neoforgeHash : sha1(tmpNeoforge.toFile()), + neoforgeHash : Utils.sha1(tmpNeoforge.toFile()), fabricLoader : fabricLoaderVersion, - fabricLoaderHash: sha1(tmpFabric.toFile()), + fabricLoaderHash: Utils.sha1(tmpFabric.toFile()), ], libraries : artifacts(libs), fabricExtra: artifacts(fabricLibs) diff --git a/buildSrc/src/main/groovy/io/izzel/arclight/gradle/tasks/UploadFilesTask.groovy b/buildSrc/src/main/groovy/io/izzel/arclight/gradle/tasks/UploadFilesTask.groovy new file mode 100644 index 000000000..d6cd20ef9 --- /dev/null +++ b/buildSrc/src/main/groovy/io/izzel/arclight/gradle/tasks/UploadFilesTask.groovy @@ -0,0 +1,95 @@ +package io.izzel.arclight.gradle.tasks + +import groovy.json.JsonOutput +import io.izzel.arclight.gradle.Utils +import org.gradle.api.DefaultTask +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.TaskAction + +import java.nio.charset.StandardCharsets +import java.nio.file.Files + +abstract class UploadFilesTask extends DefaultTask { + + @Input + abstract Property getMcVersion() + + @Input + abstract Property getVersion() + + @Input + abstract Property getSnapshot() + + @Input + abstract Property getGitHash() + + @Input + abstract Property getBranch() + + @TaskAction + void run() { + for (def file in inputs.files.asFileTree.files) { + if (file.isFile()) { + try { + this.uploadOne(file) + } catch (Exception e) { + project.logger.error("Error uploading $file", e) + throw e + } + } + } + } + + private static final String OBJECTS = "https://files.hypertention.cn/v1/objects/%s" + private static final String FILES = "https://files.hypertention.cn/v1/files%s" + + private void uploadOne(File file) { + def sha1 = Utils.sha1(file) + def modloader = file.name.split('-')[1] + project.logger.lifecycle("Uploading {}, sha1 {}", file.name, sha1) + (new URL(OBJECTS.formatted(sha1)).openConnection() as HttpURLConnection).with { + it.setRequestMethod("PUT") + it.doOutput = true + it.addRequestProperty("X-Lightning-Sha1", sha1) + it.addRequestProperty("X-Lightning-Filename", file.name.replace(".jar", "-" + gitHash.get() + ".jar")) + it.addRequestProperty("AuthToken", System.getenv().ARCLIGHT_FILES_TOKEN) + it.addRequestProperty("Content-Type", "application/java-archive") + it.addRequestProperty("Content-Length", Files.size(file.toPath()).toString()) + it.setInstanceFollowRedirects(true) + it.connect() + Utils.using(it.outputStream) { + Files.copy(file.toPath(), it) + } + if (it.responseCode != 200) { + def reason = new String(it.inputStream.readAllBytes()) + project.logger.error(reason) + throw new Exception(reason) + } + } + link("/arclight/branches/${branch.get()}/versions-snapshot/${version.get()}/${modloader}", [type: 'object', value: sha1]) + link("/arclight/branches/${branch.get()}/latest-snapshot", [type: 'link', value: "/arclight/branches/${branch.get()}/versions-snapshot/${version.get()}", cache_seconds: 3600]) + if (!snapshot.get()) { + link("/arclight/branches/${branch.get()}/versions-stable/${version.get()}/${modloader}", [type: 'object', value: sha1]) + link("/arclight/branches/${branch.get()}/latest-stable", [type: 'link', value: "/arclight/branches/${branch.get()}/versions-stable/${version.get()}", cache_seconds: 86400]) + } + } + + private static void link(String path, Object payload) { + (new URL(FILES.formatted(path)).openConnection() as HttpURLConnection).with { + it.setRequestMethod("PUT") + it.doOutput = true + it.addRequestProperty("Content-Type", "application/json") + it.addRequestProperty("AuthToken", System.getenv().ARCLIGHT_FILES_TOKEN) + it.connect() + Utils.using(it.outputStream) { + it.write(JsonOutput.toJson(payload).getBytes(StandardCharsets.UTF_8)) + } + if (it.responseCode != 200) { + def reason = new String(it.inputStream.readAllBytes()) + project.logger.error(reason) + throw new Exception(reason) + } + } + } +}