diff --git a/.github/workflows/check-update.yml b/.github/workflows/check-update.yml index a1c5ae403..9d0c23162 100644 --- a/.github/workflows/check-update.yml +++ b/.github/workflows/check-update.yml @@ -2,8 +2,8 @@ name: Check Update on: workflow_dispatch: - schedule: - - cron: '30 * * * *' +# schedule: +# - cron: '30 * * * *' permissions: contents: write @@ -28,14 +28,12 @@ jobs: - name: Download artifacts if: ${{ env.continue == 'true' }} run: | - wget "$DOWNLOAD_BASE_URL/HMCL-$HMCL_VERSION.exe" - wget "$DOWNLOAD_BASE_URL/HMCL-$HMCL_VERSION.exe.sha256" - wget "$DOWNLOAD_BASE_URL/HMCL-$HMCL_VERSION.jar" - wget "$DOWNLOAD_BASE_URL/HMCL-$HMCL_VERSION.jar.sha256" - wget "$DOWNLOAD_BASE_URL/HMCL-$HMCL_VERSION.sh" - wget "$DOWNLOAD_BASE_URL/HMCL-$HMCL_VERSION.sh.sha256" - env: - DOWNLOAD_BASE_URL: https://ci.huangyuhui.net/job/HMCL/lastSuccessfulBuild/artifact/HMCL/build/libs + wget "$HMCL_CI_DOWNLOAD_BASE_URI/HMCL-$HMCL_VERSION.exe" + wget "$HMCL_CI_DOWNLOAD_BASE_URI/HMCL-$HMCL_VERSION.exe.sha256" + wget "$HMCL_CI_DOWNLOAD_BASE_URI/HMCL-$HMCL_VERSION.jar" + wget "$HMCL_CI_DOWNLOAD_BASE_URI/HMCL-$HMCL_VERSION.jar.sha256" + wget "$HMCL_CI_DOWNLOAD_BASE_URI/HMCL-$HMCL_VERSION.sh" + wget "$HMCL_CI_DOWNLOAD_BASE_URI/HMCL-$HMCL_VERSION.sh.sha256" - name: Generate release note if: ${{ env.continue == 'true' }} run: | @@ -84,14 +82,12 @@ jobs: - name: Download artifacts if: ${{ env.continue == 'true' }} run: | - wget "$DOWNLOAD_BASE_URL/HMCL-$HMCL_VERSION.exe" - wget "$DOWNLOAD_BASE_URL/HMCL-$HMCL_VERSION.exe.sha256" - wget "$DOWNLOAD_BASE_URL/HMCL-$HMCL_VERSION.jar" - wget "$DOWNLOAD_BASE_URL/HMCL-$HMCL_VERSION.jar.sha256" - wget "$DOWNLOAD_BASE_URL/HMCL-$HMCL_VERSION.sh" - wget "$DOWNLOAD_BASE_URL/HMCL-$HMCL_VERSION.sh.sha256" - env: - DOWNLOAD_BASE_URL: https://ci.huangyuhui.net/job/HMCL-stable/lastSuccessfulBuild/artifact/HMCL/build/libs + wget "$HMCL_CI_DOWNLOAD_BASE_URI/HMCL-$HMCL_VERSION.exe" + wget "$HMCL_CI_DOWNLOAD_BASE_URI/HMCL-$HMCL_VERSION.exe.sha256" + wget "$HMCL_CI_DOWNLOAD_BASE_URI/HMCL-$HMCL_VERSION.jar" + wget "$HMCL_CI_DOWNLOAD_BASE_URI/HMCL-$HMCL_VERSION.jar.sha256" + wget "$HMCL_CI_DOWNLOAD_BASE_URI/HMCL-$HMCL_VERSION.sh" + wget "$HMCL_CI_DOWNLOAD_BASE_URI/HMCL-$HMCL_VERSION.sh.sha256" - name: Generate release note if: ${{ env.continue == 'true' }} run: | @@ -103,9 +99,9 @@ jobs: echo "" >> RELEASE_NOTE echo "| File Name | SHA-256 Checksum |" >> RELEASE_NOTE echo "| --- | --- |" >> RELEASE_NOTE - echo "| [HMCL-$HMCL_VERSION.exe]($GH_DOWNLOAD_BASE_URL/release-$HMCL_VERSION/HMCL-$HMCL_VERSION.exe) | \`$(cat HMCL-$HMCL_VERSION.exe.sha256)\` |" >> RELEASE_NOTE - echo "| [HMCL-$HMCL_VERSION.jar]($GH_DOWNLOAD_BASE_URL/release-$HMCL_VERSION/HMCL-$HMCL_VERSION.jar) | \`$(cat HMCL-$HMCL_VERSION.jar.sha256)\` |" >> RELEASE_NOTE - echo "| [HMCL-$HMCL_VERSION.sh]($GH_DOWNLOAD_BASE_URL/release-$HMCL_VERSION/HMCL-$HMCL_VERSION.sh) | \`$(cat HMCL-$HMCL_VERSION.sh.sha256)\` |" >> RELEASE_NOTE + echo "| [HMCL-$HMCL_VERSION.exe]($GH_DOWNLOAD_BASE_URL/v$HMCL_VERSION/HMCL-$HMCL_VERSION.exe) | \`$(cat HMCL-$HMCL_VERSION.exe.sha256)\` |" >> RELEASE_NOTE + echo "| [HMCL-$HMCL_VERSION.jar]($GH_DOWNLOAD_BASE_URL/v$HMCL_VERSION/HMCL-$HMCL_VERSION.jar) | \`$(cat HMCL-$HMCL_VERSION.jar.sha256)\` |" >> RELEASE_NOTE + echo "| [HMCL-$HMCL_VERSION.sh]($GH_DOWNLOAD_BASE_URL/v$HMCL_VERSION/HMCL-$HMCL_VERSION.sh) | \`$(cat HMCL-$HMCL_VERSION.sh.sha256)\` |" >> RELEASE_NOTE env: GH_DOWNLOAD_BASE_URL: https://github.com/HMCL-dev/HMCL/releases/download - name: Create release @@ -120,3 +116,4 @@ jobs: target_commitish: ${{ env.HMCL_COMMIT_SHA }} name: ${{ env.HMCL_TAG_NAME }} tag_name: ${{ env.HMCL_TAG_NAME }} + prerelease: true diff --git a/build.gradle.kts b/build.gradle.kts index 8bdd11d0b..512e7dca8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -77,11 +77,9 @@ tasks.register("updateDocuments") { } tasks.register("checkUpdateDev") { - tagPrefix.set("v") - uri.set("https://ci.huangyuhui.net/job/HMCL") + uri.set("https://ci.huangyuhui.net/job/HMCL-nightly") } tasks.register("checkUpdateStable") { - tagPrefix.set("release-") uri.set("https://ci.huangyuhui.net/job/HMCL-stable") } diff --git a/buildSrc/src/main/java/org/jackhuang/hmcl/gradle/ci/CheckUpdate.java b/buildSrc/src/main/java/org/jackhuang/hmcl/gradle/ci/CheckUpdate.java index 316d104ef..3c2e4ae96 100644 --- a/buildSrc/src/main/java/org/jackhuang/hmcl/gradle/ci/CheckUpdate.java +++ b/buildSrc/src/main/java/org/jackhuang/hmcl/gradle/ci/CheckUpdate.java @@ -55,9 +55,6 @@ public abstract class CheckUpdate extends DefaultTask { @Input public abstract Property getUri(); - @Input - public abstract Property getTagPrefix(); - public CheckUpdate() { getOutputs().upToDateWhen(task -> false); } @@ -69,10 +66,21 @@ public abstract class CheckUpdate extends DefaultTask { ); } + private static String concatUri(String base, String... others) { + var builder = new StringBuilder(base); + for (String other : others) { + if (builder.charAt(builder.length() - 1) != '/') { + builder.append('/'); + } + builder.append(Objects.requireNonNull(other)); + } + return builder.toString(); + } + @TaskAction public void run() throws Exception { String uri = getUri().get(); - URI apiUri = toURI(uri, "api/json"); + URI apiUri = URI.create(concatUri(uri, "api", "json")); LOGGER.quiet("Fetching metadata from {}", apiUri); BuildMetadata buildMetadata; @@ -93,19 +101,19 @@ public abstract class CheckUpdate extends DefaultTask { .filter(it -> !it.color().equals("disabled")) .map(it -> { try { - return fetchBuildInfo(helper, toURI(it.url, "lastSuccessfulBuild/api/json")); + return fetchBuildInfo(helper, it.url); } catch (Throwable e) { - throw new GradleException("Failed to retrieve build info from " + it.url(), e); + throw new GradleException("Failed to fetch build info from " + it.url(), e); } }).sorted(Comparator.comparing(BuildMetadata::timestamp)) .toList(); if (metadatas.isEmpty()) - throw new GradleException("Failed to retrieve build metadata from " + apiUri); + throw new GradleException("Failed to fetch build metadata from " + apiUri); buildMetadata = metadatas.get(metadatas.size() - 1); } else if (WORKFLOW_JOB.equals(jobType) || FREE_STYLE_PROJECT.equals(jobType)) { - buildMetadata = fetchBuildInfo(helper, toURI(uri, "lastSuccessfulBuild/api/json")); + buildMetadata = fetchBuildInfo(helper, uri); } else { throw new GradleException("Unsupported job type: " + jobType); } @@ -130,14 +138,17 @@ public abstract class CheckUpdate extends DefaultTask { addEnv.accept("HMCL_COMMIT_SHA", buildMetadata.revision()); addEnv.accept("HMCL_VERSION", buildMetadata.version()); - addEnv.accept("HMCL_TAG_NAME", getTagPrefix().get() + buildMetadata.version()); + addEnv.accept("HMCL_TAG_NAME", "v" + buildMetadata.version()); + addEnv.accept("HMCL_CI_DOWNLOAD_BASE_URI", buildMetadata.downloadBaseUri); } } - private record BuildMetadata(String version, String revision, long timestamp) { + private record BuildMetadata(String version, String revision, long timestamp, String downloadBaseUri) { } - private BuildMetadata fetchBuildInfo(Helper helper, URI uri) throws IOException, InterruptedException { + private BuildMetadata fetchBuildInfo(Helper helper, String jobUri) throws IOException, InterruptedException { + URI uri = URI.create(concatUri(jobUri, "lastSuccessfulBuild", "api", "json")); + LOGGER.quiet("Fetching build info from {}", uri); BuildInfo buildInfo = Objects.requireNonNull(helper.fetch(uri, BuildInfo.class), "build info"); @@ -153,16 +164,28 @@ public abstract class CheckUpdate extends DefaultTask { throw new GradleException("Invalid revision: " + revision); Pattern fileNamePattern = Pattern.compile("HMCL-(?\\d+(?:\\.\\d+)+)\\.jar"); - String version = Objects.requireNonNullElse(buildInfo.artifacts(), List.of()) - .stream() - .map(ArtifactInfo::fileName) - .map(fileNamePattern::matcher) - .filter(Matcher::matches) - .map(matcher -> matcher.group("version")) + ArtifactInfo jarArtifact = Objects.requireNonNullElse(buildInfo.artifacts(), List.of()).stream() + .filter(it -> fileNamePattern.matcher(it.fileName()).matches()) .findFirst() .orElseThrow(() -> new GradleException("Could not find .jar artifact")); - return new BuildMetadata(version, revision, buildInfo.timestamp()); + String fileName = jarArtifact.fileName(); + String relativePath = jarArtifact.relativePath(); + if (!relativePath.endsWith("/" + fileName)) { + throw new GradleException("Invalid artifact relative path: " + jarArtifact); + } + + Matcher matcher = fileNamePattern.matcher(fileName); + if (!matcher.matches()) { + throw new AssertionError("Artifact: " + jarArtifact.fileName()); + } + + String version = matcher.group("version"); + + String downloadBaseUrl = concatUri(buildInfo.url(), "artifact", + relativePath.substring(0, relativePath.length() - fileName.length() - 1)); + + return new BuildMetadata(version, revision, buildInfo.timestamp(), downloadBaseUrl); } private static final class Helper implements AutoCloseable { @@ -193,14 +216,15 @@ public abstract class CheckUpdate extends DefaultTask { } - private record BuildInfo(long number, + private record BuildInfo(String url, + long number, long timestamp, List artifacts, List actions ) { } - record ArtifactInfo(String fileName) { + record ArtifactInfo(String fileName, String relativePath) { } record ActionInfo(String _class, BuiltRevision lastBuiltRevision) {