Skip to main content

將 Linux 應用程式建置並發佈到 Snap Store

如何準備並將 Linux 應用程式發佈到 Snap Store。

在典型的開發週期中, 你可以在命令列使用 flutter run 測試應用程式, 或透過 IDE 中的 RunDebug 選項進行測試。預設情況下, Flutter 會建置應用程式的 debug 版本。

當你準備好要建立應用程式的 release 版本時, 例如要發佈到 Snap Store 或其他 替代通道, 本頁將提供協助。

先決條件

#

若要建置並發佈到 Snap Store,你需要以下元件:

設定建置環境

#

請依照下列說明設定你的建置環境。

安裝 snapcraft

#

在命令列執行以下指令:

sudo snap install snapcraft --classic

安裝 LXD

#

要安裝 LXD,請使用以下指令:

sudo snap install lxd

在 snap 建置過程中需要安裝 LXD。 安裝完成後,還需要對 LXD 進行設定才能使用。 大多數情境下,預設答案已經適用。

sudo lxd init
Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want to configure a new storage pool? (yes/no) [default=yes]:
Name of the new storage pool [default=default]:
Name of the storage backend to use (btrfs, dir, lvm, zfs, ceph) [default=zfs]:
Create a new ZFS pool? (yes/no) [default=yes]:
Would you like to use an existing empty disk or partition? (yes/no) [default=no]:
Size in GB of the new loop device (1GB minimum) [default=5GB]:
Would you like to connect to a MAAS server? (yes/no) [default=no]:
Would you like to create a new local network bridge? (yes/no) [default=yes]:
What should the new bridge be called? [default=lxdbr0]:
What IPv4 address should be used? (CIDR subnet notation, "auto" or "none") [default=auto]:
What IPv6 address should be used? (CIDR subnet notation, "auto" or "none") [default=auto]:
Would you like LXD to be available over the network? (yes/no) [default=no]:
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:

在第一次執行時,LXD 可能無法連接到其 socket:

An error occurred when trying to communicate with the 'LXD'
provider: cannot connect to the LXD socket
('/var/snap/lxd/common/lxd/unix.socket').

這表示你需要將你的使用者名稱加入 LXD(lxd)群組,因此請先登出你的工作階段,然後再重新登入:

sudo usermod -a -G lxd <your username>

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: Super Cool App
description: Super Cool App that does everything!

confinement: strict
base: core22
grade: stable

slots:
  dbus-super-cool-app: # adjust accordingly to your app name
    interface: dbus
    bus: session
    name: org.bar.super_cool_app # adjust accordingly to your app name and

apps:
  super-cool-app:
    command: super_cool_app
    extensions: [gnome] # gnome includes the libraries required by flutter
    plugs:
    - network
    slots:
      - dbus-super-cool-app
parts:
  super-cool-app:
    source: .
    plugin: flutter
    flutter-target: lib/main.dart # The main entry-point file of the application

以下章節將說明 YAML 檔案的各個部分。

Metadata

#

此區塊在 snapcraft.yaml 檔案中用來定義與描述應用程式。snap 版本會從 build 區塊中取得(採用)。

yaml
name: super-cool-app
version: 0.1.0
summary: Super Cool App
description: Super Cool App that does everything!

Grade、confinement 與 base

#

本節說明如何建構此 snap。

yaml
confinement: strict
base: core22
grade: stable
Grade(等級)

指定 snap 的品質;這在後續的發佈步驟中會用到。

Confinement(限制級別)

指定 snap 安裝到最終用戶系統後,能夠存取的系統資源級別。Strict confinement(嚴格限制)會將應用程式的存取權限限制在特定資源(由 app 區段中的 plugs 定義)。

Base(基礎)

Snap 設計為自包含的應用程式,因此需要自己的私有核心根檔案系統,稱為 basebase 關鍵字用來指定所使用的版本,提供最小集合的共用函式庫,並在執行時掛載為應用程式的根檔案系統。

Apps(應用程式)

#

此區段定義 snap 內包含的應用程式。每個 snap 可以包含一個或多個應用程式。本範例僅包含一個應用程式——super_cool_app。

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

指定相對於 snap 根目錄的二進位檔,並於 snap 被呼叫時執行。

Extensions

一個或多個 extension(擴充套件)的清單。Snapcraft extension 是可重複使用的元件,能在建置與執行階段,將一組函式庫與工具暴露給 snap,而開發者無需具體了解所包含的 framework。gnome extension 會將 GTK 3 函式庫暴露給 Flutter snap。這可確保更小的安裝體積並提升與系統的整合度。

Plugs

一個或多個系統介面 plug(插頭)的清單。當 snap 採用嚴格隔離時,這些 plug 是提供必要功能所需。此 Flutter snap 需要網路存取權限。

DBus interface

DBus 介面 提供 snap 之間透過 DBus 通訊的方式。提供 DBus 服務的 snap 需宣告一個 slot(插槽),指定 well-known DBus 名稱及所使用的 bus。欲與該服務通訊的 snap 則需宣告一個 plug,連接到提供服務的 snap。請注意,若要讓您的 snap 能透過 snap store 發佈並取得此 well-known DBus 名稱,需進行 snap 宣告(只需將 snap 上傳至商店並申請人工審查,審查員會進行審核)。

當提供服務的 snap 安裝時,snapd 會產生安全性政策,允許其在指定的 bus 上監聽該 well-known DBus 名稱。若指定的是 system bus,snapd 也會產生 DBus bus 政策,允許 'root' 擁有該名稱,並允許任何使用者與該服務通訊。非 snap 的程序可依傳統權限檢查與提供服務的 snap 通訊。其他(消費端)snap 則僅能透過連接兩個 snap 的介面來與提供服務的 snap 進行通訊。

dbus-super-cool-app: # adjust accordingly to your app name
  interface: dbus
  bus: session
  name: dev.site.super_cool_app

Parts

#

本節說明組裝 snap 所需的來源(parts)。

Parts 可以透過插件(plugins)自動下載與建置。與 extensions 類似,snapcraft 可以使用各種插件(如 Python、C、Java 和 Ruby)來協助建置流程。Snapcraft 也提供了一些特殊插件。

nil 插件

不執行任何動作,實際的建置流程需透過手動覆寫來處理。

flutter 插件

提供必要的 Flutter SDK 工具,讓你無需手動下載與設定建置工具即可使用。

yaml
parts:
  super-cool-app:
    source: .
    plugin: flutter
    flutter-target: lib/main.dart # The main entry-point file of the application

Desktop 檔案與圖示

#

Desktop entry 檔案(桌面啟動項目檔案)用於將應用程式新增到桌面選單。這些檔案會指定應用程式的名稱與圖示、所屬分類、相關搜尋關鍵字等資訊。這些檔案的副檔名為 .desktop,並遵循 XDG Desktop Entry Specification 1.1 版規範。

Flutter super-cool-app.desktop 範例

#

請將 .desktop 檔案放在你的 Flutter 專案中的 <project root>/snap/gui/super-cool-app.desktop 目錄下。

注意:icon 與 .desktop 檔案名稱必須與你在 yaml 檔案中設定的應用程式名稱相同!

例如:

yaml
[Desktop Entry]
Name=Super Cool App
Comment=Super Cool App that does everything
Exec=super-cool-app
Icon=${SNAP}/meta/gui/super-cool-app.png # Replace name with your app name.
Terminal=false
Type=Application
Categories=Education; # Adjust accordingly your snap category.

請將副檔名為 .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 的網頁管理介面註冊,或是使用命令列如下操作:
    snapcraft login
    snapcraft register
    
  3. 發佈應用程式。在閱讀下一節以了解如何選擇 Snap Store 頻道後,將 snap 推送到商店:
    snapcraft upload --release=<channel> <file>.snap
    

Snap Store 頻道(channels)

#

Snap Store 使用頻道(channels)來區分不同版本的 snap。

snapcraft upload 指令會將 snap 檔案上傳到 Snap Store。然而,在執行此指令之前, 你需要先了解不同的發佈頻道。每個頻道由三個組成部分構成:

Track

所有 snap 都必須有一個預設的 track,稱為 latest。 除非另有指定,否則會使用這個預設 track。

Risk

定義應用程式的穩定程度。 Snap Store 使用的風險等級包括: stablecandidatebetaedge

Branch

允許建立短期存在的 snap 分支,用於測試 bug 修復。

Snap Store 自動審查

#

Snap Store 會對你的 snap 進行多項自動化檢查。 根據 snap 的建置方式,以及是否有特定的安全性疑慮, 也可能會進行人工審查。如果所有檢查都順利通過, 你的 snap 就會在商店中上架。

其他 snapcraft 資源

#

你可以從 snapcraft.io 網站上的以下連結, 學習更多相關資訊:

其他部署資源

#

一款全方位的 Flutter 應用程式打包與發佈工具, 為你提供一站式解決方案,滿足各種發佈需求。

支援多種主流打包格式,如 appimage、deb、pacman、rpm 等。

用於離線建置 Flutter 應用程式的 Flatpak manifest 工具。

支援 Flatpak 準備,可用於發佈到 Flathub