likes
comments
collection
share

Tauri开发EPUB编辑器(三) 程序检查更新 借助Github Action自动发布安装包Tauri v2版本目前尚

作者站长头像
站长
· 阅读数 29

Tauri程序的检查更新,以及借助Github Action自动发布安装包

我使用的是v2版本的Tauri,以下所有内容都是基于v2,。

原本我不打算写这篇的,但由于Tauri v2版本目前尚处于beta测试阶段,相关文档也还在建设中,文档内容非常的缺失,很多东西都只能靠自己摸索,所以我还是决定写这篇文章,希望对其他人能有所帮助。

Tauri开发EPUB编辑器(三) 程序检查更新 借助Github Action自动发布安装包Tauri v2版本目前尚

Tauri程序的检查更新

1. 安装Updater插件

v2版本的Tauri采用的是插件式的模块,例如Dialog(对话框)、Theme(主题)等等,也包括Updater(更新器),想使用更新器,首先需要执行命令:

pnpm tauri add updater

这样tauri的cli会自动帮我们下载相关的依赖,并将插件相关的代码写入main.rslib.rs文件中。

2. 生成秘钥

接下来我们需要生成一对秘钥,执行命令:

pnpm run tauri signer generate -- -w .tauri/app.key

生成过程中会让我们输入一个密码,你可以选择输入密码,也可以直接按回车选择留空。

这样就会在我们项目的.tauri/目录下生成两个文件:app.keyapp.key.pub,前者是私钥,后者是公钥。

如果是开源项目,需要将秘钥文件添加到git ignore,避免被上传到在线仓库中

但事实上,官方推荐我们将私钥放在本地的用户目录下,这也是绝大多数存在秘钥场景时的做法:

Linux

pnpm tauri signer generate -w ~/.tauri/myapp.key

Windows

pnpm tauri signer generate -w $HOME/.tauri/myapp.key

只是我个人为了省事,直接放在了项目里,但还是建议大家采用官方推荐的做法。

3. 最新版本的json

然后,我们需要在tauri.conf.json中配置更新信息:

"plugins": {
    "updater": {
      "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDE4MUUwQTA1RThCMjc2QzIKUldUQ2RyTG9CUW9lR09ONEtxamVpZXR4aVphTlFzSHNmb0F2M01pSHFSV0hFWGNwZllWQ3hFamIK",
      "endpoints": [
        "https://github.com/taiyuuki/eb-code/releases/latest/download/latest.json"
      ],
      "windows": {
        "installMode": "passive"
      }
    }
  }

其中pubkey就是公钥文件app.key.pub里的内容(不能是地址),直接复制内容粘贴进去即可。

endpoints是包含最新版本信息的json文件的地址,可以填写多个地址,如果前者失效时,会继续往后查找。json的格式如下:

latest.json

{
  "version": "0.1.0",
  "notes": "See the assets to download this version and install.",
  "pub_date": "2024-06-21T14:39:55.687Z",
  "platforms": {
    "darwin-x86_64": {
      "signature": "dW50cnVzdGVkIGNvbW1lbnQ6IHNpZ25hdHVyZSBmcm9tIHRhdXJpIHNlY3JldCBrZXkKUlVUQ2RyTG9CUW9lR01uNXFPUWJGbkdVaUF3ckY0RUtmMXlTZjVMV2hueUZUWXJVelp6RlhYR1Qzd0hhLzBuMXhCL2g3UHRhdGlLcmxtd1ovcW5EUGpiaWsrT0x1VTJWQXdNPQp0cnVzdGVkIGNvbW1lbnQ6IHRpbWVzdGFtcDoxNzE4OTgwMzQ3CWZpbGU6RWJvb2sgQ29kZS5hcHAudGFyLmd6CitCbHJ2NGJrZnZLQmRYSUVUdHZlSW9lMllnUGFBUk9udUxYQVFMcEN2M2NMRGNOK3pheDRBUXJITldDeE4ySU01Y3J4eS9tcVFEUU5WbEROZm15bEFRPT0K",
      "url": "https://github.com/taiyuuki/eb-code/releases/download/eb-code-v0.1.0/Ebook.Code_x64.app.tar.gz"
    },
    "darwin-aarch64": {
      "signature": "dW50cnVzdGVkIGNvbW1lbnQ6IHNpZ25hdHVyZSBmcm9tIHRhdXJpIHNlY3JldCBrZXkKUlVUQ2RyTG9CUW9lR0gxUXkya1Bwb2crTUpVSGNEWlowZkhPeE1oaDliaXpqSW9jVytmbDhSNXFWeGUwQVFZbDVJVkhVUFFrYm1nTDJUN2V6d2o2WVlJeUZ5aVBRcXZpV0FjPQp0cnVzdGVkIGNvbW1lbnQ6IHRpbWVzdGFtcDoxNzE4OTgwMzU3CWZpbGU6RWJvb2sgQ29kZS5hcHAudGFyLmd6Cno3Sm40aFdNWkRBT2dpUVVyemhlYTYvb3V5eGV2dFRwQmVYZVVBZnRBM2UweFQxaXdyK1NSbzRFUitmMmtSTVVDZjYvbVd0aWFaZVBMK0RGSTlML0RRPT0K",
      "url": "https://github.com/taiyuuki/eb-code/releases/download/eb-code-v0.1.0/Ebook.Code_aarch64.app.tar.gz"
    },
    "linux-x86_64": {
      "signature": "dW50cnVzdGVkIGNvbW1lbnQ6IHNpZ25hdHVyZSBmcm9tIHRhdXJpIHNlY3JldCBrZXkKUlVUQ2RyTG9CUW9lR09Pemc3UDJ4bytMZ25leTE0OHdkYURrcVJmb1VGbFNEZGFDSmRkWDBnK1UwMGVxOUJBZWVHR2ZsZGJZZWdydFh5Vk9wVkVDVUluRGxCTHFwS0ZQRHc4PQp0cnVzdGVkIGNvbW1lbnQ6IHRpbWVzdGFtcDoxNzE4OTgwNjE1CWZpbGU6RWJvb2sgQ29kZV8wLjEuMF9hbWQ2NC5BcHBJbWFnZS50YXIuZ3oKcmZBZlVFWjViOXZQNnUvQURoOTU2TWRqLzZwUk5GS0Z4Nm5yTkJCeHVtNmxYZDM4NTh1WWM2aTJFS1JSbURsZGx0K0MyZlNIc0hQSzh1aDlzbjFCRGc9PQo=",
      "url": "https://github.com/taiyuuki/eb-code/releases/download/eb-code-v0.1.0/Ebook.Code_0.1.0_amd64.AppImage.tar.gz"
    },
    "windows-x86_64": {
      "signature": "dW50cnVzdGVkIGNvbW1lbnQ6IHNpZ25hdHVyZSBmcm9tIHRhdXJpIHNlY3JldCBrZXkKUlVUQ2RyTG9CUW9lR0d1T0xiUlR1a2VuZVVCRU1jUWFzdlBzQndIeFNFYkNoOEFRWVlSZGF3OS9DMW5JejE4VEtBRDhLTUJRV1lKUk5YbmtXM24wOUk1VzhwUG9IcGVoRlFFPQp0cnVzdGVkIGNvbW1lbnQ6IHRpbWVzdGFtcDoxNzE4OTgwNzg4CWZpbGU6RWJvb2sgQ29kZV8wLjEuMF94NjRfemgtQ04ubXNpLnppcApqY0lQTFVEOWJrYk1vRk1vZVRadXEwc2ZDbDFCQ0ltS3YvY01lWnNlYjVKWFhmMCtBS3RtcC9obGdLVDZhU2dMdklDMXFXNzIxcHlSdWFxMnZROWVDdz09Cg==",
      "url": "https://github.com/taiyuuki/eb-code/releases/download/eb-code-v0.1.0/Ebook.Code_0.1.0_x64_zh-CN.msi.zip"
    }
  }
}

以上内容是使用Tauri Action自动生成的(参考后文),假如你不使用Action,你可能需要了解一下每一个字段的含义:

  • version:最新版本号
  • notes:一些说明性质的信息
  • pub_date:发布日期
  • platforms:对应不同的平台
  • url:即应用程序下载地址
  • signature:sig文件的内容,sig文件与打包的可执行文件在同一个目录下,通常只有在配置了Updater插件时,才会生成这个文件。

其中versionplatforms.[target].urlplatforms.[target].signature是必填项,其余的是选填项。

4. 检查更新

Tauri提供的Updater API,可以用于检查更新:

import { ask } from '@tauri-apps/plugin-dialog'
import { check } from '@tauri-apps/plugin-updater'

async function check_update() {
    const update = await check()
    if (update) {
        if (update.currentVersion !== update.version) {
            const yes = await ask(`发现新版本${update.version},是否前往下载?`, {
                title: '检查更新',
                okLabel: '更新',
                cancelLabel: '取消',
            })
            if (yes) {
                // 我这里选择打开下载链接
                window.open('https://github.com/taiyuuki/eb-code/releases/latest')
            }

        }
    }
}

export { check_update }

check函数会请求我们在tauri.conf.jsonendpoints中配置的json文件地址,返回一个Update对象。

Update对象上有一些属性的方法:

declare class Update extends Resource {
    available: boolean; // 版本是否可用
    currentVersion: string; // 当前程序的版本
    version: string; // 最新的版本
    date?: string;
    body?: string;
    /** 下载更新包 */
    download(onEvent?: (progress: DownloadEvent) => void): Promise<void>;
    /** 安装更新包 */
    install(): Promise<void>;
    /** 下载并安装更新包 */
    downloadAndInstall(onEvent?: (progress: DownloadEvent) => void): Promise<void>;
    close(): Promise<void>;
}

5. 打包时的环境变量

当我们配置了Updater,打包程序时需要我们提供两个环境变量:

  • TAURI_SIGNING_PRIVATE_KEY:私钥app.key的内容
  • TAURI_SIGNING_PRIVATE_KEY_PASSWORD:生成秘钥过程中我们输入的那个密码

TAURI_SIGNING_PRIVATE_KEY是必须的,而TAURI_SIGNING_PRIVATE_KEY_PASSWORD如果缺省,则会在打包过程中让我们手动输入。

注意:在v1版本中,这两个环境变量的名称和v2版本的不一样,分别是TAURI_SIGNING_KEY和TAURI_KEY_PASSWORD。

Mac、Linux

export TAURI_SIGNING_PRIVATE_KEY="Path or content of your private key"
# optionally also add a password
export TAURI_SIGNING_PRIVATE_KEY_PASSWORD=""

Windows

$env:TAURI_SIGNING_PRIVATE_KEY="Path or content of your private key"
<# optionally also add a password #>
$env:TAURI_SIGNING_PRIVATE_KEY_PASSWORD=""

为了不暴露我们的私钥,同时又避免打包时的麻烦,我们可以写一段打包的脚本:

scripts/build.ts

import { readFile } from 'node:fs'
import { resolve } from 'node:path'
import { spawn } from 'node:child_process'
import { promisify } from 'node:util'

async function build() {
    const cwd = process.cwd()
    const readFileAsync = promisify(readFile) // 将readFile转为Promise API
    let key = ''
    let pwd = ''

    try {
        key = await readFileAsync(resolve(cwd, '.tauri/app.key'), 'utf-8') // 读取私钥
        pwd = await readFileAsync(resolve(cwd, '.tauri/password.key'), 'utf-8') // 读取密码
    }
    catch(_) {
        throw new Error('No private key found, private key is used to sign updates, see https://v2.tauri.app/plugin/updater')
    }
    // 执行打包命令,通过env配置环境变量,注意不要忘了原始环境 process.env
    const build_process = spawn('pnpm tauri build', [], {
        cwd,
        env: { 
            TAURI_SIGNING_PRIVATE_KEY: key,
            TAURI_SIGNING_PRIVATE_KEY_PASSWORD: pwd,
            ...process.env,
        },
        shell: true,
        stdio: 'inherit',
    })
    build_process.on('exit', code => {
        if (code !== 0) {
            throw new Error(`Build failed with code ${code}`)
        }
    })
    
}

build()

安装esno,用于执行ts脚本( 如果你是用JS写的,直接用node执行即可)

pnpm i esno -D

将脚本写入package.json

TS

{
    scripts: {
        "tauri:build": "esno ./scripts/build.ts"
    }
}

或JS

{
    scripts: {
        "tauri:build": "node ./scripts/build.js"
    }
}

执行打包脚本

pnpm tauri:build

借助Github Action自动发包

自动发包很简单,使用官方提供的Tauri Action

如果没有配置Updater的话,官方提供的示例就足够了,加上Updater,也只需多配置两个环境变量。

.github/workflows

name: 'publish'

on:
  push:
    branches:
      - release

# This workflow will trigger on each push to the `release` branch to create or update a GitHub release, build your app, and upload the artifacts to the release.

jobs:
  publish-tauri:
    permissions:
      contents: write
    strategy:
      fail-fast: false
      matrix:
        include:
          - platform: 'macos-latest' # for Arm based macs (M1 and above).
            args: '--target aarch64-apple-darwin'
          - platform: 'macos-latest' # for Intel based macs.
            args: '--target x86_64-apple-darwin'
          - platform: 'ubuntu-22.04' # for Tauri v1 you could replace this with ubuntu-20.04.
            args: ''
          - platform: 'windows-latest'
            args: ''

    runs-on: ${{ matrix.platform }}
    steps:
      - uses: actions/checkout@v4

      - name: setup node
        uses: actions/setup-node@v4
        with:
          node-version: lts/*

      - name: install Rust stable
        uses: dtolnay/rust-toolchain@stable
        with:
          # Those targets are only used on macos runners so it's in an `if` to slightly speed up windows and linux builds.
          targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}

      - name: install dependencies (ubuntu only)
        if: matrix.platform == 'ubuntu-22.04' # This must match the platform value defined above.
        run: |
          sudo apt-get update
          sudo apt-get install -y libwebkit2gtk-4.0-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
        # webkitgtk 4.0 is for Tauri v1 - webkitgtk 4.1 is for Tauri v2.
        # You can remove the one that doesn't apply to your app to speed up the workflow a bit.
        
        # 如果你使用的是pnpm,需要先安装pnpm,官方示例使用的是yarn,使用没有这一步。
      - name: install pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 8
          run_install: true

      - name: install frontend dependencies
        run: pnpm install
		
		# 注意这个地方的环境变量,除GITHUB_TOKEN外,其他的需要手动进行配置。
      - uses: tauri-apps/tauri-action@v0
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
          TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
        with:
          tagName: app-v__VERSION__ # the action automatically replaces \_\_VERSION\_\_ with the app version.
          releaseName: 'App v__VERSION__'
          releaseBody: 'See the assets to download this version and install.'
          releaseDraft: true
          prerelease: false
          args: ${{ matrix.args }}

环境变量需要我们在仓库的 Settings -> Secrets and variables -> Action 里进行配置,如下图:

Tauri开发EPUB编辑器(三) 程序检查更新 借助Github Action自动发布安装包Tauri v2版本目前尚

配置好了以后,我们只需用git新建一个名称为release的分支,然后push到仓库既可触发Action,它将自动打包并发布到Release,但它状态是Draft(草稿),所以我们最后还需要手动编辑并将其publish(发布)。

Tauri开发EPUB编辑器(三) 程序检查更新 借助Github Action自动发布安装包Tauri v2版本目前尚

打包时关于图标的问题

最后提一个在线打包时的一个坑,Tauri的对图标的要求会非常严格,很容易遇到以下问题:

# help: message: icon xxx.png is not RGBA

我们借助Tauri CLI提供的工具,对图标进行处理即可:

pnpm tauri icon

或者

cargo tauri icon
> cargo tauri icon --help  
cargo-tauri-icon 1.1.0  
  
Generates various icons for all major platforms  
  
USAGE:  
cargo tauri icon [OPTIONS] [INPUT]  
  
ARGS:  
<INPUT> Path to the source icon (png, 1024x1024px with transparency) [default: ./app-icon.png]  
  
OPTIONS:  
-h, --help Print help information  
-o, --output <OUTPUT> Output directory. Default: 'icons' directory next to the tauri.conf.json file  
-v, --verbose Enables verbose logging  
-V, --version Print version information

详情可见:Icons | Tauri Apps

转载自:https://juejin.cn/post/7382890605682409535
评论
请登录