Signing needs passwords and keys. fpack is designed so that they never have to be written to fpack.yaml, the command line or the logs.
Which setting wins#
For every setting, the first source that provides a value wins:
- command-line flag (
--flavor prod) FPACK_*environment variable (FPACK_FLAVOR=prod)fpack.yaml(build.flavor: prod)- default
Each key in the reference lists its variable and flag; the environment variables page lists them all.
${VAR} in fpack.yaml#
Any value in fpack.yaml can read an environment variable when the file is loaded:
android:
signing:
store_file: ~/keys/upload.jks
store_password: ${KEYSTORE_PASSWORD} # an error if it is not set
key_alias: ${KEY_ALIAS:-upload} # a default when it is not set
output:
dir: ${DIST_DIR:-dist}
Use this for anything secret or machine-specific. Commit the file, keep the values in your shell, a password manager or CI secrets.
Note
${VAR} is expanded when the configuration is loaded. In hooks
write $VAR (Windows %VAR%) for variables that only exist while the hook runs.
Dedicated variables#
Signing and notarization settings have their own variables, so a CI job needs no fpack.yaml
edits:
| Area | Variables |
|---|---|
| Android |
FPACK_ANDROID_KEYSTORE
,
FPACK_ANDROID_KEYSTORE_BASE64
,
FPACK_ANDROID_KEYSTORE_PASSWORD
,
FPACK_ANDROID_KEY_ALIAS
,
FPACK_ANDROID_KEY_PASSWORD
|
| iOS |
FPACK_IOS_EXPORT_METHOD
,
FPACK_IOS_EXPORT_OPTIONS_PLIST
,
FPACK_IOS_CODESIGN
|
| macOS signing |
FPACK_MACOS_SIGN
,
FPACK_MACOS_SIGN_IDENTITY
,
FPACK_MACOS_INSTALLER_IDENTITY
,
FPACK_MACOS_PROVISIONING_PROFILE
,
FPACK_MACOS_PROFILE_CHECK
,
FPACK_MACOS_SMOKE_TEST
|
| macOS notarization |
FPACK_MACOS_NOTARIZE
,
FPACK_MACOS_NOTARY_PROFILE
,
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
|
| Windows |
FPACK_WINDOWS_CERTIFICATE
,
FPACK_WINDOWS_CERTIFICATE_PASSWORD
,
FPACK_WINDOWS_CERT_THUMBPRINT
,
FPACK_WINDOWS_CERT_SUBJECT
,
FPACK_WINDOWS_SIGN_DLIB
,
FPACK_WINDOWS_SIGN_DLIB_METADATA
|
What fpack protects#
-
Passwords are redacted in logs, in
--dry-runoutput (shown as***), inNOTARIZATION.mdand in--json. - Passwords are never put on a command line; they travel in environment variables or temporary files.
-
Key material fpack writes (for example a keystore decoded from
FPACK_ANDROID_KEYSTORE_BASE64) goes tobuild/fpack/secrets/with mode 0600 and is deleted after the build. - It checks credentials before the long build: a wrong keystore password or alias, a missing signing identity.
In CI#
- Store secrets in your CI's secret store.
- Map them to the
FPACK_*variables in the job'senv. -
For files (keystore,
.p12, API key.p8), store them as base64 and decode on the runner.
- run: fpack build apk aab
env:
FPACK_ANDROID_KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }}
FPACK_ANDROID_KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
FPACK_ANDROID_KEY_ALIAS: upload
Complete workflows per platform: CI recipes. Platform specifics: Android, macOS, Windows.
Danger
Never commit keystores, .p12 / .p8 files, certificates or passwords. If one leaks, treat it as compromised: change the passwords, revoke the API key, or create a new certificate.
Next#
签名需要密码和密钥。fpack 的设计目标是:它们永远不必写进 fpack.yaml、命令行或日志。
哪个设置优先#
对每个设置,第一个提供了值的来源生效:
- 命令行参数(
--flavor prod) FPACK_*环境变量(FPACK_FLAVOR=prod)fpack.yaml(build.flavor: prod)- 默认值
参考里每个键都列出了它的变量和参数;环境变量页列出全部变量。
fpack.yaml 里的 ${VAR}#
fpack.yaml 里的任何值都可以在加载文件时读取环境变量:
android:
signing:
store_file: ~/keys/upload.jks
store_password: ${KEYSTORE_PASSWORD} # 未设置则报错
key_alias: ${KEY_ALIAS:-upload} # 未设置时使用默认值
output:
dir: ${DIST_DIR:-dist}
任何机密或与机器相关的值都用它。文件可以提交,值放在你的 shell、密码管理器或 CI 密钥里。
说明
${VAR} 是在加载配置时展开的。在钩子里,仅在钩子运行期间才存在的变量要写成 $VAR(Windows 是
%VAR%)。
专用变量#
签名和公证的设置有各自的变量,所以 CI 任务无需修改 fpack.yaml:
| 范围 | 变量 |
|---|---|
| Android |
FPACK_ANDROID_KEYSTORE
、
FPACK_ANDROID_KEYSTORE_BASE64
、
FPACK_ANDROID_KEYSTORE_PASSWORD
、
FPACK_ANDROID_KEY_ALIAS
、
FPACK_ANDROID_KEY_PASSWORD
|
| iOS |
FPACK_IOS_EXPORT_METHOD
、
FPACK_IOS_EXPORT_OPTIONS_PLIST
、
FPACK_IOS_CODESIGN
|
| macOS 签名 |
FPACK_MACOS_SIGN
、
FPACK_MACOS_SIGN_IDENTITY
、
FPACK_MACOS_INSTALLER_IDENTITY
、
FPACK_MACOS_PROVISIONING_PROFILE
、
FPACK_MACOS_PROFILE_CHECK
、
FPACK_MACOS_SMOKE_TEST
|
| macOS 公证 |
FPACK_MACOS_NOTARIZE
、
FPACK_MACOS_NOTARY_PROFILE
、
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
|
| Windows |
FPACK_WINDOWS_CERTIFICATE
、
FPACK_WINDOWS_CERTIFICATE_PASSWORD
、
FPACK_WINDOWS_CERT_THUMBPRINT
、
FPACK_WINDOWS_CERT_SUBJECT
、
FPACK_WINDOWS_SIGN_DLIB
、
FPACK_WINDOWS_SIGN_DLIB_METADATA
|
fpack 如何保护它们#
-
密码会在日志、
--dry-run输出(显示为***)、NOTARIZATION.md和--json里被隐藏。 - 密码绝不会出现在命令行上;它们通过环境变量或临时文件传递。
-
fpack 写出的密钥文件(例如从
FPACK_ANDROID_KEYSTORE_BASE64解码出的密钥库)放在build/fpack/secrets/,权限 0600,构建后删除。 - 它在漫长的构建之前就检查凭证:错误的密钥库密码或别名、找不到的签名证书。
在 CI 中#
- 把密钥存进 CI 的密钥库。
- 在任务的
env里把它们映射到FPACK_*变量。 - 对文件(密钥库、
.p12、API 密钥.p8),以 base64 存储,在运行机器上解码。
- run: fpack build apk aab
env:
FPACK_ANDROID_KEYSTORE_BASE64: ${{ secrets.KEYSTORE_BASE64 }}
FPACK_ANDROID_KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
FPACK_ANDROID_KEY_ALIAS: upload
各平台的完整工作流:CI 示例。各平台细节:Android、macOS、Windows。
危险
绝不要提交密钥库、.p12 / .p8 文件、证书或密码。一旦泄露,就视为已被攻破:修改密码、吊销 API 密钥,或创建新证书。
下一步#
钩子。