@daemux/store-automator 0.10.29 → 0.10.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/package.json +1 -1
- package/plugins/store-automator/.claude-plugin/plugin.json +1 -1
- package/plugins/store-automator/agents/appstore-meta-creator.md +27 -1
- package/templates/CLAUDE.md.template +20 -0
- package/templates/fastlane/ios/Fastfile.template +17 -15
- package/templates/scripts/ci/ios/build.sh +19 -0
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
},
|
|
6
6
|
"metadata": {
|
|
7
7
|
"description": "App Store & Google Play automation for Flutter apps",
|
|
8
|
-
"version": "0.10.
|
|
8
|
+
"version": "0.10.30"
|
|
9
9
|
},
|
|
10
10
|
"plugins": [
|
|
11
11
|
{
|
|
12
12
|
"name": "store-automator",
|
|
13
13
|
"source": "./plugins/store-automator",
|
|
14
14
|
"description": "3 agents for app store publishing: reviewer, meta-creator, media-designer",
|
|
15
|
-
"version": "0.10.
|
|
15
|
+
"version": "0.10.30",
|
|
16
16
|
"keywords": [
|
|
17
17
|
"flutter",
|
|
18
18
|
"app-store",
|
package/package.json
CHANGED
|
@@ -15,7 +15,8 @@ You are a senior ASO (App Store Optimization) specialist and localization expert
|
|
|
15
15
|
5. SAVE all files to fastlane/metadata/ in the correct directory structure
|
|
16
16
|
6. GENERATE fastlane/app_rating_config.json based on app content analysis
|
|
17
17
|
7. GENERATE fastlane/data_safety.csv based on app data collection analysis
|
|
18
|
-
8.
|
|
18
|
+
8. GENERATE fastlane/metadata/review_information/ contact files for App Store review team
|
|
19
|
+
9. Verify character limits are respected in every language
|
|
19
20
|
|
|
20
21
|
## Files You Create
|
|
21
22
|
|
|
@@ -81,6 +82,20 @@ Analyze the app's content (screens, features, user interactions) and generate a
|
|
|
81
82
|
|
|
82
83
|
Apple string values: "NONE", "INFREQUENT_MILD", "FREQUENT_INTENSE". Google string values: "NO", "MILD", "MODERATE", "STRONG".
|
|
83
84
|
|
|
85
|
+
### Review Information (fastlane/metadata/review_information/)
|
|
86
|
+
|
|
87
|
+
Generate review contact information for App Store Connect review team.
|
|
88
|
+
|
|
89
|
+
| File | Content | Rules |
|
|
90
|
+
|------|---------|-------|
|
|
91
|
+
| first_name.txt | Random US-like first name | e.g., "James", "Sarah", "Michael" -- realistic, not celebrity/fictional |
|
|
92
|
+
| last_name.txt | Random US-like last name | e.g., "Smith", "Johnson", "Williams" -- realistic, not celebrity/fictional |
|
|
93
|
+
| phone_number.txt | Random US phone number | Format: +1XXXXXXXXXX (valid area code like 212, 415, 312) |
|
|
94
|
+
| email_address.txt | support@{domain} | Use domain from web.support_email or derive from web.domain in ci.config.yaml |
|
|
95
|
+
| demo_user.txt | Empty | Sign-in not required |
|
|
96
|
+
| demo_password.txt | Empty | Sign-in not required |
|
|
97
|
+
| notes.txt | Review notes | "No sign-in required. The app is free to use." |
|
|
98
|
+
|
|
84
99
|
### Data Safety Config (fastlane/data_safety.csv)
|
|
85
100
|
|
|
86
101
|
Analyze the app's data collection practices (authentication, messaging, payments, analytics, crash reporting, etc.) and generate a CSV declaring what data is collected, shared, its purpose, and security practices.
|
|
@@ -226,6 +241,14 @@ fastlane/
|
|
|
226
241
|
app_rating_config.json
|
|
227
242
|
data_safety.csv
|
|
228
243
|
metadata/
|
|
244
|
+
review_information/
|
|
245
|
+
first_name.txt
|
|
246
|
+
last_name.txt
|
|
247
|
+
phone_number.txt
|
|
248
|
+
email_address.txt
|
|
249
|
+
demo_user.txt
|
|
250
|
+
demo_password.txt
|
|
251
|
+
notes.txt
|
|
229
252
|
ios/
|
|
230
253
|
copyright.txt
|
|
231
254
|
en-US/
|
|
@@ -265,6 +288,9 @@ fastlane/
|
|
|
265
288
|
- data_safety.csv has matching DATA_SHARED entries for every DATA_COLLECTED category
|
|
266
289
|
- data_safety.csv has DATA_USAGE purpose entries for every collected data type
|
|
267
290
|
- data_safety.csv includes SECURITY_PRACTICES entries for encryption and deletion
|
|
291
|
+
- review_information/ directory has all 7 files (first_name, last_name, phone_number, email_address, demo_user, demo_password, notes)
|
|
292
|
+
- review_information/phone_number.txt uses valid US format (+1 followed by 10 digits with valid area code)
|
|
293
|
+
- review_information/email_address.txt uses the actual domain from ci.config.yaml
|
|
268
294
|
|
|
269
295
|
## Output Footer
|
|
270
296
|
|
|
@@ -58,6 +58,26 @@ IAP and subscription configuration. Durations: ONE_WEEK to ONE_YEAR. Intro offer
|
|
|
58
58
|
### fastlane/screenshots/
|
|
59
59
|
Store screenshots by platform and device size. Generated by app-designer via Stitch MCP.
|
|
60
60
|
|
|
61
|
+
### App Icon Setup
|
|
62
|
+
The app icon must be set before the first release. Flutter creates projects with a default icon that MUST be replaced.
|
|
63
|
+
|
|
64
|
+
**Using flutter_launcher_icons (recommended):**
|
|
65
|
+
1. Add to pubspec.yaml dev_dependencies: `flutter_launcher_icons: ^0.14.3`
|
|
66
|
+
2. Add configuration:
|
|
67
|
+
```yaml
|
|
68
|
+
flutter_launcher_icons:
|
|
69
|
+
android: true
|
|
70
|
+
ios: true
|
|
71
|
+
image_path: "assets/icon/app_icon.png"
|
|
72
|
+
min_sdk_android: 21
|
|
73
|
+
```
|
|
74
|
+
3. Place your 1024x1024 PNG icon at `assets/icon/app_icon.png`
|
|
75
|
+
4. Run: `dart run flutter_launcher_icons`
|
|
76
|
+
|
|
77
|
+
**Manual replacement:**
|
|
78
|
+
- iOS: Replace all PNGs in `ios/Runner/Assets.xcassets/AppIcon.appiconset/`
|
|
79
|
+
- Android: Replace all `ic_launcher.png` in `android/app/src/main/res/mipmap-*/`
|
|
80
|
+
|
|
61
81
|
## Flutter Project Structure
|
|
62
82
|
|
|
63
83
|
### Folder Structure
|
|
@@ -27,22 +27,18 @@ rescue StandardError
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def asc_api_key
|
|
30
|
+
params = {
|
|
31
|
+
key_id: ENV["APP_STORE_CONNECT_KEY_IDENTIFIER"],
|
|
32
|
+
issuer_id: ENV["APP_STORE_CONNECT_ISSUER_ID"],
|
|
33
|
+
is_key_content_base64: false
|
|
34
|
+
}
|
|
30
35
|
key_path = ENV["FASTLANE_API_KEY_PATH"]
|
|
31
36
|
if key_path && File.exist?(key_path)
|
|
32
|
-
|
|
33
|
-
key_id: ENV["APP_STORE_CONNECT_KEY_IDENTIFIER"],
|
|
34
|
-
issuer_id: ENV["APP_STORE_CONNECT_ISSUER_ID"],
|
|
35
|
-
key_filepath: key_path,
|
|
36
|
-
is_key_content_base64: false
|
|
37
|
-
)
|
|
37
|
+
params[:key_filepath] = key_path
|
|
38
38
|
else
|
|
39
|
-
|
|
40
|
-
key_id: ENV["APP_STORE_CONNECT_KEY_IDENTIFIER"],
|
|
41
|
-
issuer_id: ENV["APP_STORE_CONNECT_ISSUER_ID"],
|
|
42
|
-
key_content: ENV["APP_STORE_CONNECT_PRIVATE_KEY"],
|
|
43
|
-
is_key_content_base64: false
|
|
44
|
-
)
|
|
39
|
+
params[:key_content] = ENV["APP_STORE_CONNECT_PRIVATE_KEY"]
|
|
45
40
|
end
|
|
41
|
+
app_store_connect_api_key(params)
|
|
46
42
|
end
|
|
47
43
|
|
|
48
44
|
# Shared deliver options reused across iOS lanes.
|
|
@@ -60,7 +56,9 @@ def metadata_deliver_options
|
|
|
60
56
|
screenshots_path: "#{ROOT_DIR}/fastlane/screenshots/ios",
|
|
61
57
|
sync_screenshots: true,
|
|
62
58
|
primary_category: ENV.fetch("PRIMARY_CATEGORY", "UTILITIES"),
|
|
63
|
-
secondary_category: ENV.fetch("SECONDARY_CATEGORY", "PRODUCTIVITY")
|
|
59
|
+
secondary_category: ENV.fetch("SECONDARY_CATEGORY", "PRODUCTIVITY"),
|
|
60
|
+
price_tier: ENV.fetch("PRICE_TIER", "0").to_i,
|
|
61
|
+
app_rating_config_path: "#{ROOT_DIR}/fastlane/app_rating_config.json"
|
|
64
62
|
)
|
|
65
63
|
end
|
|
66
64
|
|
|
@@ -76,11 +74,15 @@ platform :ios do
|
|
|
76
74
|
deliver(
|
|
77
75
|
metadata_deliver_options.merge(submission_options).merge(
|
|
78
76
|
ipa: Dir.glob("#{APP_DIR}/build/ios/ipa/*.ipa").first,
|
|
79
|
-
app_rating_config_path: "#{ROOT_DIR}/fastlane/app_rating_config.json",
|
|
80
77
|
skip_metadata: !metadata_changed?("fastlane/metadata/ios/"),
|
|
81
78
|
skip_screenshots: !metadata_changed?("fastlane/screenshots/ios/"),
|
|
82
79
|
run_precheck_before_submit: true,
|
|
83
|
-
precheck_include_in_app_purchases: false
|
|
80
|
+
precheck_include_in_app_purchases: false,
|
|
81
|
+
submission_information: {
|
|
82
|
+
export_compliance_uses_encryption: false,
|
|
83
|
+
content_rights_contains_third_party_content: false,
|
|
84
|
+
content_rights_has_rights: true
|
|
85
|
+
}
|
|
84
86
|
)
|
|
85
87
|
)
|
|
86
88
|
end
|
|
@@ -53,6 +53,25 @@ if [ -f "$PBXPROJ" ]; then
|
|
|
53
53
|
echo "Xcode project patched for CI signing"
|
|
54
54
|
fi
|
|
55
55
|
|
|
56
|
+
# --- Set encryption compliance (avoids "Missing Compliance" in App Store Connect) ---
|
|
57
|
+
INFO_PLIST="$APP_ROOT/ios/Runner/Info.plist"
|
|
58
|
+
if [ -f "$INFO_PLIST" ]; then
|
|
59
|
+
/usr/libexec/PlistBuddy -c "Delete :ITSAppUsesNonExemptEncryption" "$INFO_PLIST" 2>/dev/null || true
|
|
60
|
+
/usr/libexec/PlistBuddy -c "Add :ITSAppUsesNonExemptEncryption bool false" "$INFO_PLIST"
|
|
61
|
+
echo "Set ITSAppUsesNonExemptEncryption=false in Info.plist"
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
# --- Warn if iOS icon is still Flutter default ---
|
|
65
|
+
ICON_1024="$APP_ROOT/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png"
|
|
66
|
+
if [ -f "$ICON_1024" ]; then
|
|
67
|
+
ICON_SIZE=$(wc -c < "$ICON_1024" | tr -d ' ')
|
|
68
|
+
if [ "$ICON_SIZE" -lt 15000 ]; then
|
|
69
|
+
echo "⚠️ WARNING: iOS app icon appears to be the Flutter default (size: ${ICON_SIZE} bytes)."
|
|
70
|
+
echo "⚠️ Replace icons in ios/Runner/Assets.xcassets/AppIcon.appiconset/ with your actual app icon."
|
|
71
|
+
echo "⚠️ Use flutter_launcher_icons package or manually replace all icon sizes."
|
|
72
|
+
fi
|
|
73
|
+
fi
|
|
74
|
+
|
|
56
75
|
# --- Build IPA ---
|
|
57
76
|
echo "Building IPA..."
|
|
58
77
|
echo " APP_ROOT: $APP_ROOT"
|