diff --git a/HMCL/build.gradle.kts b/HMCL/build.gradle.kts index 5b5607e9a..ba54ab261 100644 --- a/HMCL/build.gradle.kts +++ b/HMCL/build.gradle.kts @@ -1,8 +1,11 @@ +import org.jackhuang.hmcl.gradle.ci.GitHubActionUtils +import org.jackhuang.hmcl.gradle.ci.JenkinsUtils import org.jackhuang.hmcl.gradle.l10n.CheckTranslations import org.jackhuang.hmcl.gradle.l10n.CreateLanguageList import org.jackhuang.hmcl.gradle.l10n.CreateLocaleNamesResourceBundle import org.jackhuang.hmcl.gradle.l10n.UpsideDownTranslate import org.jackhuang.hmcl.gradle.mod.ParseModDataTask +import org.jackhuang.hmcl.gradle.utils.PropertiesUtils import java.net.URI import java.nio.file.FileSystems import java.nio.file.Files @@ -16,30 +19,36 @@ plugins { alias(libs.plugins.shadow) } -val isOfficial = System.getenv("HMCL_SIGNATURE_KEY") != null - || (System.getenv("GITHUB_REPOSITORY_OWNER") == "HMCL-dev" && System.getenv("GITHUB_BASE_REF") - .isNullOrEmpty()) +val projectConfig = PropertiesUtils.load(rootProject.file("config/project.properties").toPath()) + +val isOfficial = JenkinsUtils.IS_ON_CI || GitHubActionUtils.IS_ON_OFFICIAL_REPO -val buildNumber = System.getenv("BUILD_NUMBER")?.toInt().let { number -> - val offset = System.getenv("BUILD_NUMBER_OFFSET")?.toInt() ?: 0 - if (number != null) { - (number - offset).toString() - } else { - val shortCommit = System.getenv("GITHUB_SHA")?.lowercase()?.substring(0, 7) - val prefix = if (isOfficial) "dev" else "unofficial" - if (!shortCommit.isNullOrEmpty()) "$prefix-$shortCommit" else "SNAPSHOT" - } -} -val versionRoot = System.getenv("VERSION_ROOT") ?: "3.6" val versionType = System.getenv("VERSION_TYPE") ?: if (isOfficial) "nightly" else "unofficial" +val versionRoot = System.getenv("VERSION_ROOT") ?: projectConfig.getProperty("versionRoot") ?: "3" val microsoftAuthId = System.getenv("MICROSOFT_AUTH_ID") ?: "" val microsoftAuthSecret = System.getenv("MICROSOFT_AUTH_SECRET") ?: "" val curseForgeApiKey = System.getenv("CURSEFORGE_API_KEY") ?: "" -val launcherExe = System.getenv("HMCL_LAUNCHER_EXE") +val launcherExe = System.getenv("HMCL_LAUNCHER_EXE") ?: "" -version = "$versionRoot.$buildNumber" +val buildNumber = System.getenv("BUILD_NUMBER")?.toInt() +if (buildNumber != null) { + version = if (JenkinsUtils.IS_ON_CI && versionType == "dev") { + "$versionRoot.0.$buildNumber" + } else { + "$versionRoot.$buildNumber" + } +} else { + val shortCommit = System.getenv("GITHUB_SHA")?.lowercase()?.substring(0, 7) + version = if (shortCommit.isNullOrBlank()) { + "$versionRoot.SNAPSHOT" + } else if (isOfficial) { + "$versionRoot.dev-$shortCommit" + } else { + "$versionRoot.unofficial-$shortCommit" + } +} val embedResources by configurations.registering @@ -50,7 +59,7 @@ dependencies { implementation(libs.twelvemonkeys.imageio.webp) implementation(libs.java.info) - if (launcherExe == null) { + if (launcherExe.isBlank()) { implementation(libs.hmclauncher) } @@ -195,7 +204,7 @@ tasks.shadowJar { "Enable-Native-Access" to "ALL-UNNAMED" ) - if (launcherExe != null) { + if (launcherExe.isNotBlank()) { into("assets") { from(file(launcherExe)) } diff --git a/build.gradle.kts b/build.gradle.kts index 173537d00..e0333963c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -21,7 +21,14 @@ subprojects { name = "libs" dirs = setOf(rootProject.file("lib")) } - mavenCentral() + + System.getenv("MAVEN_CENTRAL_REPO").let { repo -> + if (repo.isNullOrBlank()) + mavenCentral() + else + maven(url = repo) + } + maven(url = "https://jitpack.io") maven(url = "https://libraries.minecraft.net") } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index ad5c14669..3b182eca1 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -1,5 +1,10 @@ repositories { - mavenCentral() + System.getenv("MAVEN_CENTRAL_REPO").let { repo -> + if (repo.isNullOrBlank()) + mavenCentral() + else + maven(url = repo) + } } dependencies { diff --git a/buildSrc/src/main/java/org/jackhuang/hmcl/gradle/ci/GitHubActionUtils.java b/buildSrc/src/main/java/org/jackhuang/hmcl/gradle/ci/GitHubActionUtils.java new file mode 100644 index 000000000..f281b83db --- /dev/null +++ b/buildSrc/src/main/java/org/jackhuang/hmcl/gradle/ci/GitHubActionUtils.java @@ -0,0 +1,32 @@ +/* + * Hello Minecraft! Launcher + * Copyright (C) 2025 huangyuhui and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.jackhuang.hmcl.gradle.ci; + +import java.util.Objects; + +/// @author Glavo +public final class GitHubActionUtils { + private static final String OFFICIAL_ORGANIZATION = "HMCL-dev"; + + public static final boolean IS_ON_OFFICIAL_REPO = + OFFICIAL_ORGANIZATION.equalsIgnoreCase(System.getenv("GITHUB_REPOSITORY_OWNER")) + && Objects.requireNonNullElse(System.getenv("GITHUB_BASE_REF"), "").isBlank(); + + private GitHubActionUtils() { + } +} diff --git a/buildSrc/src/main/java/org/jackhuang/hmcl/gradle/ci/JenkinsUtils.java b/buildSrc/src/main/java/org/jackhuang/hmcl/gradle/ci/JenkinsUtils.java new file mode 100644 index 000000000..775cebfec --- /dev/null +++ b/buildSrc/src/main/java/org/jackhuang/hmcl/gradle/ci/JenkinsUtils.java @@ -0,0 +1,27 @@ +/* + * Hello Minecraft! Launcher + * Copyright (C) 2025 huangyuhui and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.jackhuang.hmcl.gradle.ci; + +/// @author Glavo +public final class JenkinsUtils { + + public static final boolean IS_ON_CI = "1".equals(System.getenv("HMCL_CI")); + + private JenkinsUtils() { + } +} diff --git a/buildSrc/src/main/java/org/jackhuang/hmcl/gradle/utils/PropertiesUtils.java b/buildSrc/src/main/java/org/jackhuang/hmcl/gradle/utils/PropertiesUtils.java new file mode 100644 index 000000000..f5b068522 --- /dev/null +++ b/buildSrc/src/main/java/org/jackhuang/hmcl/gradle/utils/PropertiesUtils.java @@ -0,0 +1,39 @@ +/* + * Hello Minecraft! Launcher + * Copyright (C) 2025 huangyuhui and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.jackhuang.hmcl.gradle.utils; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Properties; + +/// @author Glavo +public final class PropertiesUtils { + public static @NotNull Properties load(Path path) throws IOException { + Properties properties = new Properties(); + try (var reader = Files.newBufferedReader(path)) { + properties.load(reader); + } + return properties; + } + + private PropertiesUtils() { + } +} diff --git a/config-jenkins.sh b/config-jenkins.sh deleted file mode 100755 index 8d5ef7f68..000000000 --- a/config-jenkins.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -_HMCL_PROJECT_ROOT=$(dirname "${BASH_SOURCE[0]}") - -sed -i 's,//services.gradle.org/distributions/,//mirrors.cloud.tencent.com/gradle/,g' "$_HMCL_PROJECT_ROOT/gradle/wrapper/gradle-wrapper.properties" diff --git a/config/jenkins/config-jenkins.sh b/config/jenkins/config-jenkins.sh new file mode 100755 index 000000000..aca01c8d9 --- /dev/null +++ b/config/jenkins/config-jenkins.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +sed -i 's,//services.gradle.org/distributions/,//mirrors.cloud.tencent.com/gradle/,g' "$PWD/gradle/wrapper/gradle-wrapper.properties" + diff --git a/config/jenkins/dev/Jenkinsfile b/config/jenkins/dev/Jenkinsfile new file mode 100644 index 000000000..af7594c63 --- /dev/null +++ b/config/jenkins/dev/Jenkinsfile @@ -0,0 +1,23 @@ +pipeline { + agent any + + environment { + HMCL_CI = '1' + + VERSION_TYPE = 'dev' + MICROSOFT_AUTH_ID = credentials('microsoft_auth_id') + MICROSOFT_AUTH_SECRET = credentials('microsoft_auth_secret') + CURSEFORGE_API_KEY = credentials('curseforge_api_key') + HMCL_SIGNATURE_KEY = credentials('hmcl_signature_key') + } + + stages { + stage('Build') { + steps { + sh 'bash ./config/jenkins/config-jenkins.sh' + sh './gradlew clean makeExecutables --stacktrace --no-daemon' + archiveArtifacts artifacts: 'HMCL/build/libs/*' + } + } + } +} diff --git a/config/jenkins/stable/Jenkinsfile b/config/jenkins/stable/Jenkinsfile new file mode 100644 index 000000000..80bcd4f7d --- /dev/null +++ b/config/jenkins/stable/Jenkinsfile @@ -0,0 +1,23 @@ +pipeline { + agent any + + environment { + HMCL_CI = '1' + + VERSION_TYPE = 'stable' + MICROSOFT_AUTH_ID = credentials('microsoft_auth_id') + MICROSOFT_AUTH_SECRET = credentials('microsoft_auth_secret') + CURSEFORGE_API_KEY = credentials('curseforge_api_key') + HMCL_SIGNATURE_KEY = credentials('hmcl_signature_key') + } + + stages { + stage('Build') { + steps { + sh 'bash ./config/jenkins/config-jenkins.sh' + sh './gradlew clean makeExecutables --stacktrace --no-daemon' + archiveArtifacts artifacts: 'HMCL/build/libs/*' + } + } + } +} diff --git a/config/project.properties b/config/project.properties new file mode 100644 index 000000000..92c4fbb3b --- /dev/null +++ b/config/project.properties @@ -0,0 +1,18 @@ +# +# Hello Minecraft! Launcher +# Copyright (C) 2025 huangyuhui and contributors +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +versionRoot=3.7