fpack 1.1.15
fpack: ^1.1.15 copied to clipboard
Package Flutter apps into release artifacts for every platform (apk, aab, ipa, dmg, exe, msix, deb, rpm, AppImage, web) with one command. Native Go core, thin Dart launcher.
Changelog #
1.1.15 #
Fixed #
fpack doctorandfpack build ipawarned "no DEVELOPMENT_TEAM set in ios/Runner.xcodeproj – signing will probably fail" even when the team was configured withios.team_idin fpack.yaml: only the Xcode project was checked. A team fromios.team_idnow counts (it wins over the project'sDEVELOPMENT_TEAM, which stays the fallback), also for the "Apple Distribution certificate for team …" check, the doctor line and the generated ExportOptions.plist.ios.team_idhas no flag or environment variable, and the macOS targets have no equivalent check.
1.1.14 #
Added #
- macOS provisioning profiles for Developer ID apps:
macos.sign.provisioning_profile(--provisioning-profile,FPACK_MACOS_PROVISIONING_PROFILE) andmacos.sign.provisioning_profiles(bundle id → profile, for app extensions, login items and other nested bundles). fpack copies each profile toContents/embedded.provisionprofile(replacing Xcode's development profile) and signs inside-out: nested bundles with their own entitlements, then the app. - Profile validation before the Xcode build and again on the built app: Developer ID type (
ProvisionsAllDevices, noProvisionedDevices), team, signing certificate (the profile must list the exact Developer ID Application certificate), app id (wildcards allowed), expiry, and every restricted entitlement (aps-environment, iCloud, associated domains, keychain access groups, …) with consistent values (e.g.aps-environmentproduction). Errors are in English and Chinese and say how to fix them. - Restricted entitlements without a profile, or an app that embeds Xcode's development profile, now stop the build before Developer ID signing (otherwise the signed app does not launch:
RBSRequestErrorDomain Code=5, POSIX 163).macos.sign.profile_check: false(FPACK_MACOS_PROFILE_CHECK) turns the checks off.fpack doctorreports the same problems. macos.smoke_test(--smoke-test,FPACK_MACOS_SMOKE_TEST) andmacos.smoke_test_seconds: after signing (before notarization) fpack opens the app, checks that it is still running after N seconds and quits it; a failure shows the launch error and thelog showcommand to find the reason.
1.1.13 #
Fixed #
snapwithlinux.snap.build_mode: lxdormultipassfailed at the end with "Cannot create packages outside of the project tree": fpack passed snapcraft an absolute host path for--output, which does not exist inside the build instance. It now passes a path relative to the snapcraft project.
Changed #
- The generated snapcraft.yaml sets
titlefrom the app's display name. - Documented that a snap is always for the build machine's architecture (LXD/Multipass do not cross-compile Flutter).
- New CI workflow
snap-modes.ymlbuilds the example snap with LXD and with Multipass for real, then installs, starts and removes it.
1.1.12 #
Added #
- New
snaptarget (aliassnapcraft): fpack generatessnap/snapcraft.yamlaround the already built bundle (dump plugin, so Flutter is not rebuilt), with basecore24,strictconfinement, thegnomeextension, desktop/wayland/x11/opengl/audio-playback/network/home plugs, a.desktopfile and the icon insnap/gui/, and version, summary, description, license and website from the config. linux.snapkeys:name,summary,description,base(core24/core22),grade,confinement(strict/classic/devmode),license,plugs,extensions,stage_packages,apps,desktop,template(your own snapcraft.yaml with placeholders),build_modeandextra_args.linux.snap.build_mode/FPACK_SNAP_BUILD_MODE:auto(the default) usesdestructiveon the matching Ubuntu release, otherwiselxd;multipassis also available. In destructive mode fpack runs snapcraft withsudo -nunless it is already root, then gives the build files back to your user.fpack doctorand preflight checks for snapcraft and LXD/Multipass (with install commands), for a host that does not match the base, and for sudo that would ask for a password. The E2E workflow builds, installs, starts and removes a snap on Ubuntu 24.04.
1.1.11 #
Fixed (documentation) #
- Hooks on Windows run through
cmd /S /C(docs saidcmd /C);--obfuscatehelp and examples give the real split-debug-info default<output>/debug-info/<platform>. - Corrected messages quoted in troubleshooting and the skill (Inno Setup not found, no Flutter project in a monorepo) and added the "which targets?" case;
fpack buildwithout targets usesbuild.targets, otherwise exits 2 (the skill said it built defaults for this OS). - Key count is 196;
output.dironly renders{app} {version} {build} {flavor} {mode};--notarizewithout credentials uses the keychain profileNotaryProfile; the mirror download asset ends in.exeon Windows; corrected the skill's export-method list, exit-code sentence andinit --yeswording, and the language-detection order.
Added #
- Documented the Windows signing env vars in every summary table and a new "Other variables fpack reads" section (Flutter/Android/Java lookup, config/cache dirs, locale, color,
COLUMNS). - Exit-code tables are generated from one source in the code; new tests check that every
FPACK_*variable, config key, YAML example,fpack …command line, flag and target in the docs matches the code, and that every public variable is documented in English and Chinese.
1.1.10 #
Changed #
- Go core is clean under JetBrains Qodana / GoLand inspections as well (63 → 0): results of
fmt.Fprint*into builders are handled explicitly,switches over iota constants have explicit defaults,AndroidSigninguses pointer receivers only, and unused constants, variables and functions were removed (including the never-injectedversion.Commit). No user-visible behavior change.
1.1.9 #
Changed #
- Go core is lint-clean: zero findings from
go vet,staticcheck -checks alland golangci-lint (errcheck, revive, govet incl. shadow, errorlint, gocritic, nilerr, unparam, misspell, …) on Linux, Windows and macOS builds. CI has a newlintjob, andgo/.golangci.ymlandgo/qodana.yamlare in the repository. - Errors from failed staging steps of Linux packages (creating directories, setting icon permissions) are now reported instead of being ignored, and wrapped errors keep their cause (
%w). - The internal "no Flutter SDK found" error text is now lowercase (the message users see is unchanged).
1.1.8 #
Added #
- Complete, optional Windows code signing (
windows.sign):- certificate sources:
.pfx(certificate+password), the certificate store bythumbprint(/sha1) orsubject(/n) withstore(/s) andmachine_store(/sm), or a signtool plugin such as Azure Trusted Signing (dlib+dlib_metadata); new env varsFPACK_WINDOWS_CERT_SUBJECT,FPACK_WINDOWS_SIGN_DLIB,FPACK_WINDOWS_SIGN_DLIB_METADATA; - signs
filesof the Release folder (default*.exeand*.dll, previously only the app exe) before zipping/packaging, the Inno Setup installer and uninstaller, and the MSIX (store certificates throughmsix:create --signtool-options; withdlibfpack signs the finished MSIX); - SHA-256 + RFC 3161 timestamp,
description(/d) andurl(/du);signtool verify /paafter signing (verify, a failure is a warning); - signtool is found in the newest Windows SDK (by version, host architecture) or PATH;
fpack doctorreports it and thewinget install Microsoft.WindowsSDK.10.0.26100fix; checks for a missing .pfx or dlib metadata.
- certificate sources:
1.1.7 #
Fixed #
msixfailed on every build: fpack passed--description, whichmsix:createdoes not accept. The msix package reads the description frompubspec.yamlonly; fpack now prints themsix_configentry to add whenwindows.msix.description/app.descriptiondiffer.- Windows hooks with quotes (e.g.
echo %FPACK_OUTPUT_DIR% > "out file.txt") failed with "The directory name is invalid": hooks now reachcmd /S /Cverbatim.
Added #
fpack doctor/ build checks warn on Windows when the project path contains non-ASCII characters, whereflutter build windowsfails.- Docs: Windows notes (project path, MSIX description,
%VAR%in hooks).
1.1.6 #
Added #
- AI agent skill: the package now ships the package skill
fpack-cli(skills/fpack-cli/SKILL.md), which teaches AI coding agents how to use fpack (install,init,doctor, targets, configuration andFPACK_*variables, signing, macOS notarization, CI, troubleshooting). Install it withdart pub add dev:fpackanddart run skills@ get --package fpack. Documented on the website (AI agent skill page) and in the READMEs.
Changed #
- The CI examples in the READMEs, the website and the skill pin the current fpack version and the action versions used by fpack's own workflows; a test keeps them current.
1.1.5 #
Changed #
- The output language follows the operating system language: Chinese (any
zhvariant) → Chinese, everything else → English. Precedence:--lang>FPACK_LANG> OS language. On macOS the UI language (AppleLanguages) now wins over Terminal'sLANG(usually derived from the region, e.g.en_US.UTF-8on a Chinese system); on Windows the display language (GetUserDefaultUILanguage) wins overLANGfrom Git Bash; explicitLC_ALL/LC_MESSAGESstill override. Linux readsLC_ALL,LC_MESSAGES,LANGUAGE,LANG. The macOS lookup is cached and refreshed when the system preferences change. - The Dart launcher's own messages (downloading/building the core, errors and fixes) are now localized too.
- Every user-facing text follows the selected language: config validation errors, usage lines, "did you mean" suggestions, the
error:prefix, example values in thefpack inittemplate and docs. Tests check that English output contains no Chinese and Chinese output (including the generatedfpack.yamlandNOTARIZATION.md) has no English prose left.
1.1.4 #
Added #
- Documentation website: https://matkurban.github.io/fpack/ (English) and https://matkurban.github.io/fpack/zh/ (Chinese) – getting started, every command, every
fpack.yamlkey andFPACK_*variable (generated from the core, so it stays accurate), platform guides (Android signing, iOS, macOS signing + notarization incl. how to get certificates and credentials, Windows, Linux, web), CI recipes, troubleshooting, FAQ, search and dark mode. Built with Jaspr inwebsite/, deployed by GitHub Actions. example/: Aurora Notes, a small Flutter app with Android flavors,--dart-define-from-fileper flavor, hooks, Linux packaging metadata and a fully commentedfpack.yaml(signing via environment variables, macOS dmg/pkg, Windows exe/msix, Linux deb/rpm/AppImage, web). Packaged for real in E2E.
Changed #
- Documentation links printed by the CLI (
fpack help, config errors,fpack initheader, signing notes) and in the JSON schema now point to the documentation website;pubspec.yamllists it asdocumentation.
Fixed #
- A flavor that only exists on Android (e.g.
build.flavor: prodwith Gradle productFlavors) no longer breaks iOS/macOS builds of a project whose Xcode projects define no custom schemes: the flavor is not passed toflutter build ios/macosthere (Flutter would reject it), with a note. Scheme detection now also includes per-user and workspace schemes, likexcodebuild -list.
1.1.3 #
Changed #
- An unknown
--flavor/build.flavoris now an error (exit 3) when the project defines flavors (Android productFlavors, shared Xcode schemes), with a "did you mean" suggestion or the list of available flavors. If no flavors are detected it stays a warning, since detection is heuristic. fpack doctor(andfpack targets) no longer listapk/aabas ready to build when Java is missing or older than 17; builds still try (Gradle may find a JDK fpack cannot see).hooks.post_buildis skipped when every target failed its checks before building (nothing was built); it still runs after build failures withFPACK_SUCCESS=0.- The JSON schema accepts target aliases in
build.targets(bundle,ios,setup, …), matching the command line.
Fixed #
hooks.post_builddocumentation:FPACK_SUCCESSis1/0.${VAR}interpolation now works in every key, including booleans, numbers, enums and lists (e.g.sign: ${SIGN}), as documented; previously typed keys failed to parse.build.targetsinfpack.yamlis validated even when targets are given on the command line, with "did you mean" suggestions (typo suggestions now treat swapped letters as one edit:wbe→web).- Unknown placeholders in
output.name/output.names.<target>are reported by validation instead of ending up literally in file names. - Wrong-type sections now say "expected a section of keys" instead of Go type names.
- JSON schema: accepts
${VAR}for non-string keys, validatesandroid.abisand the target names underoutput.names. - All missing tools of a target are reported at once (not one per run); flavor hints no longer have a missing target name;
doctorno longer repeats the same tool line for deb/rpm/appimage. - The monorepo hint quotes project paths with spaces (
fpack -C 'my app'). - Launcher download: honors
HTTPS_PROXY/HTTP_PROXY/NO_PROXY, and gives up after 30 s without data (instead of hanging) so it falls back to the next resolution step. - README: accurate key count and description of environment overrides.
CI #
- E2E builds projects in paths with spaces and CJK characters on Linux and Windows, including the monorepo-root hint and running from a subdirectory.
1.1.2 #
Fixed #
- macOS notarization:
notarytool submituploads that fail because of the network (e.g.abortedUpload … HTTPClientError.deadlineExceededfrom Apple's S3 storage) are retried twice (after 20 s and 60 s) instead of failing the target; nothing is recorded until Apple returns a submission id. - Failed build steps now pick their hint from the command output first: an upload timeout no longer suggests re-creating the keychain profile ("create the profile once …"); it explains that the network failed and nothing was submitted.
1.1.1 #
Launcher: verified prebuilt cores first #
- The Dart launcher now prefers a verified prebuilt binary over a local
go build. Resolution order:FPACK_CORE→ cached core of the matching version → bundledprebuilt/binary (SHA-256 frommanifest.json) → download from the GitHub Release (SHA-256 fromchecksums.txt) → only if the download fails or is disabled, a local build from the bundled Go sources. - The local fallback is announced clearly:
fpack: note: no verified prebuilt core available (<reason>)followed by the Go version and path used, and a confirmation after the build. - Controls:
FPACK_NO_DOWNLOAD=1(offline: bundled binary or local build),FPACK_DOWNLOAD_URL(mirror),FPACK_GO=<path>/FPACK_GO=none(pick Go / never build locally — a failed download is then a clear error with download links),FPACK_REBUILD=1(developers: build locally first),FPACK_HOME. fpack --wrapper-infoshows the Go version and the resolution order.- When nothing works, the error lists every attempt plus concrete fixes (network / mirror, install Go, or download the binary and set
FPACK_CORE).
Documentation #
README.mdis now English (shown on pub.dev); the Chinese README moved toREADME.ZH.md;README.en.mdwas removed. Both have a language switch at the top.- New section on obtaining macOS signing and notarization credentials (README, README.ZH and
doc/configuration.md§2.13): Developer ID Application/Installer certificates,notarytool store-credentialskeychain profile (Apple ID + app-specific password from account.apple.com + Team ID), App Store Connect API key (.p8, Key ID, Issuer ID), exporting certificates as .p12 from Keychain Access and importing them on CI runners, mapped to the fpack.yaml keys andFPACK_*variables. - Hints in the core point to
README.md/README.ZH.md/doc/configuration.md.
1.1.0 #
Everything configurable #
- One key registry drives
FPACK_*environment variables, validation, the JSON schema (schema/fpack.schema.json,fpack schema), thefpack inittemplate and the key/env tables indoc/configuration.md— they can no longer drift apart. 188 keys in total, 121 new:- app:
copyright,license,support_url;publisherfalls back to the CompanyName inwindows/runner/Runner.rc. - build:
tree_shake_icons. output:names(per-target templates),checksum_algorithm(sha256|sha512); new placeholders{target}and{date}. - hooks:
pre_build,pre_package.<target>,post_package.<target>,post_buildwithFPACK_*environment (artifact paths, version, success). - android:
project_args,signing.v1–v4(re-sign with apksigner, v4 writes.idsig). - ios:
team_id,signing_style,signing_certificate,provisioning_profiles,destination,thinning,upload_symbols,strip_swift_symbols,manage_app_version_and_build_number,export_options→ fpack generates ExportOptions.plist. - macos:
sign.hardened_runtime, notary API key (notary_api_key,notary_api_key_id,notary_api_issuer) and Apple ID (notary_apple_id,notary_team_id,notary_password) credentials,notarize.wait; DMG layout (backgroundvia create-dmg,window_position,window_size,icon_size,app_position,applications_position,volume_icon,license,format,filesystem); pkgmin_os,require_restart,relocatable,preinstall,postinstall,version. - windows:
sign.*(signtool with .pfx or thumbprint: app exe, Inno installer + uninstaller, msix;timestamp_url,description,signtool); Inno Setuppublisher,publisher_url,support_url,updates_url,default_dir,group_name,desktop_icon,run_after_install,license_file,info_before,info_after,setup_icon,wizard_image,wizard_small_image,wizard_style,compression,min_version,privileges,languages(bundled Chinese translation);msix.*metadata (display name, publisher, identity, capabilities, languages, logo, file extensions, protocol activation, execution alias, start at login, store, version, certificate, sign, os_min_version). - linux:
prefix,generic_name,keywords,mime_types,startup_wm_class,icon_sizes(hicolor theme),metainfo; debsection,priority,recommends,suggests,conflicts,preinst/postinst/prerm/postrm; rpmgroup,license,pre/post/preun/postun; AppImageupdate_information,extra_args. - web:
source_maps,optimization_level,csp,web_define,static_assets_url,web_resources_cdn.
- app:
- Validation: unknown keys with "did you mean", type errors with line numbers, enums and ranges, conflicting combinations, missing files for the targets being built.
fpack initlists every key with zh/en comments (--lang), allowed values, defaults, examples and env/flag names, pre-filled from the project (ids, flavor, publisher, define files, team id, Inno AppId…); asks for the default flavor when Android flavors exist; never overwrites: an existing file getsfpack.yaml.new+ a diff (--forcereplaces). The generated file references the JSON schema for editor completion.- New environment variables:
FPACK_NOTARIZE_WAIT,FPACK_NOTARY_APPLE_ID,FPACK_NOTARY_TEAM_ID,FPACK_NOTARY_PASSWORD,FPACK_NOTARY_API_KEY,FPACK_NOTARY_API_KEY_ID,FPACK_NOTARY_API_ISSUER,FPACK_WINDOWS_CERTIFICATE,FPACK_WINDOWS_CERTIFICATE_PASSWORD,FPACK_WINDOWS_CERT_THUMBPRINT.
Friendlier macOS notarization #
- Right after
notarytool submitreturns an id, fpack writesNOTARIZATION.md(zh/en) andnotarization.jsoninto the output directory: artifact + SHA-256, submission id, time, the credential kind (never secrets) and copy-pastenotarytool info/wait/log,stapler staple/validate,spctlandfpack notarizecommands. The files are updated with the final status; for Invalid submissions Apple's log is downloaded and summarized with fixes. - While waiting: elapsed time and a hint that Ctrl-C only stops waiting (the submission continues at Apple); Ctrl-C prints where the record is and keeps the uploaded file.
macos.notarize.wait: false/FPACK_NOTARIZE_WAIT=false/--notarize-no-wait: submit and finish; the summary and--jsonmark the artifactsubmitted.- New commands
fpack notarize status [dir|id]andfpack notarize finish [dir](wait, staple DMG/pkg/app zip, rewrite checksums, summarize rejections).
Other #
fpack schemacommand.--json: artifacts carrynotarization(state, id, status, record path).
Fixed #
- Android projects with productFlavors but no flavor failed only after a full Gradle build ("Gradle build failed to produce an .apk file"); fpack now stops at preflight and suggests
--flavor. - A flavor set for Linux/Windows/Web printed a warning per target and leaked into file names; it is now a single note and
{flavor}is empty for platforms without flavor support. - apksigner re-signing (
android.signing.v1–v4) failed when the output directory did not exist yet; APKs are now signed in the staging directory and moved into place. - Real builds ignored
output.namesand thepre_package/post_packagehooks (only--dry-runapplied them). appimagetoolwrote the.zsyncfile (withlinux.appimage.update_information) into the project root; it now runs in the staging directory and the.zsynclands next to the AppImage in the output directory (listed in the checksums).- The APK signature check verifies the configured schemes (v1 with
--min-sdk-version 21, v4 with the.idsigfile), so the summary note lists all of them. - A DMG left in the staging directory by a failed run (e.g. rejected by notarization) made the next
create-dmgrefuse ("Output file already exists"); the whole DMG stage is reset now. - The deb
copyrightfile had a stray space after removing "©" fromapp.copyright.
1.0.0 #
- First release.
- Targets: apk (universal / per-ABI / both), aab, ipa (export method, ExportOptions.plist, unsigned), macos (zip, Developer ID signing, optional notarization), dmg (hdiutil / create-dmg, signing, notarization, stapling), pkg (pkgbuild + productbuild installer into /Applications, Developer ID Installer signing, notarization, stapling), windows (portable zip), exe (Inno Setup), msix, linux (tar.gz), deb, rpm, AppImage, web (zip).
- Commands: build, doctor, list, init, clean, version.
- Android signing injected via environment (no Gradle edits), keystore verification, signer check.
- macOS Developer ID signing / notarization configured only through fpack.yaml
macos.sign(+installer_identityfor pkg),FPACK_MACOS_*and flags; unsigned (Xcode signature kept) when not configured. The pubspecdmg:section of thedmgpackage is not read (not in build, doctor or init). fpack initwrites a commentedmacos.sign/macos.pkgsection with placeholders and lists the keychain's Developer ID identities as hints.--dry-run,--json, zh/en output, CI-friendly output, Ctrl-C handling, SHA256SUMS.- Dart launcher with verified bundled binaries, Go build fallback and checksum-verified downloads.
- Complete configuration reference: doc/configuration.md.
- Tested end to end on a real app (Android apk/aab, iOS ipa, macOS app/dmg) and in CI on Windows, macOS and Linux.