ios-app-review-plugin 1.0.0
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/settings.local.json +42 -0
- package/.github/actions/ios-review/action.yml +106 -0
- package/.github/workflows/ci.yml +103 -0
- package/.github/workflows/publish.yml +57 -0
- package/CHANGELOG.md +66 -0
- package/CONTRIBUTING.md +175 -0
- package/LICENSE +21 -0
- package/README.md +205 -0
- package/bitrise/step.sh +128 -0
- package/bitrise/step.yml +101 -0
- package/dist/analyzer.d.ts.map +1 -0
- package/dist/analyzers/asc-iap.d.ts.map +1 -0
- package/dist/analyzers/asc-metadata.d.ts.map +1 -0
- package/dist/analyzers/asc-screenshots.d.ts.map +1 -0
- package/dist/analyzers/asc-version.d.ts.map +1 -0
- package/dist/analyzers/code-scanner.d.ts.map +1 -0
- package/dist/analyzers/deprecated-api.d.ts.map +1 -0
- package/dist/analyzers/entitlements.d.ts.map +1 -0
- package/dist/analyzers/index.d.ts.map +1 -0
- package/dist/analyzers/info-plist.d.ts.map +1 -0
- package/dist/analyzers/privacy.d.ts.map +1 -0
- package/dist/analyzers/private-api.d.ts.map +1 -0
- package/dist/analyzers/security.d.ts.map +1 -0
- package/dist/analyzers/ui-ux.d.ts.map +1 -0
- package/dist/asc/auth.d.ts.map +1 -0
- package/dist/asc/client.d.ts.map +1 -0
- package/dist/asc/endpoints/apps.d.ts.map +1 -0
- package/dist/asc/endpoints/iap.d.ts.map +1 -0
- package/dist/asc/endpoints/screenshots.d.ts.map +1 -0
- package/dist/asc/endpoints/versions.d.ts.map +1 -0
- package/dist/asc/errors.d.ts.map +1 -0
- package/dist/asc/index.d.ts.map +1 -0
- package/dist/asc/types.d.ts.map +1 -0
- package/dist/badge/generator.d.ts.map +1 -0
- package/dist/badge/index.d.ts.map +1 -0
- package/dist/badge/types.d.ts.map +1 -0
- package/dist/cache/file-cache.d.ts.map +1 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/types.d.ts.map +1 -0
- package/dist/cli/commands/help.d.ts.map +1 -0
- package/dist/cli/commands/scan.d.ts.map +1 -0
- package/dist/cli/commands/version.d.ts.map +1 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/git/diff.d.ts.map +1 -0
- package/dist/git/index.d.ts.map +1 -0
- package/dist/git/types.d.ts.map +1 -0
- package/dist/guidelines/database.d.ts.map +1 -0
- package/dist/guidelines/index.d.ts.map +1 -0
- package/dist/guidelines/matcher.d.ts.map +1 -0
- package/dist/guidelines/types.d.ts.map +1 -0
- package/dist/history/comparator.d.ts.map +1 -0
- package/dist/history/index.d.ts.map +1 -0
- package/dist/history/store.d.ts.map +1 -0
- package/dist/history/types.d.ts.map +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +994 -0
- package/dist/parsers/index.d.ts.map +1 -0
- package/dist/parsers/plist.d.ts.map +1 -0
- package/dist/parsers/xcodeproj.d.ts.map +1 -0
- package/dist/progress/index.d.ts.map +1 -0
- package/dist/progress/reporter.d.ts.map +1 -0
- package/dist/progress/types.d.ts.map +1 -0
- package/dist/reports/html.d.ts.map +1 -0
- package/dist/reports/index.d.ts.map +1 -0
- package/dist/reports/json.d.ts.map +1 -0
- package/dist/reports/markdown.d.ts.map +1 -0
- package/dist/reports/types.d.ts.map +1 -0
- package/dist/rules/engine.d.ts.map +1 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/loader.d.ts.map +1 -0
- package/dist/rules/types.d.ts.map +1 -0
- package/dist/types/index.d.ts.map +1 -0
- package/docs/ANALYZERS.md +237 -0
- package/docs/API.md +308 -0
- package/docs/BADGES.md +130 -0
- package/docs/CI_CD.md +283 -0
- package/docs/CLI.md +140 -0
- package/docs/REPORTS.md +212 -0
- package/docs/ROADMAP.md +267 -0
- package/docs/RULES.md +182 -0
- package/docs/SECURITY.md +89 -0
- package/docs/TROUBLESHOOTING.md +227 -0
- package/docs/tutorials/ASC_SETUP.md +188 -0
- package/docs/tutorials/CI_INTEGRATION.md +292 -0
- package/docs/tutorials/CUSTOM_RULES.md +291 -0
- package/docs/tutorials/GETTING_STARTED.md +226 -0
- package/docs/video-scripts/01-introduction.md +106 -0
- package/docs/video-scripts/02-cli-usage.md +120 -0
- package/docs/video-scripts/03-ci-integration.md +198 -0
- package/eslint.config.js +33 -0
- package/examples/.ios-review-rules.json +82 -0
- package/examples/bitrise-workflow.yml +129 -0
- package/examples/fastlane-lane.rb +71 -0
- package/examples/github-action.yml +147 -0
- package/fastlane/Fastfile.example +114 -0
- package/fastlane/README.md +99 -0
- package/jest.config.js +36 -0
- package/package.json +65 -0
- package/scripts/benchmark.ts +112 -0
- package/scripts/debug-parser.ts +37 -0
- package/scripts/debug-pbxproj.ts +36 -0
- package/scripts/debug-specific.ts +47 -0
- package/scripts/test-analyze.ts +67 -0
- package/scripts/xcode-cloud-review.sh +167 -0
- package/src/analyzer.ts +227 -0
- package/src/analyzers/asc-iap.ts +300 -0
- package/src/analyzers/asc-metadata.ts +326 -0
- package/src/analyzers/asc-screenshots.ts +310 -0
- package/src/analyzers/asc-version.ts +368 -0
- package/src/analyzers/code-scanner.ts +408 -0
- package/src/analyzers/deprecated-api.ts +390 -0
- package/src/analyzers/entitlements.ts +345 -0
- package/src/analyzers/index.ts +12 -0
- package/src/analyzers/info-plist.ts +409 -0
- package/src/analyzers/privacy.ts +376 -0
- package/src/analyzers/private-api.ts +377 -0
- package/src/analyzers/security.ts +327 -0
- package/src/analyzers/ui-ux.ts +509 -0
- package/src/asc/auth.ts +204 -0
- package/src/asc/client.ts +258 -0
- package/src/asc/endpoints/apps.ts +115 -0
- package/src/asc/endpoints/iap.ts +171 -0
- package/src/asc/endpoints/screenshots.ts +164 -0
- package/src/asc/endpoints/versions.ts +174 -0
- package/src/asc/errors.ts +109 -0
- package/src/asc/index.ts +108 -0
- package/src/asc/types.ts +369 -0
- package/src/badge/generator.ts +48 -0
- package/src/badge/index.ts +2 -0
- package/src/badge/types.ts +5 -0
- package/src/cache/file-cache.ts +75 -0
- package/src/cache/index.ts +2 -0
- package/src/cache/types.ts +10 -0
- package/src/cli/commands/help.ts +41 -0
- package/src/cli/commands/scan.ts +44 -0
- package/src/cli/commands/version.ts +12 -0
- package/src/cli/index.ts +92 -0
- package/src/cli/types.ts +17 -0
- package/src/git/diff.ts +21 -0
- package/src/git/index.ts +2 -0
- package/src/git/types.ts +5 -0
- package/src/guidelines/database.ts +344 -0
- package/src/guidelines/index.ts +4 -0
- package/src/guidelines/matcher.ts +84 -0
- package/src/guidelines/types.ts +28 -0
- package/src/history/comparator.ts +114 -0
- package/src/history/index.ts +3 -0
- package/src/history/store.ts +135 -0
- package/src/history/types.ts +40 -0
- package/src/index.ts +1113 -0
- package/src/parsers/index.ts +3 -0
- package/src/parsers/plist.ts +253 -0
- package/src/parsers/xcodeproj.ts +265 -0
- package/src/progress/index.ts +2 -0
- package/src/progress/reporter.ts +65 -0
- package/src/progress/types.ts +9 -0
- package/src/reports/html.ts +322 -0
- package/src/reports/index.ts +20 -0
- package/src/reports/json.ts +92 -0
- package/src/reports/markdown.ts +187 -0
- package/src/reports/types.ts +26 -0
- package/src/rules/engine.ts +121 -0
- package/src/rules/index.ts +3 -0
- package/src/rules/loader.ts +83 -0
- package/src/rules/types.ts +25 -0
- package/src/types/index.ts +247 -0
- package/tests/analyzer.test.ts +142 -0
- package/tests/analyzers/asc-iap.test.ts +228 -0
- package/tests/analyzers/asc-metadata.test.ts +210 -0
- package/tests/analyzers/asc-screenshots.test.ts +135 -0
- package/tests/analyzers/asc-version.test.ts +259 -0
- package/tests/analyzers/code-scanner.test.ts +745 -0
- package/tests/analyzers/deprecated-api.test.ts +286 -0
- package/tests/analyzers/entitlements.test.ts +411 -0
- package/tests/analyzers/info-plist.test.ts +148 -0
- package/tests/analyzers/privacy.test.ts +623 -0
- package/tests/analyzers/private-api.test.ts +255 -0
- package/tests/analyzers/security.test.ts +300 -0
- package/tests/analyzers/ui-ux.test.ts +357 -0
- package/tests/asc/auth.test.ts +189 -0
- package/tests/asc/client.test.ts +207 -0
- package/tests/asc/endpoints.test.ts +1359 -0
- package/tests/badge/generator.test.ts +73 -0
- package/tests/cache/file-cache.test.ts +124 -0
- package/tests/cli/cli-index.test.ts +510 -0
- package/tests/cli/commands.test.ts +67 -0
- package/tests/cli/scan.test.ts +152 -0
- package/tests/git/diff.test.ts +69 -0
- package/tests/guidelines/matcher.test.ts +209 -0
- package/tests/history/comparator.test.ts +272 -0
- package/tests/history/store.test.ts +200 -0
- package/tests/integration/cli.test.ts +95 -0
- package/tests/integration/e2e.test.ts +130 -0
- package/tests/parsers/plist.test.ts +240 -0
- package/tests/parsers/xcodeproj.test.ts +289 -0
- package/tests/progress/reporter.test.ts +117 -0
- package/tests/reports/html.test.ts +176 -0
- package/tests/reports/json.test.ts +235 -0
- package/tests/reports/markdown.test.ts +196 -0
- package/tests/rules/engine.test.ts +229 -0
- package/tests/rules/loader.test.ts +187 -0
- package/tests/setup.ts +15 -0
- package/tsconfig.json +27 -0
- package/tsconfig.test.json +9 -0
package/docs/SECURITY.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Supported Versions
|
|
4
|
+
|
|
5
|
+
| Version | Supported |
|
|
6
|
+
|---------|-----------|
|
|
7
|
+
| 1.0.x | Yes |
|
|
8
|
+
| 0.4.x | Security fixes only |
|
|
9
|
+
| < 0.4 | No |
|
|
10
|
+
|
|
11
|
+
## Reporting a Vulnerability
|
|
12
|
+
|
|
13
|
+
If you discover a security vulnerability in the iOS App Review Plugin, please report it responsibly.
|
|
14
|
+
|
|
15
|
+
**Do not open a public GitHub issue for security vulnerabilities.**
|
|
16
|
+
|
|
17
|
+
Instead, send a private report:
|
|
18
|
+
|
|
19
|
+
1. Email: Send details to the repository maintainer via the email listed in the npm package or GitHub profile.
|
|
20
|
+
2. GitHub Security Advisories: Use the [private vulnerability reporting feature](https://github.com/ahmetsina/ios-app-review-plugin/security/advisories/new) on the repository.
|
|
21
|
+
|
|
22
|
+
### What to Include
|
|
23
|
+
|
|
24
|
+
- Description of the vulnerability
|
|
25
|
+
- Steps to reproduce
|
|
26
|
+
- Affected versions
|
|
27
|
+
- Potential impact
|
|
28
|
+
- Suggested fix (if any)
|
|
29
|
+
|
|
30
|
+
### Response Timeline
|
|
31
|
+
|
|
32
|
+
- **Acknowledgment:** Within 48 hours
|
|
33
|
+
- **Assessment:** Within 5 business days
|
|
34
|
+
- **Fix timeline:** Depends on severity (critical: 7 days, high: 14 days, medium: 30 days)
|
|
35
|
+
|
|
36
|
+
## Security Considerations
|
|
37
|
+
|
|
38
|
+
### App Store Connect Credentials
|
|
39
|
+
|
|
40
|
+
The plugin uses ASC API credentials (Key ID, Issuer ID, private key) for App Store Connect validation. These credentials:
|
|
41
|
+
|
|
42
|
+
- Are read from environment variables (`ASC_KEY_ID`, `ASC_ISSUER_ID`, `ASC_PRIVATE_KEY_PATH`)
|
|
43
|
+
- Are never logged, stored, or transmitted outside the ASC API
|
|
44
|
+
- Are used only to generate short-lived JWTs for ASC API calls
|
|
45
|
+
- Should be stored in your CI platform's secrets management
|
|
46
|
+
|
|
47
|
+
**Never commit `.p8` private key files to version control.**
|
|
48
|
+
|
|
49
|
+
### File System Access
|
|
50
|
+
|
|
51
|
+
The plugin reads files from the specified project path and its subdirectories. It:
|
|
52
|
+
|
|
53
|
+
- Reads source files (`.swift`, `.m`, `.mm`, `.h`, `.c`, `.cpp`), plists, storyboards, asset catalogs
|
|
54
|
+
- Does not modify any project files
|
|
55
|
+
- Does not execute any project code
|
|
56
|
+
- Does not download or install any dependencies from the project
|
|
57
|
+
- Writes only to explicitly specified output paths (report files, badge SVG, history store)
|
|
58
|
+
|
|
59
|
+
### Scan History Storage
|
|
60
|
+
|
|
61
|
+
When `--save-history` is used, scan results are stored as JSON files in a `.ios-review-history` directory near the project. These files contain:
|
|
62
|
+
|
|
63
|
+
- Issue IDs and titles
|
|
64
|
+
- File paths and line numbers
|
|
65
|
+
- Scores and timestamps
|
|
66
|
+
- Git branch and commit info
|
|
67
|
+
|
|
68
|
+
Review the history directory contents and add it to `.gitignore` if the data is sensitive.
|
|
69
|
+
|
|
70
|
+
### Network Access
|
|
71
|
+
|
|
72
|
+
The plugin makes network requests only when ASC validation is enabled (`--include-asc`). All requests go to Apple's App Store Connect API (`api.appstoreconnect.apple.com`) over HTTPS.
|
|
73
|
+
|
|
74
|
+
No telemetry, analytics, or other network calls are made.
|
|
75
|
+
|
|
76
|
+
### Dependencies
|
|
77
|
+
|
|
78
|
+
The plugin uses a minimal dependency set:
|
|
79
|
+
|
|
80
|
+
- `@modelcontextprotocol/sdk` -- MCP protocol
|
|
81
|
+
- `fast-glob` -- File discovery
|
|
82
|
+
- `plist` -- Plist parsing
|
|
83
|
+
- `zod` -- Input validation
|
|
84
|
+
|
|
85
|
+
All dependencies should be audited regularly:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npm audit
|
|
89
|
+
```
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# Troubleshooting
|
|
2
|
+
|
|
3
|
+
## Installation Issues
|
|
4
|
+
|
|
5
|
+
### "Cannot find module" errors after build
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
Error: Cannot find module '/path/to/dist/index.js'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Rebuild the project:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm run clean && npm run build
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Node.js version error
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
SyntaxError: Unexpected token ...
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The plugin requires Node.js >= 18. Check your version:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
node --version
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Project Parsing Errors
|
|
32
|
+
|
|
33
|
+
### "No Xcode project found" or empty results
|
|
34
|
+
|
|
35
|
+
The plugin looks for `.xcodeproj` or `.xcworkspace` at the specified path. Make sure you point to the right location:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Point to the .xcodeproj file, not the directory containing it
|
|
39
|
+
ios-app-review scan ./MyApp/MyApp.xcodeproj
|
|
40
|
+
|
|
41
|
+
# Or the directory containing the .xcodeproj
|
|
42
|
+
ios-app-review scan ./MyApp/
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### "Failed to parse project.pbxproj"
|
|
46
|
+
|
|
47
|
+
Complex `.pbxproj` files with unusual formatting may cause parse issues. Verify the file is valid:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
plutil -lint ./MyApp.xcodeproj/project.pbxproj
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
If the project uses Xcode build settings variables like `$(SRCROOT)` in paths, the parser resolves these to the project's base directory.
|
|
54
|
+
|
|
55
|
+
### No source files found
|
|
56
|
+
|
|
57
|
+
The scanner excludes these directories by default:
|
|
58
|
+
- `Pods/`
|
|
59
|
+
- `Carthage/`
|
|
60
|
+
- `build/`
|
|
61
|
+
- `DerivedData/`
|
|
62
|
+
- `Tests/`
|
|
63
|
+
- `UITests/`
|
|
64
|
+
- `*.generated.swift`
|
|
65
|
+
|
|
66
|
+
If your source files are in an unexpected location, ensure they are referenced in the Xcode project's target or accessible under the base path.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Info.plist Issues
|
|
71
|
+
|
|
72
|
+
### "Info.plist not found at configured path"
|
|
73
|
+
|
|
74
|
+
The path in the project's build settings (INFOPLIST_FILE) is relative to the project directory. The plugin resolves it automatically, but if the file was moved:
|
|
75
|
+
|
|
76
|
+
1. Check the actual path: `find . -name "Info.plist"`
|
|
77
|
+
2. Update the build setting in Xcode
|
|
78
|
+
3. Or use `check_info_plist` directly with the absolute path
|
|
79
|
+
|
|
80
|
+
### Plist parse errors
|
|
81
|
+
|
|
82
|
+
Binary plists are supported. If parsing fails, convert to XML format:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
plutil -convert xml1 ./MyApp/Info.plist
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## App Store Connect (ASC) Issues
|
|
91
|
+
|
|
92
|
+
### "ASC_KEY_ID environment variable is required"
|
|
93
|
+
|
|
94
|
+
Set all three required environment variables:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
export ASC_KEY_ID="XXXXXXXXXX"
|
|
98
|
+
export ASC_ISSUER_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
|
99
|
+
export ASC_PRIVATE_KEY_PATH="/path/to/AuthKey_XXXXXXXXXX.p8"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### "Unable to read private key"
|
|
103
|
+
|
|
104
|
+
1. Verify the file exists and is readable:
|
|
105
|
+
```bash
|
|
106
|
+
ls -la "$ASC_PRIVATE_KEY_PATH"
|
|
107
|
+
```
|
|
108
|
+
2. Check the file format. It should start with `-----BEGIN PRIVATE KEY-----`.
|
|
109
|
+
3. Ensure no extra whitespace or characters were added during transfer.
|
|
110
|
+
|
|
111
|
+
### "401 Unauthorized" from ASC API
|
|
112
|
+
|
|
113
|
+
- **Key expired or revoked:** Regenerate the key in App Store Connect > Users and Access > Keys.
|
|
114
|
+
- **Wrong Issuer ID:** The Issuer ID is shown at the top of the Keys page, not on individual key rows.
|
|
115
|
+
- **Insufficient permissions:** The API key must have at least "App Manager" role.
|
|
116
|
+
- **Clock skew:** JWT tokens include timestamps. Ensure your system clock is accurate.
|
|
117
|
+
|
|
118
|
+
### "404 Not Found" for bundle ID
|
|
119
|
+
|
|
120
|
+
The bundle ID must match an app that exists in your App Store Connect account. Check:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# List apps (requires ASC CLI or API)
|
|
124
|
+
# The bundleId is case-sensitive
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Rate limiting
|
|
128
|
+
|
|
129
|
+
The ASC API client includes built-in rate limiting. If you see rate limit errors, the client will automatically retry after the specified delay. For parallel CI builds, consider staggering ASC validation steps.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Custom Rules Issues
|
|
134
|
+
|
|
135
|
+
### "No .ios-review-rules.json found"
|
|
136
|
+
|
|
137
|
+
The rule loader searches from the project directory upward. Place the file:
|
|
138
|
+
- In the project root (next to `.xcodeproj`)
|
|
139
|
+
- Or in any parent directory
|
|
140
|
+
- Or specify explicitly: `--config ./path/to/rules.json`
|
|
141
|
+
|
|
142
|
+
### "Custom rules validation FAILED"
|
|
143
|
+
|
|
144
|
+
Common issues:
|
|
145
|
+
- **Invalid JSON:** Run `jq . .ios-review-rules.json` to validate syntax.
|
|
146
|
+
- **Missing required fields:** Every rule needs `id`, `title`, `description`, `severity`, and `pattern`.
|
|
147
|
+
- **version must be 1:** The schema version must be the literal number `1`.
|
|
148
|
+
- **Invalid severity:** Must be `"error"`, `"warning"`, or `"info"`.
|
|
149
|
+
|
|
150
|
+
### Regex pattern not matching
|
|
151
|
+
|
|
152
|
+
- Backslashes must be double-escaped in JSON: `\\b` for `\b`, `\\s` for `\s`.
|
|
153
|
+
- Test patterns in JavaScript: `new RegExp("your-pattern", "g")`.
|
|
154
|
+
- Ensure the `flags` field is set (default: `"g"`). Without `g`, only the first match per file is reported.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Large Project Performance
|
|
159
|
+
|
|
160
|
+
### Scan takes too long
|
|
161
|
+
|
|
162
|
+
1. **Use incremental scanning:**
|
|
163
|
+
```bash
|
|
164
|
+
ios-app-review scan ./MyApp.xcodeproj --changed-since main
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
2. **Run specific analyzers:**
|
|
168
|
+
```bash
|
|
169
|
+
ios-app-review scan ./MyApp.xcodeproj --analyzers code,security
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
3. **Exclude unnecessary targets:** The plugin analyzes all application targets by default. If you have multiple targets, use the `targetName` parameter (MCP) to focus on one.
|
|
173
|
+
|
|
174
|
+
### Memory issues on very large projects
|
|
175
|
+
|
|
176
|
+
For projects with thousands of source files, Node.js may need more heap space:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
NODE_OPTIONS="--max-old-space-size=4096" ios-app-review scan ./MyApp.xcodeproj
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## History and Comparison Issues
|
|
185
|
+
|
|
186
|
+
### "No previous scan found"
|
|
187
|
+
|
|
188
|
+
Run a scan with `--save-history` first to create the baseline:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
ios-app-review scan ./MyApp.xcodeproj --save-history
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
History is stored in `.ios-review-history/` near the project directory.
|
|
195
|
+
|
|
196
|
+
### History directory location
|
|
197
|
+
|
|
198
|
+
The history store writes to a `.ios-review-history` directory in the parent directory of the resolved project path. For example, if your project is at `/code/MyApp/MyApp.xcodeproj`, history is stored in `/code/MyApp/.ios-review-history/`.
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## MCP Server Issues
|
|
203
|
+
|
|
204
|
+
### Server does not start
|
|
205
|
+
|
|
206
|
+
When run without arguments, the binary starts as an MCP server on stdio. Ensure your MCP client configuration points to the correct path:
|
|
207
|
+
|
|
208
|
+
```json
|
|
209
|
+
{
|
|
210
|
+
"ios-app-review": {
|
|
211
|
+
"command": "node",
|
|
212
|
+
"args": ["/absolute/path/to/ios-app-review-plugin/dist/index.js"]
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### "Unknown tool" errors
|
|
218
|
+
|
|
219
|
+
Verify you are calling tools with their exact names. Tool names use underscores, not hyphens: `analyze_ios_app`, not `analyze-ios-app`.
|
|
220
|
+
|
|
221
|
+
### Server crashes silently
|
|
222
|
+
|
|
223
|
+
Check stderr output. The server logs startup and fatal errors to stderr:
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
node dist/index.js 2>server.log
|
|
227
|
+
```
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# App Store Connect Setup Tutorial
|
|
2
|
+
|
|
3
|
+
This tutorial walks through generating an API key, configuring environment variables, and using the ASC validation tools.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The ASC validators check your app's metadata, screenshots, version info, and in-app purchases directly against the App Store Connect API. This catches issues that are only visible in ASC, like missing screenshot sizes, incomplete localizations, or version conflicts.
|
|
8
|
+
|
|
9
|
+
**Requirements:**
|
|
10
|
+
- An Apple Developer Program membership
|
|
11
|
+
- Admin or App Manager access to App Store Connect
|
|
12
|
+
- An app already created in App Store Connect
|
|
13
|
+
|
|
14
|
+
## Step 1: Generate an API Key
|
|
15
|
+
|
|
16
|
+
1. Open [App Store Connect](https://appstoreconnect.apple.com/).
|
|
17
|
+
2. Navigate to **Users and Access** > **Integrations** > **App Store Connect API**.
|
|
18
|
+
3. Click **Generate API Key** (or the "+" button).
|
|
19
|
+
4. Name it something descriptive: `ios-app-review-ci`.
|
|
20
|
+
5. Select the **App Manager** role (minimum required).
|
|
21
|
+
6. Click **Generate**.
|
|
22
|
+
|
|
23
|
+
You will see:
|
|
24
|
+
- **Key ID**: A 10-character alphanumeric string (e.g., `ABC1234DEF`)
|
|
25
|
+
- **Issuer ID**: A UUID shown at the top of the page (e.g., `12345678-abcd-efgh-ijkl-123456789012`)
|
|
26
|
+
|
|
27
|
+
7. Click **Download API Key** to get the `.p8` file. You can only download this once.
|
|
28
|
+
|
|
29
|
+
Save the `.p8` file securely. A typical location:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
~/.appstoreconnect/AuthKey_ABC1234DEF.p8
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Step 2: Configure Environment Variables
|
|
36
|
+
|
|
37
|
+
Set three environment variables:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
export ASC_KEY_ID="ABC1234DEF"
|
|
41
|
+
export ASC_ISSUER_ID="12345678-abcd-efgh-ijkl-123456789012"
|
|
42
|
+
export ASC_PRIVATE_KEY_PATH="$HOME/.appstoreconnect/AuthKey_ABC1234DEF.p8"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
For persistent configuration, add these to your shell profile (`~/.zshrc` or `~/.bashrc`).
|
|
46
|
+
|
|
47
|
+
### For CI Systems
|
|
48
|
+
|
|
49
|
+
| Platform | How to store |
|
|
50
|
+
|----------|-------------|
|
|
51
|
+
| GitHub Actions | Settings > Secrets > Add `ASC_KEY_ID`, `ASC_ISSUER_ID`, `ASC_PRIVATE_KEY` (file contents) |
|
|
52
|
+
| Fastlane | `.env` file or Fastlane Match |
|
|
53
|
+
| Bitrise | Secrets tab in workflow editor |
|
|
54
|
+
| Xcode Cloud | Workflow > Environment Variables |
|
|
55
|
+
|
|
56
|
+
In CI, you typically store the `.p8` file contents as a secret and write it to a temp file:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
echo "$ASC_PRIVATE_KEY" > /tmp/AuthKey.p8
|
|
60
|
+
export ASC_PRIVATE_KEY_PATH=/tmp/AuthKey.p8
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Step 3: Verify the Connection
|
|
64
|
+
|
|
65
|
+
### Using the CLI
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
ios-app-review scan ./MyApp.xcodeproj --include-asc --analyzers asc-metadata
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
If credentials are correct, you will see metadata validation results. If not, you will get an authentication error.
|
|
72
|
+
|
|
73
|
+
### Using the MCP Tool
|
|
74
|
+
|
|
75
|
+
In Claude Code:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
Validate the App Store Connect metadata for bundle ID com.mycompany.myapp
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
This calls the `validate_asc_metadata` tool.
|
|
82
|
+
|
|
83
|
+
## Step 4: Run ASC Validators
|
|
84
|
+
|
|
85
|
+
### Individual Validators
|
|
86
|
+
|
|
87
|
+
**Metadata check:**
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Via MCP
|
|
91
|
+
validate_asc_metadata with bundleId "com.mycompany.myapp"
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Checks: app name length, subtitle, description, keywords, privacy policy URL, support URL, marketing URL.
|
|
95
|
+
|
|
96
|
+
**Screenshots check:**
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# Via MCP
|
|
100
|
+
validate_asc_screenshots with bundleId "com.mycompany.myapp"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Checks: required device sizes present, screenshot counts per locale, no failed uploads.
|
|
104
|
+
|
|
105
|
+
**Version comparison:**
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# Via MCP
|
|
109
|
+
compare_versions with bundleId "com.mycompany.myapp", localVersion "2.1.0", localBuild "45"
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Checks: version/build number increments, submission status, release notes presence.
|
|
113
|
+
|
|
114
|
+
**IAP validation:**
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# Via MCP
|
|
118
|
+
validate_iap with bundleId "com.mycompany.myapp"
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Checks: localized names/descriptions, review screenshots, submission readiness.
|
|
122
|
+
|
|
123
|
+
### Full ASC Validation
|
|
124
|
+
|
|
125
|
+
Run all four validators at once:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# Via MCP
|
|
129
|
+
full_asc_validation with bundleId "com.mycompany.myapp"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Or via CLI:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
ios-app-review scan ./MyApp.xcodeproj --include-asc
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Step 5: Understand ASC Results
|
|
139
|
+
|
|
140
|
+
ASC issues use these categories:
|
|
141
|
+
|
|
142
|
+
| Category | Validator |
|
|
143
|
+
|----------|-----------|
|
|
144
|
+
| `metadata` | asc-metadata |
|
|
145
|
+
| `screenshots` | asc-screenshots |
|
|
146
|
+
| `version` | asc-version |
|
|
147
|
+
| `iap` | asc-iap |
|
|
148
|
+
|
|
149
|
+
Common findings:
|
|
150
|
+
|
|
151
|
+
- **Missing privacy policy URL** -- Required for all apps. Add in App Store Connect > App Information.
|
|
152
|
+
- **App name too long** -- Must be 30 characters or fewer.
|
|
153
|
+
- **Missing screenshots for device** -- iPhone 6.7" and 6.5" are required. iPad 12.9" if supporting iPad.
|
|
154
|
+
- **Failed screenshot uploads** -- Re-upload screenshots that show "processing failed" status.
|
|
155
|
+
- **Version not incremented** -- The new version must be higher than the current App Store version.
|
|
156
|
+
- **IAP missing review screenshot** -- Each IAP needs a screenshot for Apple's review team.
|
|
157
|
+
- **IAP missing localization** -- Name and description must be provided in at least one language.
|
|
158
|
+
|
|
159
|
+
## Troubleshooting
|
|
160
|
+
|
|
161
|
+
### "401 Unauthorized"
|
|
162
|
+
|
|
163
|
+
- Verify the Key ID matches the downloaded key.
|
|
164
|
+
- Verify the Issuer ID (shown at the top of the Keys page, not per-key).
|
|
165
|
+
- Regenerate the key if it was revoked.
|
|
166
|
+
- Check system clock accuracy (JWT tokens are time-sensitive).
|
|
167
|
+
|
|
168
|
+
### "404 Not Found" for bundle ID
|
|
169
|
+
|
|
170
|
+
- The bundle ID is case-sensitive.
|
|
171
|
+
- The app must exist in your ASC account.
|
|
172
|
+
- The API key must have access to the app (check team membership).
|
|
173
|
+
|
|
174
|
+
### Rate Limiting
|
|
175
|
+
|
|
176
|
+
The ASC API has rate limits. The client handles retries automatically. If running in parallel CI jobs, stagger ASC checks or use a shared rate limiter.
|
|
177
|
+
|
|
178
|
+
### Permission Errors
|
|
179
|
+
|
|
180
|
+
The API key needs at least **App Manager** role. **Developer** role is insufficient for reading all metadata.
|
|
181
|
+
|
|
182
|
+
## Security Notes
|
|
183
|
+
|
|
184
|
+
- Never commit `.p8` files to version control.
|
|
185
|
+
- Add to `.gitignore`: `*.p8`, `AuthKey_*.p8`.
|
|
186
|
+
- Use CI secrets for all three credential values.
|
|
187
|
+
- The plugin generates short-lived JWT tokens (20-minute expiry) and does not persist credentials.
|
|
188
|
+
- Delete temp key files after CI runs: `rm /tmp/AuthKey.p8`.
|