likes
comments
collection
share

🔥基于GitHub的Electron自动发布与更新🔥

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

前言

公众号:【可乐前端】,分享前端面试与web实战知识

本文介绍了如何在 Electron 中自动发布到 GitHub 以及自动更新的实现方案,话不多说,让我们立刻开始。

自动发布

我们可以依托 GitHub 作为安装包的托管平台,对于每一次的版本发布,都可以在对应的仓库里新建一个 release ,并把对应的安装包资源传输到 release 中。

🔥基于GitHub的Electron自动发布与更新🔥

打包的时候可以使用 electron-builder 这个库,在根目录下创建 electron-builder.yml 配置文件。写入如下配置:

publish:
  provider: github
  owner: '你的账户名'
  repo: '你的仓库名'
  token: '你的token' 
  releaseType: 'release'

如何生成 GitHub Token 已经在上一期文章中介绍过,感兴趣的同学可以在上面链接中点开查看。然后修改打包的命令如下:

"build:mac": "npm run build && electron-builder --mac --config --publish always"

这样在我们在我们执行完打包命令之后,会自动把产物推送到 GitHub 对应的 release 中。这里需要注意的一点是,版本号都是基于 package.jsonversion 字段,所以在每一次打包发布之前记得先修改这里的值。

🔥基于GitHub的Electron自动发布与更新🔥

可以看到在打包完成之后,会自动把产物推送到 GitHub 中,我们可以在 GitHub 对应的发布分支上看到对应的内容。

🔥基于GitHub的Electron自动发布与更新🔥

publishprovider 的可选值

electron-builder 中,publish 部分的 provider 字段用于指定发布提供者。以下是一些常见的 provider 取值:

GitHub (github):

使用 GitHub 来发布应用程序。设置 provider: github 时,需要提供 GitHub 仓库的相关信息,例如 repoownerGitHub Personal Access Token

    publish:
      provider: github
      repo: owner/repo
      owner: owner
      token: $GITHUB_TOKEN

Generic (generic):

使用通用的发布提供者,这通常用于自定义或私有的发布流程。需要指定发布的目标地址、协议等信息。

    publish:
      provider: generic
      url: "https://your-custom-publish-server.com"
      channel: "latest"

当使用通用发布模式时(例如 https://your-custom-publish-server.com),那么这个自定义服务器应该支持以下几个路由:

  • /update/${platform}/${arch}/${version}:

    • ${platform}: 平台,例如 win, mac, 或 linux
    • ${arch}: 架构,例如 x64arm64
    • ${version}: 版本号,例如 1.0.0

    该路由用于获取应用程序更新信息,返回一个 JSON 对象,其中包含更新的版本号、下载地址等信息。

    示例响应:

    {
      "name": "YourApp",
      "notes": "Release notes for version 1.1.0",
      "pub_date": "2024-02-25T12:00:00Z",
      "url": "https://your-custom-publish-server.com/downloads/YourApp-1.1.0.zip",
      "version": "1.1.0"
    }
    
  • /download/${version}/${filename}:

    • ${version}: 版本号,例如 1.0.0
    • ${filename}: 文件名,例如 YourApp-1.0.0.zip

    该路由用于提供应用程序的下载文件,返回文件的二进制内容。

  • /latest:

    该路由用于获取最新版本的应用程序信息,返回一个 JSON 对象,其中包含最新版本的版本号、下载地址等信息。

    示例响应:

    {
      "name": "YourApp",
      "notes": "Release notes for latest version",
      "pub_date": "2024-02-25T12:00:00Z",
      "url": "https://your-custom-publish-server.com/downloads/YourApp-latest.zip",
      "version": "latest"
    }
    

Bintray (bintray):

使用 Bintray 提供者,这通常用于发布到 JCenter 仓库。需要提供 Bintray 仓库的相关信息,例如 ownerpackagerepo 等。

publish:
  provider: bintray
  owner: bintray-owner
  package: bintray-package
  repo: bintray-repo
  user: bintray-username
  token: $BINTRAY_API_KEY   

S3 (s3):

使用 Amazon S3 提供者,用于将应用程序发布到 Amazon S3 存储桶。需要提供 S3 存储桶的相关信息。

    publish:
      provider: s3
      bucket: your-s3-bucket
      acl: public-read

自动更新

自动发布处理完之后,接下来介绍自动更新。自动更新可以使用electron-updater这个库。首先在应用初始化的时候,需要查看当前应用是否有新版本可用,即是否需要自动更新;如果当前有新版本可用,则下载新版本的资源,下载完之后就可以重启应用了。

介绍一下用到electron-updater中的API:

  • checkForUpdates:检查是否有新更新可用
  • downloadUpdate:下载更新
  • quitAndInstall:安装更新
  • on:监听事件
    • checking-for-update:检查更新中
    • update-available:有新版本可用
    • update-not-available:没有新版本可用
    • error:错误事件
    • update-downloaded:更新下载完毕
    • download-progress:下载事件,其中包括总下载量、已下载量等属性
      • total:下载的文件的总字节数
      • delta: 表示自上次进度事件以来已下载的字节数
      • transferred: 表示自下载开始以来已经传输的字节数
      • percent: 表示下载完成的百分比
      • bytesPerSecond: 表示当前下载速度,即每秒传输的字节数

了解了上面的知识之后,可以实现一个监听更新的函数listenAutoUpdate,在app ready时调用。

import { autoUpdater } from 'electron-updater'
import { COMMON_ERROR_LOG } from '../event'
import { app, dialog } from 'electron'
export default (mainWindow) => {
  const sendStatusToWindow = (text) => {
    mainWindow.webContents.send(COMMON_ERROR_LOG, `update msg:${text}`)
  }
  autoUpdater.checkForUpdates()
  autoUpdater.autoDownload = false
  autoUpdater.autoInstallOnAppQuit = true
  autoUpdater.on('checking-for-update', () => {
    sendStatusToWindow('Checking for update...')
  })

  autoUpdater.on('update-available', (info) => {
    // 当有新版本可用时,弹窗提示用户
    dialog
      .showMessageBox({
        type: 'info',
        title: '新版本可用',
        message: '有一个可用的新版本,要更新吗',
        buttons: ['是', '否']
      })
      .then((result) => {
        if (result.response === 0) {
          // 用户选择更新,触发下载和安装
          autoUpdater.downloadUpdate()
        }
      })
  })

  autoUpdater.on('update-not-available', (info) => {
    sendStatusToWindow('Update not available.')
  })

  autoUpdater.on('error', (err) => {
    sendStatusToWindow(err)
  })

  autoUpdater.on('update-downloaded', () => {
    // 处理下载完成的情况
    dialog
      .showMessageBox({
        type: 'info',
        title: '更新下载完成',
        message: '点击确定重启获取最新内容',
        buttons: ['确定']
      })
      .then(() => {
        // 调用 quitAndInstall 来安装更新
        autoUpdater.quitAndInstall()
      })
  })
  autoUpdater.on('download-progress', (progressObj) => {
    sendStatusToWindow(JSON.stringify(progressObj))
  })
}

上面的代码主要做了如下的事情:

  • 检查是否有更新。
  • 监听自动更新的不同阶段的事件,包括检查更新、更新可用、更新未可用、下载进度以及下载完成。
  • 根据不同事件的触发,执行相应的操作,例如弹出提示用户更新的对话框、显示下载进度等。

Mac 中需要注意的坑:

  1. 在一些脚手架生成的代码中会有这么一段代码:
app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
      app.quit()
    }
})

这样资源占用导致自动更新失败,需要把这个 if 去掉

  1. macOS 上,应用程序必须得到签名后才能自动更新。 这是 Squirrel.Mac 的要求。

最后

以上就是本文的所有内容,介绍了 Electron 中自动发布与更新的一些方法。如果你觉得有意思的话,点点关注点点赞吧~

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