Loading...
Loading...
Compare original and translation side by side
| Platform | Requirement | Certificate Type |
|---|---|---|
| Android | Required for Play Store | Java Keystore (JKS) |
| iOS | Required for distribution | Apple Developer Certificate |
| Linux | Optional (enhances trust) | GPG Key |
| macOS | Required for distribution | Developer ID / Apple Distribution |
| Windows | Required (SmartScreen) | OV or EV Certificate |
| 平台 | 要求 | 证书类型 |
|---|---|---|
| Android | 发布至应用商店必需 | Java Keystore (JKS) |
| iOS | 分发必需 | Apple Developer Certificate |
| Linux | 可选(提升信任度) | GPG Key |
| macOS | 分发必需 | Developer ID / Apple Distribution |
| Windows | 必需(通过SmartScreen验证) | OV或EV证书 |
keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias uploadkeytool -genkey -v -keystore $env:USERPROFILE\upload-keystore.jks -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 -alias uploadkeytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias uploadkeytool -genkey -v -keystore $env:USERPROFILE\upload-keystore.jks -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 -alias uploadsrc-tauri/gen/android/keystore.propertiespassword=<your-password>
keyAlias=upload
storeFile=/path/to/upload-keystore.jkskeystore.propertiessrc-tauri/gen/android/keystore.propertiespassword=<your-password>
keyAlias=upload
storeFile=/path/to/upload-keystore.jkskeystore.propertiessrc-tauri/gen/android/app/build.gradle.ktsimport java.io.FileInputStream
// Add before android { } block
val keystorePropertiesFile = rootProject.file("keystore.properties")
val keystoreProperties = java.util.Properties()
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}
android {
// ... existing config ...
signingConfigs {
create("release") {
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["password"] as String
storeFile = file(keystoreProperties["storeFile"] as String)
storePassword = keystoreProperties["password"] as String
}
}
buildTypes {
release {
signingConfig = signingConfigs.getByName("release")
// ... other release config ...
}
}
}src-tauri/gen/android/app/build.gradle.ktsimport java.io.FileInputStream
// 在android { }块之前添加
val keystorePropertiesFile = rootProject.file("keystore.properties")
val keystoreProperties = java.util.Properties()
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}
android {
// ... 现有配置 ...
signingConfigs {
create("release") {
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["password"] as String
storeFile = file(keystoreProperties["storeFile"] as String)
storePassword = keystoreProperties["password"] as String
}
}
buildTypes {
release {
signingConfig = signingConfigs.getByName("release")
// ... 其他发布配置 ...
}
}
}| Variable | Description |
|---|---|
| Key alias (e.g., |
| Keystore password |
| Base64-encoded keystore file |
- name: Setup Android signing
run: |
cd src-tauri/gen/android
echo "keyAlias=${{ secrets.ANDROID_KEY_ALIAS }}" > keystore.properties
echo "password=${{ secrets.ANDROID_KEY_PASSWORD }}" >> keystore.properties
base64 -d <<< "${{ secrets.ANDROID_KEY_BASE64 }}" > $RUNNER_TEMP/keystore.jks
echo "storeFile=$RUNNER_TEMP/keystore.jks" >> keystore.properties| 变量 | 描述 |
|---|---|
| 密钥别名(例如: |
| 密钥库密码 |
| Base64编码的密钥库文件 |
- name: Setup Android signing
run: |
cd src-tauri/gen/android
echo "keyAlias=${{ secrets.ANDROID_KEY_ALIAS }}" > keystore.properties
echo "password=${{ secrets.ANDROID_KEY_PASSWORD }}" >> keystore.properties
base64 -d <<< "${{ secrets.ANDROID_KEY_BASE64 }}" > $RUNNER_TEMP/keystore.jks
echo "storeFile=$RUNNER_TEMP/keystore.jks" >> keystore.properties| Variable | Description |
|---|---|
| Issuer ID from App Store Connect |
| Key ID from App Store Connect |
| Path to the |
| 变量 | 描述 |
|---|---|
| App Store Connect中的颁发者ID |
| App Store Connect中的密钥ID |
| |
| Variable | Description |
|---|---|
| Base64-encoded |
| Password used when exporting certificate |
| Base64-encoded provisioning profile |
| 变量 | 描述 |
|---|---|
| Base64编码的 |
| 导出证书时使用的密码 |
| Base64编码的配置文件 |
| Distribution | Certificate Type |
|---|---|
| Debugging | Apple Development or iOS App Development |
| App Store | Apple Distribution or iOS Distribution |
| Ad Hoc | Apple Distribution or iOS Distribution |
| 分发方式 | 证书类型 |
|---|---|
| 调试 | Apple Development或iOS App Development |
| App Store | Apple Distribution或iOS Distribution |
| 临时分发 | Apple Distribution或iOS Distribution |
.p12base64 -i certificate.p12.p12base64 -i certificate.p12base64 -i profile.mobileprovisionbase64 -i profile.mobileprovisiongpg2 --full-gen-keygpg2 --full-gen-key| Variable | Description |
|---|---|
| Set to |
| GPG Key ID (optional, uses default if not set) |
| Key password (required for CI/CD) |
| Set to |
| 变量 | 描述 |
|---|---|
| 设置为 |
| GPG密钥ID(可选,未设置则使用默认密钥) |
| 密钥密码(CI/CD环境必需) |
| 设置为 |
SIGN=1 APPIMAGETOOL_SIGN_PASSPHRASE="your-passphrase" npm run tauri buildSIGN=1 APPIMAGETOOL_SIGN_PASSPHRASE="your-passphrase" npm run tauri build./src-tauri/target/release/bundle/appimage/app_version_amd64.AppImage --appimage-signature./src-tauri/target/release/bundle/appimage/app_version_amd64.AppImage --appimage-signaturechmod +x validate-x86_64.AppImage
./validate-x86_64.AppImage your-app.AppImagechmod +x validate-x86_64.AppImage
./validate-x86_64.AppImage your-app.AppImage| Certificate | Use Case |
|---|---|
| Apple Distribution | App Store submissions |
| Developer ID Application | Distribution outside App Store |
| 证书 | 使用场景 |
|---|---|
| Apple Distribution | 提交至App Store |
| Developer ID Application | App Store外分发 |
.cer.cer{
"bundle": {
"macOS": {
"signingIdentity": "Developer ID Application: Your Name (TEAM_ID)"
}
}
}{
"bundle": {
"macOS": {
"signingIdentity": "Developer ID Application: Your Name (TEAM_ID)"
}
}
}| Variable | Description |
|---|---|
| Base64-encoded |
| Password for exported certificate |
| Certificate name in keychain |
| Variable | Description |
|---|---|
| Issuer ID |
| Key ID |
| Path to |
| Variable | Description |
|---|---|
| Apple ID email |
| App-specific password |
| Team identifier |
| 变量 | 描述 |
|---|---|
| Base64编码的 |
| 导出证书时的密码 |
| 钥匙串中的证书名称 |
| 变量 | 描述 |
|---|---|
| 颁发者ID |
| 密钥ID |
| |
| 变量 | 描述 |
|---|---|
| Apple ID邮箱 |
| 应用专用密码 |
| 团队标识符 |
undefinedundefinedundefinedundefined{
"bundle": {
"macOS": {
"signingIdentity": "-"
}
}
}{
"bundle": {
"macOS": {
"signingIdentity": "-"
}
}
}- name: Import certificate
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
run: |
echo $APPLE_CERTIFICATE | base64 --decode > certificate.p12
security create-keychain -p actions temp.keychain
security import certificate.p12 -k temp.keychain -P $APPLE_CERTIFICATE_PASSWORD -T /usr/bin/codesign
security list-keychains -s temp.keychain
security unlock-keychain -p actions temp.keychain
security set-key-partition-list -S apple-tool:,apple: -s -k actions temp.keychain- name: Import certificate
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
run: |
echo $APPLE_CERTIFICATE | base64 --decode > certificate.p12
security create-keychain -p actions temp.keychain
security import certificate.p12 -k temp.keychain -P $APPLE_CERTIFICATE_PASSWORD -T /usr/bin/codesign
security list-keychains -s temp.keychain
security unlock-keychain -p actions temp.keychain
security set-key-partition-list -S apple-tool:,apple: -s -k actions temp.keychain| Type | SmartScreen | Availability |
|---|---|---|
| OV (Organization Validated) | Builds reputation over time | Before June 1, 2023 |
| EV (Extended Validation) | Immediate trust | Required after June 1, 2023 |
| 类型 | SmartScreen信任度 | 可用性 |
|---|---|---|
| OV(组织验证) | 逐步建立信任度 | 2023年6月1日前可获取 |
| EV(扩展验证) | 即时信任 | 2023年6月1日后必需 |
{
"bundle": {
"windows": {
"certificateThumbprint": "A1B1A2B2A3B3A4B4A5B5A6B6A7B7A8B8A9B9A0B0",
"digestAlgorithm": "sha256",
"timestampUrl": "http://timestamp.sectigo.com"
}
}
}{
"bundle": {
"windows": {
"certificateThumbprint": "A1B1A2B2A3B3A4B4A5B5A6B6A7B7A8B8A9B9A0B0",
"digestAlgorithm": "sha256",
"timestampUrl": "http://timestamp.sectigo.com"
}
}
}http://timestamp.sectigo.comhttp://timestamp.digicert.comhttp://timestamp.globalsign.comhttp://timestamp.sectigo.comhttp://timestamp.digicert.comhttp://timestamp.globalsign.comopenssl pkcs12 -export -in cert.cer -inkey private-key.key -out certificate.pfxopenssl pkcs12 -export -in cert.cer -inkey private-key.key -out certificate.pfx| Variable | Description |
|---|---|
| Base64-encoded |
| PFX export password |
| 变量 | 描述 |
|---|---|
| Base64编码的 |
| PFX导出密码 |
- name: Import Windows certificate
env:
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}
run: |
echo "$WINDOWS_CERTIFICATE" | base64 --decode > certificate.pfx
Import-PfxCertificate -FilePath certificate.pfx -CertStoreLocation Cert:\CurrentUser\My -Password (ConvertTo-SecureString -String $env:WINDOWS_CERTIFICATE_PASSWORD -AsPlainText -Force)
shell: pwsh- name: Import Windows certificate
env:
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}
run: |
echo "$WINDOWS_CERTIFICATE" | base64 --decode > certificate.pfx
Import-PfxCertificate -FilePath certificate.pfx -CertStoreLocation Cert:\CurrentUser\My -Password (ConvertTo-SecureString -String $env:WINDOWS_CERTIFICATE_PASSWORD -AsPlainText -Force)
shell: pwsh| Variable | Description |
|---|---|
| Azure AD application client ID |
| Azure AD application secret |
| Azure AD tenant ID |
tauri.conf.json{
"bundle": {
"windows": {
"signCommand": "relic sign --key azurekeyvault --file %1"
}
}
}| 变量 | 描述 |
|---|---|
| Azure AD应用程序客户端ID |
| Azure AD应用程序密钥 |
| Azure AD租户ID |
tauri.conf.json{
"bundle": {
"windows": {
"signCommand": "relic sign --key azurekeyvault --file %1"
}
}
}{
"bundle": {
"windows": {
"signCommand": "trusted-signing-cli -e <endpoint> -a <account> -c <profile> %1"
}
}
}{
"bundle": {
"windows": {
"signCommand": "trusted-signing-cli -e <endpoint> -a <account> -c <profile> %1"
}
}
}{
"bundle": {
"windows": {
"signCommand": "your-signing-tool --sign %1"
}
}
}%1{
"bundle": {
"windows": {
"signCommand": "your-signing-tool --sign %1"
}
}
}%1ANDROID_KEY_ALIASANDROID_KEY_PASSWORDANDROID_KEY_BASE64ANDROID_KEY_ALIASANDROID_KEY_PASSWORDANDROID_KEY_BASE64IOS_CERTIFICATEIOS_CERTIFICATE_PASSWORDIOS_MOBILE_PROVISIONIOS_CERTIFICATEIOS_CERTIFICATE_PASSWORDIOS_MOBILE_PROVISIONAPPLE_API_ISSUERAPPLE_API_KEYAPPLE_API_KEY_PATHAPPLE_API_ISSUERAPPLE_API_KEYAPPLE_API_KEY_PATHAPPLE_CERTIFICATEAPPLE_CERTIFICATE_PASSWORDAPPLE_SIGNING_IDENTITYAPPLE_CERTIFICATEAPPLE_CERTIFICATE_PASSWORDAPPLE_SIGNING_IDENTITYAPPLE_IDAPPLE_PASSWORDAPPLE_TEAM_IDAPPLE_IDAPPLE_PASSWORDAPPLE_TEAM_IDSIGNSIGN_KEYAPPIMAGETOOL_SIGN_PASSPHRASEAPPIMAGETOOL_FORCE_SIGNSIGNSIGN_KEYAPPIMAGETOOL_SIGN_PASSPHRASEAPPIMAGETOOL_FORCE_SIGNWINDOWS_CERTIFICATEWINDOWS_CERTIFICATE_PASSWORDWINDOWS_CERTIFICATEWINDOWS_CERTIFICATE_PASSWORDAZURE_CLIENT_IDAZURE_CLIENT_SECRETAZURE_TENANT_IDAZURE_CLIENT_IDAZURE_CLIENT_SECRETAZURE_TENANT_ID