Logofpack

Many targets, one command

Build everything this machine can build, preview plans, get JSON results, work in monorepos and clean up.

多目标一条命令

构建这台机器能构建的一切、预览计划、获取 JSON 结果、在 monorepo 中工作并清理。

Choose the targets#

fpack build apk aab ipa          # name them
fpack build --all                # every target this machine can build
fpack build                      # the targets in build.targets
build:
  targets: [apk, aab, ipa, dmg]

Without targets and without build.targets, fpack stops with exit code 2 and asks which targets to build. Aliases work on the command line and in build.targets:

AliasTarget
bundle, appbundleaab
androidapk
iosipa
mac, osx, appmacos
win, zip, portablewindows
setup, installer, innoexe
tar, tgz, tar.gzlinux
debiandeb
fedorarpm
image, AppImageappimage
snapcraftsnap

What --all skips#

--all builds what this machine can build and skips the rest, each with the reason (for example "needs macOS"). Targets needing a missing optional tool (appimage without appimagetool, snap without snapcraft) are skipped too. Naming a target explicitly is stricter: a target this machine cannot build is an error (exit code 3) that points to a CI runner of that OS.

Shared builds#

One flutter build is shared per platform in a run: macos + dmg + pkg build once, linux + deb + rpm + appimage + snap build once, windows + exe + msix build once. Asking for many formats of one platform costs little extra time.

Rehearse and inspect#

fpack build --all --dry-run     # print the plan and every command; run nothing
fpack list                      # every target: platform, extension, whether this machine can build it
fpack doctor apk ipa dmg        # prerequisites of these targets only

Machine-readable results#

fpack build --all --json > result.json

With --json, stdout carries only the JSON result (targets, status, artifact paths, sizes, hashes, notarization state, durations, error excerpts and fixes); human output goes to stderr. Fields and examples: Exit codes and JSON.

Interrupting#

One Ctrl-C stops the running flutter, Gradle or xcodebuild process group gracefully; a second one kills it. The exit code is 130. An interrupted notarization wait keeps processing at Apple; finish it with fpack notarize finish.

Monorepos and other directories#

fpack walks up from the current directory to pubspec.yaml. At a repository root with several Flutter projects it lists them; pick one with -C:

fpack -C apps/client build web --base-href /app/
fpack --config ci/fpack.ci.yaml build apk      # another config file

(--project DIR / -C, --config FILE, FPACK_CONFIG.)

Verbose output, colors and language#

OptionEffect
-v, --verbosestream the full output of every tool
--no-color no colors (also NO_COLOR , FPACK_NO_COLOR ; FORCE_COLOR forces them)
--lang zh|en output language (also FPACK_LANG; default: your OS language)
-y, --yes assume yes / use defaults for questions (for example in fpack init , fpack clean )

Without a TTY, spinners and colors are off and fpack prints a heartbeat line every 60 seconds so a CI job does not time out on silence.

Clean up#

fpack clean                     # remove build/fpack (logs, temporary files)
fpack clean --dist              # also delete the output directory (asks first)
fpack clean --flutter-clean     # also run `flutter clean`
fpack clean --all --dry-run     # show what would be deleted

Next#

The reference for every command and option, and CI recipes.

选择目标#

fpack build apk aab ipa          # 写出名字
fpack build --all                # 这台机器能构建的每个目标
fpack build                      # build.targets 里的目标
build:
  targets: [apk, aab, ipa, dmg]

没有目标也没有 build.targets 时,fpack 以退出码 2 停止并询问要构建哪些目标。别名在命令行和 build.targets 里都可以用:

别名目标
bundle、appbundleaab
androidapk
iosipa
mac、osx、appmacos
win、zip、portablewindows
setup、installer、innoexe
tar、tgz、tar.gzlinux
debiandeb
fedorarpm
image、AppImageappimage
snapcraftsnap

--all 会跳过什么#

--all 构建这台机器能构建的目标,其余的跳过并给出原因(例如“needs macOS”)。需要缺失的可选工具的目标(没有 appimagetool 的 appimage、没有 snapcraft 的 snap)也会被跳过。明确指定目标则更严格:指定一个本机无法构建的目标是错误(退出码 3),并指向对应系统的 CI 机器。

共享构建#

每次运行中,每个平台只做一次 flutter build:macos + dmg + pkg 只构建一次,linux + deb + rpm + appimage + snap 只构建一次,windows + exe + msix 只构建一次。同一平台要多种格式,几乎不增加时间。

预演与查看#

fpack build --all --dry-run     # 打印计划和每条命令,什么都不运行
fpack list                      # 每个目标:平台、扩展名、这台机器能否构建
fpack doctor apk ipa dmg        # 只检查这几个目标的前置条件

机器可读的结果#

fpack build --all --json > result.json

使用 --json 时,stdout 只输出 JSON 结果(目标、状态、产物路径、大小、哈希、公证状态、耗时、错误摘要和修复建议);人类可读的输出走 stderr。字段和示例:退出码与 JSON 输出。

中断#

一次 Ctrl-C 会优雅地停止正在运行的 flutter、Gradle 或 xcodebuild 进程组;第二次则强制结束。退出码是 130。被中断的公证等待会在 Apple 那边继续处理,用 fpack notarize finish 完成它。

Monorepo 与其他目录#

fpack 从当前目录向上找到 pubspec.yaml。在含有多个 Flutter 项目的仓库根目录,它会列出这些项目;用 -C 选择其一:

fpack -C apps/client build web --base-href /app/
fpack --config ci/fpack.ci.yaml build apk      # 另一个配置文件

(--project 目录 / -C、--config 文件、FPACK_CONFIG。)

详细输出、颜色与语言#

选项作用
-v、--verbose输出每个工具的完整输出
--no-color 不使用颜色(也可用 NO_COLOR、FPACK_NO_COLOR;FORCE_COLOR 强制使用颜色)
--lang zh|en输出语言(也可用 FPACK_LANG;默认取你的系统语言)
-y、--yes 默认回答“是”/使用默认值(例如 fpack init、fpack clean)

没有 TTY 时,进度动画和颜色会关闭,fpack 每 60 秒输出一行心跳,避免 CI 因长时间无输出而超时。

清理#

fpack clean                     # 删除 build/fpack(日志、临时文件)
fpack clean --dist              # 同时删除输出目录(会先询问)
fpack clean --flutter-clean     # 同时运行 `flutter clean`
fpack clean --all --dry-run     # 显示将删除什么

下一步#

每个命令和选项的参考,以及 CI 示例。