app-store-deployment
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseApp Store Deployment
应用商店部署
Overview
概述
Publish mobile applications to official app stores with proper code signing, versioning, testing, and submission procedures.
通过规范的代码签名、版本控制、测试及提交流程,将移动应用发布至官方应用商店。
When to Use
适用场景
- Publishing apps to App Store and Google Play
- Managing app versions and releases
- Configuring signing certificates and provisioning profiles
- Automating build and deployment processes
- Managing app updates and rollouts
- 将应用发布至App Store和Google Play
- 管理应用版本与发布
- 配置签名证书与描述文件
- 自动化构建与部署流程
- 管理应用更新与推送
Instructions
操作指南
1. iOS Deployment Setup
1. iOS部署配置
bash
undefinedbash
undefinedCreate development and distribution signing certificates
Create development and distribution signing certificates
Step 1: Generate Certificate Signing Request (CSR) in Keychain Access
Step 1: Generate Certificate Signing Request (CSR) in Keychain Access
Step 2: Create App ID in Apple Developer Portal
Step 2: Create App ID in Apple Developer Portal
Step 3: Create provisioning profiles (Development, Distribution)
Step 3: Create provisioning profiles (Development, Distribution)
Xcode configuration for signing
Xcode configuration for signing
Set Team ID, Bundle Identifier, and select provisioning profiles
Set Team ID, Bundle Identifier, and select provisioning profiles
Build Settings:
Build Settings:
- Code Sign Identity: "iPhone Distribution"
- Code Sign Identity: "iPhone Distribution"
- Provisioning Profile: Select appropriate profile
- Provisioning Profile: Select appropriate profile
- Code Sign Style: Automatic (recommended)
- Code Sign Style: Automatic (recommended)
Info.plist settings
Info.plist settings
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<false/>
</dict>
<key>NSUserTrackingUsageDescription</key>
<string>We use tracking for analytics</string>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<false/>
</dict>
<key>NSUserTrackingUsageDescription</key>
<string>We use tracking for analytics</string>
</dict>
</plist>
Build for App Store submission
Build for App Store submission
xcodebuild -workspace MyApp.xcworkspace
-scheme MyApp
-configuration Release
-archivePath ~/Desktop/MyApp.xcarchive
archive
-scheme MyApp
-configuration Release
-archivePath ~/Desktop/MyApp.xcarchive
archive
xcodebuild -workspace MyApp.xcworkspace
-scheme MyApp
-configuration Release
-archivePath ~/Desktop/MyApp.xcarchive
archive
-scheme MyApp
-configuration Release
-archivePath ~/Desktop/MyApp.xcarchive
archive
Export for distribution
Export for distribution
xcodebuild -exportArchive
-archivePath ~/Desktop/MyApp.xcarchive
-exportOptionsPlist ExportOptions.plist
-exportPath ~/Desktop/MyApp
-archivePath ~/Desktop/MyApp.xcarchive
-exportOptionsPlist ExportOptions.plist
-exportPath ~/Desktop/MyApp
xcodebuild -exportArchive
-archivePath ~/Desktop/MyApp.xcarchive
-exportOptionsPlist ExportOptions.plist
-exportPath ~/Desktop/MyApp
-archivePath ~/Desktop/MyApp.xcarchive
-exportOptionsPlist ExportOptions.plist
-exportPath ~/Desktop/MyApp
ExportOptions.plist
ExportOptions.plist
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>teamID</key>
<string>YOUR_TEAM_ID</string>
<key>signingStyle</key>
<string>automatic</string>
<key>method</key>
<string>app-store</string>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>teamID</key>
<string>YOUR_TEAM_ID</string>
<key>signingStyle</key>
<string>automatic</string>
<key>method</key>
<string>app-store</string>
</dict>
</plist>
Upload to App Store
Upload to App Store
xcrun altool --upload-app --file MyApp.ipa
--type ios
-u your-apple-id@example.com
-p your-app-specific-password
--type ios
-u your-apple-id@example.com
-p your-app-specific-password
undefinedxcrun altool --upload-app --file MyApp.ipa
--type ios
-u your-apple-id@example.com
-p your-app-specific-password
--type ios
-u your-apple-id@example.com
-p your-app-specific-password
undefined2. Android Deployment Setup
2. Android部署配置
gradle
// build.gradle configuration
android {
compileSdkVersion 33
defaultConfig {
applicationId "com.example.myapp"
minSdkVersion 21
targetSdkVersion 33
versionCode 1
versionName "1.0.0"
}
signingConfigs {
release {
storeFile file("keystore.jks")
storePassword System.getenv("KEYSTORE_PASSWORD")
keyAlias System.getenv("KEY_ALIAS")
keyPassword System.getenv("KEY_PASSWORD")
}
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation 'com.google.android.play:core:1.10.3'
}bash
undefinedgradle
// build.gradle configuration
android {
compileSdkVersion 33
defaultConfig {
applicationId "com.example.myapp"
minSdkVersion 21
targetSdkVersion 33
versionCode 1
versionName "1.0.0"
}
signingConfigs {
release {
storeFile file("keystore.jks")
storePassword System.getenv("KEYSTORE_PASSWORD")
keyAlias System.getenv("KEY_ALIAS")
keyPassword System.getenv("KEY_PASSWORD")
}
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation 'com.google.android.play:core:1.10.3'
}bash
undefinedCreate keystore for app signing
Create keystore for app signing
keytool -genkey -v
-keystore ~/my-release-key.jks
-keyalg RSA
-keysize 2048
-validity 10950
-alias my-key-alias
-keystore ~/my-release-key.jks
-keyalg RSA
-keysize 2048
-validity 10950
-alias my-key-alias
keytool -genkey -v
-keystore ~/my-release-key.jks
-keyalg RSA
-keysize 2048
-validity 10950
-alias my-key-alias
-keystore ~/my-release-key.jks
-keyalg RSA
-keysize 2048
-validity 10950
-alias my-key-alias
Build App Bundle
Build App Bundle
./gradlew bundleRelease
./gradlew bundleRelease
Build APK for testing
Build APK for testing
./gradlew assembleRelease
./gradlew assembleRelease
Verify APK signature
Verify APK signature
jarsigner -verify -verbose -certs app/build/outputs/apk/release/app-release.apk
undefinedjarsigner -verify -verbose -certs app/build/outputs/apk/release/app-release.apk
undefined3. Version Management
3. 版本管理
bash
undefinedbash
undefinedVersion tracking
Version tracking
package.json
package.json
{
"name": "myapp",
"version": "1.0.0",
"build": {
"ios": { "buildNumber": "1" },
"android": { "versionCode": 1 }
}
}
{
"name": "myapp",
"version": "1.0.0",
"build": {
"ios": { "buildNumber": "1" },
"android": { "versionCode": 1 }
}
}
Increment version script
Increment version script
#!/bin/bash
CURRENT=$(jq -r '.version' package.json)
IFS='.' read -ra VER <<< "$CURRENT"
MAJOR=${VER[0]}
MINOR=${VER[1]}
PATCH=${VER[2]}
PATCH=$((PATCH + 1))
NEW_VERSION="$MAJOR.$MINOR.$PATCH"
jq ".version = "$NEW_VERSION"" package.json > package.json.tmp
mv package.json.tmp package.json
echo "Version updated to $NEW_VERSION"
undefined#!/bin/bash
CURRENT=$(jq -r '.version' package.json)
IFS='.' read -ra VER <<< "$CURRENT"
MAJOR=${VER[0]}
MINOR=${VER[1]}
PATCH=${VER[2]}
PATCH=$((PATCH + 1))
NEW_VERSION="$MAJOR.$MINOR.$PATCH"
jq ".version = "$NEW_VERSION"" package.json > package.json.tmp
mv package.json.tmp package.json
echo "Version updated to $NEW_VERSION"
undefined4. Automated CI/CD with GitHub Actions
4. 基于GitHub Actions的自动化CI/CD
yaml
name: Deploy to App Stores
on:
push:
tags:
- 'v*'
jobs:
build-ios:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Build iOS App
run: |
cd ios
pod install
xcodebuild -workspace MyApp.xcworkspace \
-scheme MyApp \
-configuration Release \
-archivePath ~/Desktop/MyApp.xcarchive \
archive
- name: Upload to App Store
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
run: |
xcrun altool --upload-app \
--file MyApp.ipa \
--type ios \
-u $APPLE_ID \
-p $APPLE_PASSWORD
build-android:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Java
uses: actions/setup-java@v3
with:
java-version: '11'
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Build Android App
env:
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
run: |
cd android
./gradlew bundleRelease
- name: Upload to Google Play
uses: r0adkll/upload-google-play@v1
with:
serviceAccountJsonPlainText: ${{ secrets.PLAY_STORE_SERVICE_ACCOUNT }}
packageName: com.example.myapp
releaseFiles: android/app/build/outputs/bundle/release/app.aab
track: internal
status: completed
create-release:
runs-on: ubuntu-latest
needs: [build-ios, build-android]
steps:
- uses: actions/checkout@v3
- name: Create GitHub Release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
body: Release notes here
draft: false
prerelease: falseyaml
name: Deploy to App Stores
on:
push:
tags:
- 'v*'
jobs:
build-ios:
runs-on: macos-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Build iOS App
run: |
cd ios
pod install
xcodebuild -workspace MyApp.xcworkspace \
-scheme MyApp \
-configuration Release \
-archivePath ~/Desktop/MyApp.xcarchive \
archive
- name: Upload to App Store
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
run: |
xcrun altool --upload-app \
--file MyApp.ipa \
--type ios \
-u $APPLE_ID \
-p $APPLE_PASSWORD
build-android:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Java
uses: actions/setup-java@v3
with:
java-version: '11'
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Build Android App
env:
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
run: |
cd android
./gradlew bundleRelease
- name: Upload to Google Play
uses: r0adkll/upload-google-play@v1
with:
serviceAccountJsonPlainText: ${{ secrets.PLAY_STORE_SERVICE_ACCOUNT }}
packageName: com.example.myapp
releaseFiles: android/app/build/outputs/bundle/release/app.aab
track: internal
status: completed
create-release:
runs-on: ubuntu-latest
needs: [build-ios, build-android]
steps:
- uses: actions/checkout@v3
- name: Create GitHub Release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
body: Release notes here
draft: false
prerelease: false5. Pre-Deployment Checklist
5. 部署前检查清单
markdown
undefinedmarkdown
undefinediOS Checklist
iOS检查清单
- Increment version (CFBundleShortVersionString)
- Update build number (CFBundleVersion)
- Run all tests (>80% coverage)
- Test on minimum iOS version
- Review crash logs
- Check for deprecated APIs
- Verify all permissions documented
- Test offline functionality
- Verify app icon (1024x1024)
- Set privacy policy URL
- Archive and verify build
- Test on real devices
- 升级版本号(CFBundleShortVersionString)
- 更新构建号(CFBundleVersion)
- 运行所有测试(覆盖率>80%)
- 在最低iOS版本上测试
- 查看崩溃日志
- 检查已废弃的API
- 验证所有权限已文档化
- 测试离线功能
- 验证应用图标(1024x1024)
- 设置隐私政策URL
- 归档并验证构建包
- 在真实设备上测试
Android Checklist
Android检查清单
- Increment versionCode and versionName
- Run all tests (>80% coverage)
- Test on API 21+ devices
- Verify navigation
- Check battery optimization
- Enable app signing
- Build release AAB
- Verify ProGuard obfuscation
- Test landscape/portrait
- Upload screenshots
- Add release notes
- Test on multiple devices
undefined- 升级versionCode和versionName
- 运行所有测试(覆盖率>80%)
- 在API 21+设备上测试
- 验证导航功能
- 检查电池优化设置
- 启用应用签名
- 构建发布版AAB
- 验证ProGuard混淆配置
- 测试横屏/竖屏模式
- 上传截图
- 添加发布说明
- 在多台设备上测试
undefinedBest Practices
最佳实践
✅ DO
✅ 建议
- Use signed certificates and provisioning profiles
- Automate builds with CI/CD
- Test on real devices before submission
- Keep version numbers consistent
- Document deployment procedures
- Use environment-specific configurations
- Implement proper error tracking
- Monitor app performance post-launch
- Plan rollout strategy
- Keep backup of signing materials
- Test offline functionality
- Maintain release notes
- 使用签名证书与描述文件
- 通过CI/CD自动化构建
- 提交前在真实设备上测试
- 保持版本号一致
- 文档化部署流程
- 使用环境专属配置
- 实现完善的错误追踪
- 发布后监控应用性能
- 规划推送策略
- 备份签名材料
- 测试离线功能
- 维护发布说明
❌ DON'T
❌ 禁忌
- Commit signing materials to git
- Skip device testing
- Release untested code
- Ignore store policies
- Use hardcoded API keys
- Skip security reviews
- Deploy without monitoring
- Ignore crash reports
- Make large version jumps
- Use invalid certificates
- Deploy without backups
- Release during holidays
- 将签名材料提交至Git
- 跳过设备测试
- 发布未测试的代码
- 忽略应用商店政策
- 使用硬编码API密钥
- 跳过安全审查
- 无监控部署
- 忽略崩溃报告
- 大幅跳跃版本号
- 使用无效证书
- 无备份部署
- 节假日期间发布