diff --git a/.github/workflows/alpha.yml b/.github/workflows/alpha.yml index d79650d8..56015291 100644 --- a/.github/workflows/alpha.yml +++ b/.github/workflows/alpha.yml @@ -115,55 +115,108 @@ jobs: echo "VERSION=$(cat package.json | jq '.version' | tr -d '"')" >> $GITHUB_ENV echo "BUILDTIME=$(TZ=Asia/Shanghai date)" >> $GITHUB_ENV - - run: | - cat > release.txt << 'EOF' - ### 我应该下载哪个版本? - - - Windows 64位: x64-setup.exe (不支持win7) - - Windows 32位: x86-setup.exe (不支持win7) - - Windows arm64架构: arm64-setup.exe - - MacOS intel芯片: x64.dmg - - MacOS apple M芯片: aarch64.dmg (提示文件损坏看下面FAQ) - - Linux 64位: amd64.AppImage/amd64.deb - - Linux 32位: i386.deb - - Linux arm64架构: arm64.deb - - Linux armv7架构: armhf.deb - - Windows 便携板 64位: x64_portable.zip (不推荐使用,无法自动更新) - - Windows 便携板 32位: x86_portable.zip (不推荐使用,无法自动更新) - - Windows 便携板 arm64架构: arm64_portable.zip (不推荐使用,无法自动更新) - - ### FAQ - - - [FAQ](https://clash-verge-rev.github.io/faq/install/) - - Created at ${{ env.BUILDTIME }}. - EOF - - name: Upload Release if: startsWith(matrix.target, 'x86_64') uses: softprops/action-gh-release@v1 with: tag_name: alpha name: "Clash Verge Rev Alpha" - body_path: release.txt + body: "More new features are now supported." prerelease: true token: ${{ secrets.GITHUB_TOKEN }} files: src-tauri/target/${{ matrix.target }}/release/bundle/appimage/*.AppImage* - name: Upload Release - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 with: tag_name: alpha name: "Clash Verge Rev Alpha" - body_path: release.txt + body: "More new features are now supported." prerelease: true token: ${{ secrets.GITHUB_TOKEN }} files: src-tauri/target/${{ matrix.target }}/release/bundle/deb/*.deb + alpha-for-fixed-webview2: + strategy: + fail-fast: false + matrix: + include: + - os: windows-latest + target: x86_64-pc-windows-msvc + arch: x64 + - os: windows-latest + target: i686-pc-windows-msvc + arch: x86 + - os: windows-latest + target: aarch64-pc-windows-msvc + arch: arm64 + runs-on: ${{ matrix.os }} + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Add Rust Target + run: rustup target add ${{ matrix.target }} + + - name: Rust Cache + uses: Swatinem/rust-cache@v2 + with: + workspaces: src-tauri + + - name: Install Node + uses: actions/setup-node@v4 + with: + node-version: "20" + + - uses: pnpm/action-setup@v3 + name: Install pnpm + with: + version: 9 + run_install: false + + - name: Pnpm install and check + run: | + pnpm i + pnpm check ${{ matrix.target }} + + - name: Download WebView2 Runtime + run: | + invoke-webrequest -uri https://github.com/westinyang/WebView2RuntimeArchive/releases/download/109.0.1518.78/Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.${{ matrix.arch }}.cab -outfile Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.${{ matrix.arch }}.cab + Expand .\Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.${{ matrix.arch }}.cab -F:* ./src-tauri + Remove-Item .\src-tauri\tauri.windows.conf.json + Rename-Item .\src-tauri\webview2.${{ matrix.arch }}.json tauri.windows.conf.json + + - name: Tauri build + id: build + uses: tauri-apps/tauri-action@v0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} + TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} + with: + tauriScript: pnpm + args: --target ${{ matrix.target }} + + - name: Rename + run: | + Rename-Item '.\src-tauri\target\${{ matrix.target }}\release\bundle\nsis\Clash Verge_${{steps.build.outputs.appVersion}}_${{ matrix.arch }}-setup.exe' 'Clash Verge_${{steps.build.outputs.appVersion}}_${{ matrix.arch }}_fixed_webview2-setup.exe' + Rename-Item '.\src-tauri\target\${{ matrix.target }}\release\bundle\nsis\Clash Verge_${{steps.build.outputs.appVersion}}_${{ matrix.arch }}-setup.nsis.zip' 'Clash Verge_${{steps.build.outputs.appVersion}}_${{ matrix.arch }}_fixed_webview2-setup.nsis.zip' + Rename-Item '.\src-tauri\target\${{ matrix.target }}\release\bundle\nsis\Clash Verge_${{steps.build.outputs.appVersion}}_${{ matrix.arch }}-setup.nsis.zip.sig' 'Clash Verge_${{steps.build.outputs.appVersion}}_${{ matrix.arch }}_fixed_webview2-setup.nsis.zip.sig' + + - name: Upload Release + uses: softprops/action-gh-release@v2 + with: + tag_name: alpha + name: "Clash Verge Rev Alpha" + body: "More new features are now supported." + prerelease: true + token: ${{ secrets.GITHUB_TOKEN }} + files: src-tauri/target/${{ matrix.target }}/release/bundle/nsis/*setup* + update_tag: name: Update tag runs-on: ubuntu-latest - needs: [alpha, alpha-for-linux] + needs: [alpha, alpha-for-linux, alpha-for-fixed-webview2] steps: - name: Checkout repository uses: actions/checkout@v4 @@ -205,7 +258,7 @@ jobs: EOF - name: Upload Release - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 with: tag_name: alpha name: "Clash Verge Rev Alpha" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 14673609..98515280 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,6 +15,8 @@ jobs: include: - os: windows-latest target: x86_64-pc-windows-msvc + - os: windows-latest + target: i686-pc-windows-msvc - os: windows-latest target: aarch64-pc-windows-msvc - os: macos-latest @@ -84,6 +86,8 @@ jobs: include: - os: ubuntu-latest target: x86_64-unknown-linux-gnu + - os: ubuntu-latest + target: i686-unknown-linux-gnu - os: ubuntu-latest target: aarch64-unknown-linux-gnu - os: ubuntu-latest @@ -126,22 +130,98 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} files: src-tauri/target/${{ matrix.target }}/release/bundle/deb/*.deb + release-for-fixed-webview2: + strategy: + fail-fast: false + matrix: + include: + - os: windows-latest + target: x86_64-pc-windows-msvc + arch: x64 + - os: windows-latest + target: i686-pc-windows-msvc + arch: x86 + - os: windows-latest + target: aarch64-pc-windows-msvc + arch: arm64 + runs-on: ${{ matrix.os }} + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Add Rust Target + run: rustup target add ${{ matrix.target }} + + - name: Rust Cache + uses: Swatinem/rust-cache@v2 + with: + workspaces: src-tauri + + - name: Install Node + uses: actions/setup-node@v4 + with: + node-version: "20" + + - uses: pnpm/action-setup@v3 + name: Install pnpm + with: + version: 9 + run_install: false + + - name: Pnpm install and check + run: | + pnpm i + pnpm check ${{ matrix.target }} + + - name: Download WebView2 Runtime + run: | + invoke-webrequest -uri https://github.com/westinyang/WebView2RuntimeArchive/releases/download/109.0.1518.78/Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.${{ matrix.arch }}.cab -outfile Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.${{ matrix.arch }}.cab + Expand .\Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.${{ matrix.arch }}.cab -F:* ./src-tauri + Remove-Item .\src-tauri\tauri.windows.conf.json + Rename-Item .\src-tauri\webview2.${{ matrix.arch }}.json tauri.windows.conf.json + + - name: Tauri build + id: build + uses: tauri-apps/tauri-action@v0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} + TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }} + with: + tauriScript: pnpm + args: --target ${{ matrix.target }} + + - name: Rename + run: | + Rename-Item '.\src-tauri\target\${{ matrix.target }}\release\bundle\nsis\Clash Verge_${{steps.build.outputs.appVersion}}_${{ matrix.arch }}-setup.exe' 'Clash Verge_${{steps.build.outputs.appVersion}}_${{ matrix.arch }}_fixed_webview2-setup.exe' + Rename-Item '.\src-tauri\target\${{ matrix.target }}\release\bundle\nsis\Clash Verge_${{steps.build.outputs.appVersion}}_${{ matrix.arch }}-setup.nsis.zip' 'Clash Verge_${{steps.build.outputs.appVersion}}_${{ matrix.arch }}_fixed_webview2-setup.nsis.zip' + Rename-Item '.\src-tauri\target\${{ matrix.target }}\release\bundle\nsis\Clash Verge_${{steps.build.outputs.appVersion}}_${{ matrix.arch }}-setup.nsis.zip.sig' 'Clash Verge_${{steps.build.outputs.appVersion}}_${{ matrix.arch }}_fixed_webview2-setup.nsis.zip.sig' + + - name: Upload Release + uses: softprops/action-gh-release@v1 + with: + tag_name: v${{steps.build.outputs.appVersion}} + name: "Clash Verge Rev v${{steps.build.outputs.appVersion}}" + body: "More new features are now supported." + token: ${{ secrets.GITHUB_TOKEN }} + files: src-tauri/target/${{ matrix.target }}/release/bundle/nsis/*setup* + release-update: runs-on: ubuntu-latest needs: [release, release-for-linux] steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: "20" - uses: pnpm/action-setup@v2 name: Install pnpm with: - version: 8 + version: 9 run_install: false - name: Pnpm install @@ -151,3 +231,29 @@ jobs: run: pnpm updater env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + release-update-for-fixed-webview2: + runs-on: ubuntu-latest + needs: [release-for-fixed-webview2] + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Node + uses: actions/setup-node@v4 + with: + node-version: "20" + + - uses: pnpm/action-setup@v2 + name: Install pnpm + with: + version: 9 + run_install: false + + - name: Pnpm install + run: pnpm i + + - name: Release updater file + run: pnpm updater-fixed-webview2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/updater.yml b/.github/workflows/updater.yml index 62c4362d..f58e33f9 100644 --- a/.github/workflows/updater.yml +++ b/.github/workflows/updater.yml @@ -10,14 +10,14 @@ jobs: uses: actions/checkout@v3 - name: Install Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: "20" - uses: pnpm/action-setup@v2 name: Install pnpm with: - version: 8 + version: 9 run_install: false - name: Pnpm install @@ -27,3 +27,28 @@ jobs: run: pnpm updater env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + release-update-for-fixed-webview2: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Node + uses: actions/setup-node@v4 + with: + node-version: "20" + + - uses: pnpm/action-setup@v2 + name: Install pnpm + with: + version: 9 + run_install: false + + - name: Pnpm install + run: pnpm i + + - name: Release updater file + run: pnpm updater-fixed-webview2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/package.json b/package.json index 0d861a1c..bb47f0f2 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "web:serve": "vite preview", "check": "node scripts/check.mjs", "updater": "node scripts/updater.mjs", + "updater-fixed-webview2": "node scripts/updater-fixed-webview2.mjs", "portable": "node scripts/portable.mjs", "prepare": "husky install" }, diff --git a/scripts/updater-fixed-webview2.mjs b/scripts/updater-fixed-webview2.mjs new file mode 100644 index 00000000..fdc3ac9c --- /dev/null +++ b/scripts/updater-fixed-webview2.mjs @@ -0,0 +1,154 @@ +import fetch from "node-fetch"; +import { getOctokit, context } from "@actions/github"; +import { resolveUpdateLog } from "./updatelog.mjs"; + +const UPDATE_TAG_NAME = "updater"; +const UPDATE_JSON_FILE = "update-fixed-webview2.json"; +const UPDATE_JSON_PROXY = "update-fixed-webview2-proxy.json"; + +/// generate update.json +/// upload to update tag's release asset +async function resolveUpdater() { + if (process.env.GITHUB_TOKEN === undefined) { + throw new Error("GITHUB_TOKEN is required"); + } + + 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 updateData = { + name: tag.name, + notes: await resolveUpdateLog(tag.name), // use updatelog.md + pub_date: new Date().toISOString(), + platforms: { + "windows-x86_64": { signature: "", url: "" }, + "windows-aarch64": { signature: "", url: "" }, + "windows-x86": { signature: "", url: "" }, + }, + }; + + const promises = latestRelease.assets.map(async (asset) => { + const { name, browser_download_url } = asset; + + // win64 url + if (name.endsWith("x64_fixed_webview2-setup.nsis.zip")) { + updateData.platforms["windows-x86_64"].url = browser_download_url; + } + // win64 signature + if (name.endsWith("x64_fixed_webview2-setup.nsis.zip.sig")) { + const sig = await getSignature(browser_download_url); + updateData.platforms["windows-x86_64"].signature = sig; + } + + // win32 url + if (name.endsWith("x86_fixed_webview2-setup.nsis.zip")) { + updateData.platforms["windows-x86"].url = browser_download_url; + } + // win32 signature + if (name.endsWith("x86_fixed_webview2-setup.nsis.zip.sig")) { + const sig = await getSignature(browser_download_url); + updateData.platforms["windows-x86"].signature = sig; + } + + // win arm url + if (name.endsWith("arm64_fixed_webview2-setup.nsis.zip")) { + updateData.platforms["windows-aarch64"].url = browser_download_url; + } + // win arm signature + if (name.endsWith("arm64_fixed_webview2-setup.nsis.zip.sig")) { + const sig = await getSignature(browser_download_url); + updateData.platforms["windows-aarch64"].signature = sig; + } + }); + + await Promise.allSettled(promises); + console.log(updateData); + + // maybe should test the signature as well + // delete the null field + Object.entries(updateData.platforms).forEach(([key, value]) => { + if (!value.url) { + console.log(`[Error]: failed to parse release for "${key}"`); + delete updateData.platforms[key]; + } + }); + + // 生成一个代理github的更新文件 + // 使用 https://hub.fastgit.xyz/ 做github资源的加速 + const updateDataNew = JSON.parse(JSON.stringify(updateData)); + + Object.entries(updateDataNew.platforms).forEach(([key, value]) => { + if (value.url) { + updateDataNew.platforms[key].url = + "https://mirror.ghproxy.com/" + value.url; + } else { + console.log(`[Error]: updateDataNew.platforms.${key} is null`); + } + }); + + // update the update.json + const { data: updateRelease } = await github.rest.repos.getReleaseByTag({ + ...options, + tag: UPDATE_TAG_NAME, + }); + + // delete the old assets + for (let asset of updateRelease.assets) { + if (asset.name === UPDATE_JSON_FILE) { + await github.rest.repos.deleteReleaseAsset({ + ...options, + asset_id: asset.id, + }); + } + + if (asset.name === UPDATE_JSON_PROXY) { + await github.rest.repos + .deleteReleaseAsset({ ...options, asset_id: asset.id }) + .catch(console.error); // do not break the pipeline + } + } + + // upload new assets + await github.rest.repos.uploadReleaseAsset({ + ...options, + release_id: updateRelease.id, + name: UPDATE_JSON_FILE, + data: JSON.stringify(updateData, null, 2), + }); + + await github.rest.repos.uploadReleaseAsset({ + ...options, + release_id: updateRelease.id, + name: UPDATE_JSON_PROXY, + data: JSON.stringify(updateDataNew, null, 2), + }); +} + +// 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(); +} + +resolveUpdater().catch(console.error); diff --git a/src-tauri/webview2.arm64.json b/src-tauri/webview2.arm64.json new file mode 100644 index 00000000..1130be88 --- /dev/null +++ b/src-tauri/webview2.arm64.json @@ -0,0 +1,38 @@ +{ + "$schema": "../node_modules/@tauri-apps/cli/schema.json", + "tauri": { + "systemTray": { + "iconPath": "icons/tray-icon.png" + }, + "bundle": { + "identifier": "io.github.clash-verge-rev.clash-verge-rev", + "targets": ["nsis", "updater"], + "windows": { + "certificateThumbprint": null, + "digestAlgorithm": "sha256", + "timestampUrl": "", + "webviewInstallMode": { + "type": "fixedRuntime", + "path": "./Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.arm64/" + }, + "nsis": { + "displayLanguageSelector": true, + "installerIcon": "icons/icon.ico", + "languages": ["SimpChinese", "English"], + "license": "../LICENSE", + "installMode": "perMachine", + "template": "./template/installer.nsi" + } + } + }, + "updater": { + "active": true, + "dialog": false, + "endpoints": [ + "https://mirror.ghproxy.com/https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-fixed-webview2-proxy.json", + "https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-fixed-webview2.json" + ], + "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEQyOEMyRjBCQkVGOUJEREYKUldUZnZmbStDeStNMHU5Mmo1N24xQXZwSVRYbXA2NUpzZE5oVzlqeS9Bc0t6RVV4MmtwVjBZaHgK" + } + } +} diff --git a/src-tauri/webview2.x64.json b/src-tauri/webview2.x64.json new file mode 100644 index 00000000..26a069a8 --- /dev/null +++ b/src-tauri/webview2.x64.json @@ -0,0 +1,38 @@ +{ + "$schema": "../node_modules/@tauri-apps/cli/schema.json", + "tauri": { + "systemTray": { + "iconPath": "icons/tray-icon.png" + }, + "bundle": { + "identifier": "io.github.clash-verge-rev.clash-verge-rev", + "targets": ["nsis", "updater"], + "windows": { + "certificateThumbprint": null, + "digestAlgorithm": "sha256", + "timestampUrl": "", + "webviewInstallMode": { + "type": "fixedRuntime", + "path": "./Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.x64/" + }, + "nsis": { + "displayLanguageSelector": true, + "installerIcon": "icons/icon.ico", + "languages": ["SimpChinese", "English"], + "license": "../LICENSE", + "installMode": "perMachine", + "template": "./template/installer.nsi" + } + } + }, + "updater": { + "active": true, + "dialog": false, + "endpoints": [ + "https://mirror.ghproxy.com/https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-fixed-webview2-proxy.json", + "https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-fixed-webview2.json" + ], + "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEQyOEMyRjBCQkVGOUJEREYKUldUZnZmbStDeStNMHU5Mmo1N24xQXZwSVRYbXA2NUpzZE5oVzlqeS9Bc0t6RVV4MmtwVjBZaHgK" + } + } +} diff --git a/src-tauri/webview2.x86.json b/src-tauri/webview2.x86.json new file mode 100644 index 00000000..ab2b490f --- /dev/null +++ b/src-tauri/webview2.x86.json @@ -0,0 +1,38 @@ +{ + "$schema": "../node_modules/@tauri-apps/cli/schema.json", + "tauri": { + "systemTray": { + "iconPath": "icons/tray-icon.png" + }, + "bundle": { + "identifier": "io.github.clash-verge-rev.clash-verge-rev", + "targets": ["nsis", "updater"], + "windows": { + "certificateThumbprint": null, + "digestAlgorithm": "sha256", + "timestampUrl": "", + "webviewInstallMode": { + "type": "fixedRuntime", + "path": "./Microsoft.WebView2.FixedVersionRuntime.109.0.1518.78.x86/" + }, + "nsis": { + "displayLanguageSelector": true, + "installerIcon": "icons/icon.ico", + "languages": ["SimpChinese", "English"], + "license": "../LICENSE", + "installMode": "perMachine", + "template": "./template/installer.nsi" + } + } + }, + "updater": { + "active": true, + "dialog": false, + "endpoints": [ + "https://mirror.ghproxy.com/https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-fixed-webview2-proxy.json", + "https://github.com/clash-verge-rev/clash-verge-rev/releases/download/updater/update-fixed-webview2.json" + ], + "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEQyOEMyRjBCQkVGOUJEREYKUldUZnZmbStDeStNMHU5Mmo1N24xQXZwSVRYbXA2NUpzZE5oVzlqeS9Bc0t6RVV4MmtwVjBZaHgK" + } + } +}