From 81ee989f1f817c2da69f0c71f3fc4a8232f306b6 Mon Sep 17 00:00:00 2001
From: GyDi <segydi@foxmail.com>
Date: Tue, 22 Feb 2022 01:56:06 +0800
Subject: [PATCH] chore: enhance publish ci

---
 .github/workflows/ci.yml |   5 +-
 scripts/release.mjs      | 119 +++++++++++++++++++++++++++------------
 2 files changed, 86 insertions(+), 38 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index aeb66e1..588a3be 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,4 +1,4 @@
-name: CI
+name: Release CI
 
 on: [push]
 
@@ -53,7 +53,7 @@ jobs:
           yarn run check
 
       - name: Tauri build
-        uses: tauri-apps/tauri-action@v0
+        uses: tauri-apps/tauri-action@b9ce5d7dc68082d21d30a60103b0ab8c5ddae3a1
         # enable cache even though failed
         continue-on-error: true
         env:
@@ -95,6 +95,5 @@ jobs:
 
       - name: Release update.json
         run: yarn run release
-        continue-on-error: true
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/scripts/release.mjs b/scripts/release.mjs
index 6760260..1752043 100644
--- a/scripts/release.mjs
+++ b/scripts/release.mjs
@@ -1,7 +1,8 @@
-import { createRequire } from "module";
+import fetch from "node-fetch";
 import { getOctokit, context } from "@actions/github";
 
-const require = createRequire(import.meta.url);
+const UPDATE_TAG_NAME = "updater";
+const UPDATE_JSON_FILE = "update.json";
 
 /// generate update.json
 /// upload to update tag's release asset
@@ -10,46 +11,85 @@ async function resolveRelease() {
     throw new Error("GITHUB_TOKEN is required");
   }
 
-  const packageJson = require("../package.json");
+  const options = { owner: context.repo.owner, repo: context.repo.repo };
+  const github = getOctokit(process.env.GITHUB_TOKEN);
+
+  const { data: tags } = await github.rest.repos.listTags({
+    ...options,
+    per_page: 10,
+    page: 1,
+  });
+
+  // get the latest publish tag
+  const tag = tags.find((t) => t.name.startsWith("v"));
+
+  console.log(tag);
+  console.log();
+
+  const { data: latestRelease } = await github.rest.repos.getReleaseByTag({
+    ...options,
+    tag: tag.name,
+  });
 
-  const { version } = packageJson;
-  const urlPrefix = "https://github.com/zzzgydi/clash-verge/releases/download";
   const updateData = {
-    name: `v${version}`,
-    notes: `Version ${version} is available now!!!`,
+    name: tag.name,
+    notes: latestRelease.body, // use the release body directly
     pub_date: new Date().toISOString(),
     platforms: {
-      win64: {
-        signature: "",
-        url: `${urlPrefix}/v${version}/clash-verge_${version}_x64.msi.zip`,
-      },
-      darwin: {
-        signature: "",
-        url: `${urlPrefix}/v${version}/clash-verge.app.tar.gz`,
-      },
+      win64: { signature: "", url: "" },
+      darwin: { signature: "", url: "" },
     },
   };
 
-  console.log(`Generating Version "${version}" update.json`);
-
-  const github = getOctokit(process.env.GITHUB_TOKEN);
+  const promises = latestRelease.assets.map(async (asset) => {
+    const { name, browser_download_url } = asset;
 
-  const { data: release } = await github.rest.repos.getReleaseByTag({
-    owner: context.repo.owner,
-    repo: context.repo.repo,
-    tag: "updater",
+    // win64 url
+    if (/\.msi\.zip$/.test(name)) {
+      updateData.platforms.win64.url = browser_download_url;
+    }
+    // darwin url
+    if (/\.app\.tar\.gz$/.test(name)) {
+      updateData.platforms.darwin.url = browser_download_url;
+    }
+    // win64 signature
+    if (/\.msi\.zip\.sig$/.test(name)) {
+      updateData.platforms.win64.signature = await getSignature(
+        browser_download_url
+      );
+    }
+    // darwin signature
+    if (/\.app\.tar\.gz\.sig$/.test(name)) {
+      updateData.platforms.darwin.signature = await getSignature(
+        browser_download_url
+      );
+    }
   });
-  const { data: assets } = await github.rest.repos.listReleaseAssets({
-    owner: context.repo.owner,
-    repo: context.repo.repo,
-    release_id: release.id,
+
+  await Promise.allSettled(promises);
+  console.log(updateData);
+
+  // maybe should test the signature as well
+  const { darwin, win64 } = updateData.platforms;
+  if (!darwin.url) {
+    console.log(`[Error]: failed to parse release for darwin`);
+    delete updateData.platforms.darwin;
+  }
+  if (!win64.url) {
+    console.log(`[Error]: failed to parse release for win64`);
+    delete updateData.platforms.win64;
+  }
+
+  // update the update.json
+  const { data: updateRelease } = await github.rest.repos.getReleaseByTag({
+    ...options,
+    tag: UPDATE_TAG_NAME,
   });
 
-  for (let asset of assets) {
-    if (asset.name === "update.json") {
+  for (let asset of updateRelease.assets) {
+    if (asset.name === UPDATE_JSON_FILE) {
       await github.rest.repos.deleteReleaseAsset({
-        owner: context.repo.owner,
-        repo: context.repo.repo,
+        ...options,
         asset_id: asset.id,
       });
       break;
@@ -57,12 +97,21 @@ async function resolveRelease() {
   }
 
   await github.rest.repos.uploadReleaseAsset({
-    owner: context.repo.owner,
-    repo: context.repo.repo,
-    release_id: release.id,
-    name: "update.json",
+    ...options,
+    release_id: updateRelease.id,
+    name: UPDATE_JSON_FILE,
     data: JSON.stringify(updateData, null, 2),
   });
 }
 
-resolveRelease();
+// get the signature file content
+async function getSignature(url) {
+  const response = await fetch(url, {
+    method: "GET",
+    headers: { "Content-Type": "application/octet-stream" },
+  });
+
+  return response.text();
+}
+
+resolveRelease().catch(console.error);
-- 
GitLab