Skip to main content

构建并发布 Linux 应用到 Snap Store

在典型的开发周期中,您可以使用命令行中的 flutter run 或 IDE 中的“运行”和“调试”选项来测试应用。默认情况下,Flutter 会构建应用的 调试 版本。

当您准备好准备应用的 发布 版本时(例如,要发布到 Snap Store),此页面可以提供帮助。

先决条件

#

要构建并发布到 Snap Store,您需要以下组件:

设置构建环境

#

使用以下说明设置您的构建环境。

安装 snapcraft

#

在命令行中,运行以下命令:

sudo snap install snapcraft --classic

安装 LXD

#

要安装 LXD,请使用以下命令:

sudo snap install lxd

在 snap 构建过程中需要 LXD。安装后,需要配置 LXD 以便使用。对于大多数用例,默认答案都适用。

sudo lxd init
是否要使用 LXD 集群?(yes/no) [default=no]:
您是否要配置新的存储池?(yes/no) [default=yes]:
新存储池的名称 [default=default]:
要使用的存储后端的名称 (btrfs, dir, lvm, zfs, ceph) [default=zfs]:
创建新的 ZFS 池?(yes/no) [default=yes]:
您是否要使用现有的空磁盘或分区?(yes/no) [default=no]:
新循环设备的大小(以 GB 为单位)(最小 1GB)[default=5GB]:
您是否要连接到 MAAS 服务器?(yes/no) [default=no]:
您是否要创建一个新的本地网络桥接?(yes/no) [default=yes]:
新的桥接器的名称应是什么?[default=lxdbr0]:
应使用哪个 IPv4 地址?(CIDR 子网表示法,“auto”或“none”)[default=auto]:
应使用哪个 IPv6 地址?(CIDR 子网表示法,“auto”或“none”)[default=auto]:
您是否希望 LXD 可通过网络访问?(yes/no) [default=no]:
您是否希望自动更新过时的缓存映像?(yes/no) [default=yes]
您是否要打印 YAML "lxd init" 预设?(yes/no) [default=no]:

在第一次运行时,LXD 可能无法连接到其套接字:

尝试与“LXD”提供程序通信时发生错误:无法连接到 LXD 套接字
('/var/snap/lxd/common/lxd/unix.socket')。

这意味着您需要将您的用户名添加到 LXD (lxd) 组,因此请注销您的会话,然后重新登录:

sudo usermod -a -G lxd <您的用户名>

Snapcraft 概述

#

snapcraft 工具根据 snapcraft.yaml 文件中列出的说明构建 snap。 要了解 snapcraft 及其核心概念,请查看Snap 文档Snapcraft 简介。 此页面底部列出了其他链接和信息。

Flutter snapcraft.yaml 示例

#

将 YAML 文件放在 Flutter 项目的 <project root>/snap/snapcraft.yaml 下。(请记住,YAML 文件对空格敏感!)例如:

yaml
name: super-cool-app
version: 0.1.0
summary: 超酷应用
description: 功能强大的超酷应用!

confinement: strict
base: core22
grade: stable

slots:
  dbus-super-cool-app: # 根据您的应用名称进行调整
    interface: dbus
    bus: session
    name: org.bar.super_cool_app # 根据您的应用名称进行调整

apps:
  super-cool-app:
    command: super_cool_app
    extensions: [gnome] # gnome 包含 Flutter 所需的库
    plugs:
    - network
    slots:
      - dbus-super-cool-app
parts:
  super-cool-app:
    source: .
    plugin: flutter
    flutter-target: lib/main.dart # 应用程序的主要入口点文件

以下部分解释了 YAML 文件的各个部分。

元数据

#

snapcraft.yaml 文件的此部分定义和描述应用程序。snap 版本是从构建部分派生的(采用的)。

yaml
name: super-cool-app
version: 0.1.0
summary: 超酷应用
description: 功能强大的超酷应用!

等级、限制和基础

#

此部分定义了 snap 的构建方式。

yaml
confinement: strict
base: core18
grade: stable

等级 :指定 snap 的质量;这与后来的发布步骤有关。

限制 :指定 snap 安装到最终用户系统后将拥有的系统资源访问级别。严格限制将应用程序访问权限限制为特定资源(在 app 部分中由插头定义)。

基础 :snap 设计为自包含应用程序,因此它们需要自己的专用核心根文件系统,称为 basebase 关键字指定用于提供最小公共库集的版本,并在运行时作为应用程序的根文件系统挂载。

应用

#

此部分定义 snap 内存在的应用程序。每个 snap 可以有一个或多个应用程序。此示例只有一个应用程序——super_cool_app。

yaml
apps:
  super-cool-app:
    command: super_cool_app
    extensions: [gnome]

命令 :指向二进制文件(相对于 snap 的根目录),并在调用 snap 时运行。

扩展 :一个或多个扩展的列表。Snapcraft 扩展是可重用的组件,可以在构建和运行时向 snap 公开库和工具集,而无需开发人员拥有包含框架的特定知识。gnome 扩展向 Flutter snap 公开 GTK 3 库。这确保了更小的占用空间和与系统的更好集成。

插头 :系统接口的一个或多个插头的列表。当 snap 严格受限时,这些是提供必要功能所必需的。此 Flutter snap 需要访问网络。

DBus 接口DBus 接口 提供了一种让 snap 通过 DBus 通信的方式。提供 DBus 服务的 snap 使用众所周知的 DBus 名称和使用的总线声明一个插槽。想要与提供 snap 的服务通信的 snap 声明提供 snap 的插头。请注意,需要您的 snap 的 snap 声明才能通过 snap 商店交付并声明此众所周知的 DBus 名称(只需将 snap 上传到商店并请求手动审核,审核人员就会查看)。

当安装提供 snap 时,snapd 将生成安全策略,允许它在指定的总线上侦听众所周知的 DBus 名称。如果指定了系统总线,snapd 还将生成 DBus 总线策略,允许“root”拥有该名称,并且任何用户都可以与该服务通信。非 snap 进程可以通过传统的权限检查来与提供 snap 通信。其他(使用)snap 可能只能通过连接 snap 的接口来与提供 snap 通信。

dbus-super-cool-app: # 根据您的应用名称进行调整
  interface: dbus
  bus: session
  name: dev.site.super_cool_app

部件

#

此部分定义组装 snap 所需的源。

可以使用插件自动下载和构建部件。与扩展类似,snapcraft 可以使用各种插件(例如 Python、C、Java 和 Ruby)来辅助构建过程。Snapcraft 还有一些特殊的插件。

nil 插件 :不执行任何操作,实际构建过程使用手动覆盖处理。

flutter 插件 :提供必要的 Flutter SDK 工具,因此您可以使用它而无需手动下载和设置构建工具。

yaml
parts:
  super-cool-app:
    source: .
    plugin: flutter
    flutter-target: lib/main.dart # 应用程序的主要入口点文件

桌面文件和图标

#

桌面条目文件用于将应用程序添加到桌面菜单。这些文件指定应用程序的名称和图标、它所属的类别、相关的搜索关键字等等。这些文件的扩展名为 .desktop,并遵循 XDG 桌面条目规范 1.1 版。

Flutter super-cool-app.desktop 示例

#

将 .desktop 文件放在 Flutter 项目的 <project root>/snap/gui/super-cool-app.desktop 下。

注意:图标和 .desktop 文件名必须与 yaml 文件中的应用名称相同!

例如:

yaml
[Desktop Entry]
Name=超酷应用
Comment=功能强大的超酷应用
Exec=super-cool-app 
Icon=${SNAP}/meta/gui/super-cool-app.png # 将名称替换为您的应用名称。
Terminal=false
Type=Application
Categories=Education; # 根据您的 snap 类别进行调整。

将您的图标(扩展名为 .png)放在 Flutter 项目的 <project root>/snap/gui/super-cool-app.png 下。

构建 snap

#

snapcraft.yaml 文件完成后,从项目的根目录运行 snapcraft,如下所示。

要使用 Multipass VM 后端:

snapcraft

要使用 LXD 容器后端:

snapcraft --use-lxd

测试 snap

#

构建 snap 后,您将在项目的根目录中获得一个 <name>.snap 文件。

$ sudo snap install ./super-cool-app_0.1.0_amd64.snap --dangerous

发布

#

您现在可以发布 snap 了。该过程包括以下步骤:

  1. 如果您尚未创建,请在 snapcraft.io 上创建一个开发者帐户。
  2. 注册应用名称。注册可以使用 Snap Store Web UI 门户或命令行完成,如下所示:
    snapcraft login
    snapcraft register
  3. 发布应用。阅读下一节以了解如何选择 Snap Store 通道后,将 snap 推送到商店:
    snapcraft upload --release=<channel> <file>.snap

Snap Store 通道

#

Snap Store 使用通道来区分不同版本的 snap。

snapcraft upload 命令将 snap 文件上传到商店。但是,在运行此命令之前,您需要了解不同的发布通道。每个通道包含三个组件:

轨道 :所有 snap 都必须具有名为 latest 的默认轨道。除非另有说明,否则这是隐含的轨道。

风险 :定义应用程序的准备情况。snap 商店中使用的风险级别为:stablecandidatebetaedge

分支 :允许创建短期 snap 序列以测试错误修复。

Snap Store 自动审核

#

Snap Store 对您的 snap 运行多个自动化检查。还可能进行手动审核,具体取决于 snap 的构建方式,以及是否存在任何特定的安全问题。如果检查通过且没有错误,则 snap 将在商店中可用。

附加资源

#

您可以从 snapcraft.io 网站上的以下链接了解更多信息: