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.
Files changed (205) hide show
  1. package/.claude/settings.local.json +42 -0
  2. package/.github/actions/ios-review/action.yml +106 -0
  3. package/.github/workflows/ci.yml +103 -0
  4. package/.github/workflows/publish.yml +57 -0
  5. package/CHANGELOG.md +66 -0
  6. package/CONTRIBUTING.md +175 -0
  7. package/LICENSE +21 -0
  8. package/README.md +205 -0
  9. package/bitrise/step.sh +128 -0
  10. package/bitrise/step.yml +101 -0
  11. package/dist/analyzer.d.ts.map +1 -0
  12. package/dist/analyzers/asc-iap.d.ts.map +1 -0
  13. package/dist/analyzers/asc-metadata.d.ts.map +1 -0
  14. package/dist/analyzers/asc-screenshots.d.ts.map +1 -0
  15. package/dist/analyzers/asc-version.d.ts.map +1 -0
  16. package/dist/analyzers/code-scanner.d.ts.map +1 -0
  17. package/dist/analyzers/deprecated-api.d.ts.map +1 -0
  18. package/dist/analyzers/entitlements.d.ts.map +1 -0
  19. package/dist/analyzers/index.d.ts.map +1 -0
  20. package/dist/analyzers/info-plist.d.ts.map +1 -0
  21. package/dist/analyzers/privacy.d.ts.map +1 -0
  22. package/dist/analyzers/private-api.d.ts.map +1 -0
  23. package/dist/analyzers/security.d.ts.map +1 -0
  24. package/dist/analyzers/ui-ux.d.ts.map +1 -0
  25. package/dist/asc/auth.d.ts.map +1 -0
  26. package/dist/asc/client.d.ts.map +1 -0
  27. package/dist/asc/endpoints/apps.d.ts.map +1 -0
  28. package/dist/asc/endpoints/iap.d.ts.map +1 -0
  29. package/dist/asc/endpoints/screenshots.d.ts.map +1 -0
  30. package/dist/asc/endpoints/versions.d.ts.map +1 -0
  31. package/dist/asc/errors.d.ts.map +1 -0
  32. package/dist/asc/index.d.ts.map +1 -0
  33. package/dist/asc/types.d.ts.map +1 -0
  34. package/dist/badge/generator.d.ts.map +1 -0
  35. package/dist/badge/index.d.ts.map +1 -0
  36. package/dist/badge/types.d.ts.map +1 -0
  37. package/dist/cache/file-cache.d.ts.map +1 -0
  38. package/dist/cache/index.d.ts.map +1 -0
  39. package/dist/cache/types.d.ts.map +1 -0
  40. package/dist/cli/commands/help.d.ts.map +1 -0
  41. package/dist/cli/commands/scan.d.ts.map +1 -0
  42. package/dist/cli/commands/version.d.ts.map +1 -0
  43. package/dist/cli/index.d.ts.map +1 -0
  44. package/dist/cli/types.d.ts.map +1 -0
  45. package/dist/git/diff.d.ts.map +1 -0
  46. package/dist/git/index.d.ts.map +1 -0
  47. package/dist/git/types.d.ts.map +1 -0
  48. package/dist/guidelines/database.d.ts.map +1 -0
  49. package/dist/guidelines/index.d.ts.map +1 -0
  50. package/dist/guidelines/matcher.d.ts.map +1 -0
  51. package/dist/guidelines/types.d.ts.map +1 -0
  52. package/dist/history/comparator.d.ts.map +1 -0
  53. package/dist/history/index.d.ts.map +1 -0
  54. package/dist/history/store.d.ts.map +1 -0
  55. package/dist/history/types.d.ts.map +1 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +994 -0
  58. package/dist/parsers/index.d.ts.map +1 -0
  59. package/dist/parsers/plist.d.ts.map +1 -0
  60. package/dist/parsers/xcodeproj.d.ts.map +1 -0
  61. package/dist/progress/index.d.ts.map +1 -0
  62. package/dist/progress/reporter.d.ts.map +1 -0
  63. package/dist/progress/types.d.ts.map +1 -0
  64. package/dist/reports/html.d.ts.map +1 -0
  65. package/dist/reports/index.d.ts.map +1 -0
  66. package/dist/reports/json.d.ts.map +1 -0
  67. package/dist/reports/markdown.d.ts.map +1 -0
  68. package/dist/reports/types.d.ts.map +1 -0
  69. package/dist/rules/engine.d.ts.map +1 -0
  70. package/dist/rules/index.d.ts.map +1 -0
  71. package/dist/rules/loader.d.ts.map +1 -0
  72. package/dist/rules/types.d.ts.map +1 -0
  73. package/dist/types/index.d.ts.map +1 -0
  74. package/docs/ANALYZERS.md +237 -0
  75. package/docs/API.md +308 -0
  76. package/docs/BADGES.md +130 -0
  77. package/docs/CI_CD.md +283 -0
  78. package/docs/CLI.md +140 -0
  79. package/docs/REPORTS.md +212 -0
  80. package/docs/ROADMAP.md +267 -0
  81. package/docs/RULES.md +182 -0
  82. package/docs/SECURITY.md +89 -0
  83. package/docs/TROUBLESHOOTING.md +227 -0
  84. package/docs/tutorials/ASC_SETUP.md +188 -0
  85. package/docs/tutorials/CI_INTEGRATION.md +292 -0
  86. package/docs/tutorials/CUSTOM_RULES.md +291 -0
  87. package/docs/tutorials/GETTING_STARTED.md +226 -0
  88. package/docs/video-scripts/01-introduction.md +106 -0
  89. package/docs/video-scripts/02-cli-usage.md +120 -0
  90. package/docs/video-scripts/03-ci-integration.md +198 -0
  91. package/eslint.config.js +33 -0
  92. package/examples/.ios-review-rules.json +82 -0
  93. package/examples/bitrise-workflow.yml +129 -0
  94. package/examples/fastlane-lane.rb +71 -0
  95. package/examples/github-action.yml +147 -0
  96. package/fastlane/Fastfile.example +114 -0
  97. package/fastlane/README.md +99 -0
  98. package/jest.config.js +36 -0
  99. package/package.json +65 -0
  100. package/scripts/benchmark.ts +112 -0
  101. package/scripts/debug-parser.ts +37 -0
  102. package/scripts/debug-pbxproj.ts +36 -0
  103. package/scripts/debug-specific.ts +47 -0
  104. package/scripts/test-analyze.ts +67 -0
  105. package/scripts/xcode-cloud-review.sh +167 -0
  106. package/src/analyzer.ts +227 -0
  107. package/src/analyzers/asc-iap.ts +300 -0
  108. package/src/analyzers/asc-metadata.ts +326 -0
  109. package/src/analyzers/asc-screenshots.ts +310 -0
  110. package/src/analyzers/asc-version.ts +368 -0
  111. package/src/analyzers/code-scanner.ts +408 -0
  112. package/src/analyzers/deprecated-api.ts +390 -0
  113. package/src/analyzers/entitlements.ts +345 -0
  114. package/src/analyzers/index.ts +12 -0
  115. package/src/analyzers/info-plist.ts +409 -0
  116. package/src/analyzers/privacy.ts +376 -0
  117. package/src/analyzers/private-api.ts +377 -0
  118. package/src/analyzers/security.ts +327 -0
  119. package/src/analyzers/ui-ux.ts +509 -0
  120. package/src/asc/auth.ts +204 -0
  121. package/src/asc/client.ts +258 -0
  122. package/src/asc/endpoints/apps.ts +115 -0
  123. package/src/asc/endpoints/iap.ts +171 -0
  124. package/src/asc/endpoints/screenshots.ts +164 -0
  125. package/src/asc/endpoints/versions.ts +174 -0
  126. package/src/asc/errors.ts +109 -0
  127. package/src/asc/index.ts +108 -0
  128. package/src/asc/types.ts +369 -0
  129. package/src/badge/generator.ts +48 -0
  130. package/src/badge/index.ts +2 -0
  131. package/src/badge/types.ts +5 -0
  132. package/src/cache/file-cache.ts +75 -0
  133. package/src/cache/index.ts +2 -0
  134. package/src/cache/types.ts +10 -0
  135. package/src/cli/commands/help.ts +41 -0
  136. package/src/cli/commands/scan.ts +44 -0
  137. package/src/cli/commands/version.ts +12 -0
  138. package/src/cli/index.ts +92 -0
  139. package/src/cli/types.ts +17 -0
  140. package/src/git/diff.ts +21 -0
  141. package/src/git/index.ts +2 -0
  142. package/src/git/types.ts +5 -0
  143. package/src/guidelines/database.ts +344 -0
  144. package/src/guidelines/index.ts +4 -0
  145. package/src/guidelines/matcher.ts +84 -0
  146. package/src/guidelines/types.ts +28 -0
  147. package/src/history/comparator.ts +114 -0
  148. package/src/history/index.ts +3 -0
  149. package/src/history/store.ts +135 -0
  150. package/src/history/types.ts +40 -0
  151. package/src/index.ts +1113 -0
  152. package/src/parsers/index.ts +3 -0
  153. package/src/parsers/plist.ts +253 -0
  154. package/src/parsers/xcodeproj.ts +265 -0
  155. package/src/progress/index.ts +2 -0
  156. package/src/progress/reporter.ts +65 -0
  157. package/src/progress/types.ts +9 -0
  158. package/src/reports/html.ts +322 -0
  159. package/src/reports/index.ts +20 -0
  160. package/src/reports/json.ts +92 -0
  161. package/src/reports/markdown.ts +187 -0
  162. package/src/reports/types.ts +26 -0
  163. package/src/rules/engine.ts +121 -0
  164. package/src/rules/index.ts +3 -0
  165. package/src/rules/loader.ts +83 -0
  166. package/src/rules/types.ts +25 -0
  167. package/src/types/index.ts +247 -0
  168. package/tests/analyzer.test.ts +142 -0
  169. package/tests/analyzers/asc-iap.test.ts +228 -0
  170. package/tests/analyzers/asc-metadata.test.ts +210 -0
  171. package/tests/analyzers/asc-screenshots.test.ts +135 -0
  172. package/tests/analyzers/asc-version.test.ts +259 -0
  173. package/tests/analyzers/code-scanner.test.ts +745 -0
  174. package/tests/analyzers/deprecated-api.test.ts +286 -0
  175. package/tests/analyzers/entitlements.test.ts +411 -0
  176. package/tests/analyzers/info-plist.test.ts +148 -0
  177. package/tests/analyzers/privacy.test.ts +623 -0
  178. package/tests/analyzers/private-api.test.ts +255 -0
  179. package/tests/analyzers/security.test.ts +300 -0
  180. package/tests/analyzers/ui-ux.test.ts +357 -0
  181. package/tests/asc/auth.test.ts +189 -0
  182. package/tests/asc/client.test.ts +207 -0
  183. package/tests/asc/endpoints.test.ts +1359 -0
  184. package/tests/badge/generator.test.ts +73 -0
  185. package/tests/cache/file-cache.test.ts +124 -0
  186. package/tests/cli/cli-index.test.ts +510 -0
  187. package/tests/cli/commands.test.ts +67 -0
  188. package/tests/cli/scan.test.ts +152 -0
  189. package/tests/git/diff.test.ts +69 -0
  190. package/tests/guidelines/matcher.test.ts +209 -0
  191. package/tests/history/comparator.test.ts +272 -0
  192. package/tests/history/store.test.ts +200 -0
  193. package/tests/integration/cli.test.ts +95 -0
  194. package/tests/integration/e2e.test.ts +130 -0
  195. package/tests/parsers/plist.test.ts +240 -0
  196. package/tests/parsers/xcodeproj.test.ts +289 -0
  197. package/tests/progress/reporter.test.ts +117 -0
  198. package/tests/reports/html.test.ts +176 -0
  199. package/tests/reports/json.test.ts +235 -0
  200. package/tests/reports/markdown.test.ts +196 -0
  201. package/tests/rules/engine.test.ts +229 -0
  202. package/tests/rules/loader.test.ts +187 -0
  203. package/tests/setup.ts +15 -0
  204. package/tsconfig.json +27 -0
  205. package/tsconfig.test.json +9 -0
package/docs/BADGES.md ADDED
@@ -0,0 +1,130 @@
1
+ # Badge Generation
2
+
3
+ The plugin generates shields.io-style SVG badges that display the review readiness score.
4
+
5
+ ## Generating a Badge
6
+
7
+ ### CLI
8
+
9
+ ```bash
10
+ ios-app-review scan ./MyApp.xcodeproj --badge
11
+ ```
12
+
13
+ This writes `badge.svg` to the current directory. When combined with `--output`, the badge is written next to the report file:
14
+
15
+ ```bash
16
+ ios-app-review scan ./MyApp.xcodeproj --badge --output reports/review.json
17
+ # Creates reports/badge.svg
18
+ ```
19
+
20
+ ### MCP Tool
21
+
22
+ The `generate_report` tool does not directly produce a badge, but the CLI `--badge` flag calls the badge generator after the report is created.
23
+
24
+ ## Badge Appearance
25
+
26
+ The badge has two sections:
27
+ - **Label** (left): "app review" in gray (`#555`)
28
+ - **Status** (right): score and pass/fail state, color-coded
29
+
30
+ ### Color Rules
31
+
32
+ | Condition | Color | Hex |
33
+ |-----------|-------|-----|
34
+ | Passed, score >= 80 | Green | `#44cc11` |
35
+ | Passed, score >= 50 | Yellow | `#dfb317` |
36
+ | Passed, score < 50 | Red | `#e05d44` |
37
+ | Failed (any errors) | Red | `#e05d44` |
38
+
39
+ ### Status Text
40
+
41
+ - Passing: `85/100`
42
+ - Failing: `fail 72/100`
43
+
44
+ ### Example SVG Output
45
+
46
+ A passing badge with score 85 renders as:
47
+
48
+ ```
49
+ [ app review | 85/100 ]
50
+ gray green
51
+ ```
52
+
53
+ A failing badge with score 60 renders as:
54
+
55
+ ```
56
+ [ app review | fail 60/100 ]
57
+ gray red
58
+ ```
59
+
60
+ ## Embedding in README
61
+
62
+ ### Direct File Reference
63
+
64
+ ```markdown
65
+ ![App Review](./badge.svg)
66
+ ```
67
+
68
+ ### With Link to Report
69
+
70
+ ```markdown
71
+ [![App Review](./badge.svg)](./reports/review.html)
72
+ ```
73
+
74
+ ### From CI Artifact
75
+
76
+ If your CI uploads the badge as an artifact, reference it from your repo's raw URL:
77
+
78
+ ```markdown
79
+ ![App Review](https://raw.githubusercontent.com/yourorg/yourapp/main/badge.svg)
80
+ ```
81
+
82
+ ## CI Integration
83
+
84
+ ### GitHub Actions: Commit Badge Back to Repo
85
+
86
+ ```yaml
87
+ - name: Generate badge
88
+ run: |
89
+ ios-app-review scan ./MyApp.xcodeproj --badge --format json --output report.json
90
+
91
+ - name: Commit badge
92
+ run: |
93
+ git config user.name "github-actions"
94
+ git config user.email "github-actions@github.com"
95
+ git add badge.svg
96
+ git diff --staged --quiet || git commit -m "Update review badge [skip ci]"
97
+ git push
98
+ ```
99
+
100
+ ### GitHub Actions: Upload as Artifact
101
+
102
+ ```yaml
103
+ - name: Upload badge
104
+ uses: actions/upload-artifact@v4
105
+ with:
106
+ name: review-badge
107
+ path: badge.svg
108
+ ```
109
+
110
+ ### Fastlane
111
+
112
+ ```ruby
113
+ lane :update_badge do
114
+ sh("ios-app-review scan ../MyApp.xcodeproj --badge")
115
+ # badge.svg is created in the current directory
116
+ end
117
+ ```
118
+
119
+ ## Customization
120
+
121
+ The badge generator accepts an optional `label` parameter (used internally). The default label is "app review". The badge dimensions scale automatically based on label and status text length.
122
+
123
+ ## SVG Details
124
+
125
+ - Font: Verdana, Geneva, DejaVu Sans
126
+ - Height: 20px
127
+ - Corner radius: 3px
128
+ - Includes ARIA attributes for accessibility (`role="img"`, `aria-label`)
129
+ - Uses `<linearGradient>` for subtle depth
130
+ - Shadow text offset for legibility
package/docs/CI_CD.md ADDED
@@ -0,0 +1,283 @@
1
+ # CI/CD Integration
2
+
3
+ The CLI exits with code 0 (pass) or 1 (errors found), making it a natural CI gate. This guide covers GitHub Actions, Fastlane, Bitrise, and Xcode Cloud.
4
+
5
+ ---
6
+
7
+ ## GitHub Actions
8
+
9
+ ### Basic Gate
10
+
11
+ ```yaml
12
+ # .github/workflows/app-review.yml
13
+ name: App Store Review Check
14
+
15
+ on:
16
+ pull_request:
17
+ paths:
18
+ - '**/*.swift'
19
+ - '**/*.m'
20
+ - '**/*.mm'
21
+ - '**/Info.plist'
22
+ - '**/PrivacyInfo.xcprivacy'
23
+ - '**/*.entitlements'
24
+
25
+ jobs:
26
+ review-check:
27
+ runs-on: macos-latest
28
+ steps:
29
+ - uses: actions/checkout@v4
30
+
31
+ - uses: actions/setup-node@v4
32
+ with:
33
+ node-version: '20'
34
+
35
+ - name: Install ios-app-review
36
+ run: npm install -g ios-app-review-plugin
37
+
38
+ - name: Run review check
39
+ run: ios-app-review scan ./MyApp.xcodeproj --format json --output report.json
40
+
41
+ - name: Upload report
42
+ if: always()
43
+ uses: actions/upload-artifact@v4
44
+ with:
45
+ name: review-report
46
+ path: report.json
47
+ ```
48
+
49
+ ### With ASC Validation and Badge
50
+
51
+ ```yaml
52
+ jobs:
53
+ review-check:
54
+ runs-on: macos-latest
55
+ steps:
56
+ - uses: actions/checkout@v4
57
+
58
+ - uses: actions/setup-node@v4
59
+ with:
60
+ node-version: '20'
61
+
62
+ - name: Install ios-app-review
63
+ run: npm install -g ios-app-review-plugin
64
+
65
+ - name: Run full review
66
+ env:
67
+ ASC_KEY_ID: ${{ secrets.ASC_KEY_ID }}
68
+ ASC_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }}
69
+ ASC_PRIVATE_KEY_PATH: ${{ runner.temp }}/AuthKey.p8
70
+ run: |
71
+ echo "${{ secrets.ASC_PRIVATE_KEY }}" > "$ASC_PRIVATE_KEY_PATH"
72
+ ios-app-review scan ./MyApp.xcodeproj \
73
+ --include-asc \
74
+ --badge \
75
+ --save-history \
76
+ --format json \
77
+ --output report.json
78
+
79
+ - name: Upload artifacts
80
+ if: always()
81
+ uses: actions/upload-artifact@v4
82
+ with:
83
+ name: review-report
84
+ path: |
85
+ report.json
86
+ badge.svg
87
+ ```
88
+
89
+ ### Incremental Scanning on PRs
90
+
91
+ ```yaml
92
+ - name: Incremental scan
93
+ run: |
94
+ ios-app-review scan ./MyApp.xcodeproj \
95
+ --changed-since origin/main \
96
+ --format json \
97
+ --output report.json
98
+ ```
99
+
100
+ ### PR Comment with Results
101
+
102
+ ```yaml
103
+ - name: Post results to PR
104
+ if: always()
105
+ uses: actions/github-script@v7
106
+ with:
107
+ script: |
108
+ const fs = require('fs');
109
+ const report = JSON.parse(fs.readFileSync('report.json', 'utf8'));
110
+ const status = report.summary.passed ? 'PASSED' : 'FAILED';
111
+ const body = `## App Review Check: ${status}
112
+
113
+ **Score:** ${report.score}/100
114
+ **Errors:** ${report.summary.errors} | **Warnings:** ${report.summary.warnings} | **Info:** ${report.summary.info}
115
+
116
+ ${report.issues.filter(i => i.severity === 'error').map(i => `- ${i.title}: ${i.filePath || ''}:${i.lineNumber || ''}`).join('\n')}`;
117
+
118
+ github.rest.issues.createComment({
119
+ issue_number: context.issue.number,
120
+ owner: context.repo.owner,
121
+ repo: context.repo.repo,
122
+ body
123
+ });
124
+ ```
125
+
126
+ ---
127
+
128
+ ## Fastlane
129
+
130
+ ### Fastfile Lane
131
+
132
+ ```ruby
133
+ # fastlane/Fastfile
134
+ desc "Run App Store review compliance check"
135
+ lane :review_check do
136
+ sh("ios-app-review scan ../MyApp.xcodeproj --format json --output ../review-report.json")
137
+
138
+ report = JSON.parse(File.read("../review-report.json"))
139
+
140
+ if report["summary"]["errors"] > 0
141
+ UI.user_error!("App Store review check failed with #{report['summary']['errors']} error(s). Score: #{report['score']}/100")
142
+ else
143
+ UI.success("App Store review check passed! Score: #{report['score']}/100")
144
+ end
145
+ end
146
+
147
+ desc "Full review with ASC validation"
148
+ lane :full_review do
149
+ review_check
150
+
151
+ sh(
152
+ "ios-app-review scan ../MyApp.xcodeproj " \
153
+ "--include-asc --format html --output ../review-report.html --badge"
154
+ )
155
+ end
156
+ ```
157
+
158
+ ### Run Before Submit
159
+
160
+ ```ruby
161
+ lane :submit do
162
+ review_check
163
+ build_app(scheme: "MyApp")
164
+ upload_to_app_store
165
+ end
166
+ ```
167
+
168
+ ---
169
+
170
+ ## Bitrise
171
+
172
+ ### bitrise.yml Step
173
+
174
+ ```yaml
175
+ workflows:
176
+ review-check:
177
+ steps:
178
+ - git-clone@8: {}
179
+
180
+ - nvm@1:
181
+ inputs:
182
+ - node_version: "20"
183
+
184
+ - script@1:
185
+ title: Install ios-app-review
186
+ inputs:
187
+ - content: npm install -g ios-app-review-plugin
188
+
189
+ - script@1:
190
+ title: Run review check
191
+ inputs:
192
+ - content: |
193
+ ios-app-review scan ./MyApp.xcodeproj \
194
+ --format json \
195
+ --output "$BITRISE_DEPLOY_DIR/review-report.json" \
196
+ --badge
197
+
198
+ # Copy badge to deploy dir
199
+ cp badge.svg "$BITRISE_DEPLOY_DIR/" 2>/dev/null || true
200
+
201
+ - deploy-to-bitrise-io@2:
202
+ inputs:
203
+ - deploy_path: "$BITRISE_DEPLOY_DIR/review-report.json"
204
+ ```
205
+
206
+ ### With ASC Secrets
207
+
208
+ Add `ASC_KEY_ID`, `ASC_ISSUER_ID`, and `ASC_PRIVATE_KEY` (base64-encoded) as Bitrise secrets, then:
209
+
210
+ ```yaml
211
+ - script@1:
212
+ title: Run full review
213
+ inputs:
214
+ - content: |
215
+ echo "$ASC_PRIVATE_KEY" | base64 -d > /tmp/AuthKey.p8
216
+ export ASC_PRIVATE_KEY_PATH=/tmp/AuthKey.p8
217
+
218
+ ios-app-review scan ./MyApp.xcodeproj \
219
+ --include-asc \
220
+ --format json \
221
+ --output "$BITRISE_DEPLOY_DIR/review-report.json"
222
+ ```
223
+
224
+ ---
225
+
226
+ ## Xcode Cloud
227
+
228
+ Xcode Cloud runs custom scripts at specific phases. Add a post-clone or post-build script.
229
+
230
+ ### ci_scripts/ci_post_clone.sh
231
+
232
+ ```bash
233
+ #!/bin/bash
234
+ set -e
235
+
236
+ # Install Node.js if not available
237
+ if ! command -v node &> /dev/null; then
238
+ brew install node
239
+ fi
240
+
241
+ # Install the tool
242
+ npm install -g ios-app-review-plugin
243
+
244
+ # Run the scan
245
+ ios-app-review scan "$CI_PRIMARY_REPOSITORY_PATH/MyApp.xcodeproj" \
246
+ --format json \
247
+ --output "$CI_PRIMARY_REPOSITORY_PATH/review-report.json"
248
+
249
+ # Print summary to build log
250
+ SCORE=$(cat "$CI_PRIMARY_REPOSITORY_PATH/review-report.json" | python3 -c "import sys,json; print(json.load(sys.stdin)['score'])")
251
+ ERRORS=$(cat "$CI_PRIMARY_REPOSITORY_PATH/review-report.json" | python3 -c "import sys,json; print(json.load(sys.stdin)['summary']['errors'])")
252
+
253
+ echo "App Review Score: $SCORE/100"
254
+ echo "Errors: $ERRORS"
255
+
256
+ if [ "$ERRORS" -gt 0 ]; then
257
+ echo "::error::App Store review check failed with $ERRORS error(s)"
258
+ exit 1
259
+ fi
260
+ ```
261
+
262
+ Make the script executable:
263
+
264
+ ```bash
265
+ chmod +x ci_scripts/ci_post_clone.sh
266
+ ```
267
+
268
+ ### ASC Credentials in Xcode Cloud
269
+
270
+ Xcode Cloud provides App Store Connect credentials automatically for certain operations. For the plugin's ASC validation, store the API key as a custom environment variable:
271
+
272
+ 1. In Xcode Cloud workflow settings, add environment variables for `ASC_KEY_ID` and `ASC_ISSUER_ID`.
273
+ 2. Store the private key content as a secret and write it to a temp file in the script.
274
+
275
+ ---
276
+
277
+ ## Tips for All Platforms
278
+
279
+ 1. **Use JSON output** for machine parsing. Markdown and HTML are better for human-readable artifacts.
280
+ 2. **Cache node_modules** to speed up repeated installs.
281
+ 3. **Incremental scanning** (`--changed-since`) significantly reduces scan time on PRs.
282
+ 4. **Save history** (`--save-history`) to track score trends across builds.
283
+ 5. **Exit code 2** indicates invalid arguments or crashes -- handle this separately from exit code 1 (issues found).
package/docs/CLI.md ADDED
@@ -0,0 +1,140 @@
1
+ # CLI Reference
2
+
3
+ The iOS App Review Plugin ships as a dual-mode binary. When invoked with arguments it runs as a CLI tool; without arguments it starts the MCP server.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ # Global install
9
+ npm install -g ios-app-review-plugin
10
+
11
+ # Or run directly after building
12
+ npm run build
13
+ node dist/index.js scan ./MyApp.xcodeproj
14
+ ```
15
+
16
+ The CLI binary is named `ios-app-review`.
17
+
18
+ ## Commands
19
+
20
+ ### scan
21
+
22
+ Analyze an iOS project for App Store review compliance.
23
+
24
+ ```
25
+ ios-app-review scan <path> [options]
26
+ ```
27
+
28
+ **Positional argument:**
29
+
30
+ - `<path>` -- Path to the `.xcodeproj`, `.xcworkspace`, or project directory. Required.
31
+
32
+ **Options:**
33
+
34
+ | Flag | Short | Default | Description |
35
+ |------|-------|---------|-------------|
36
+ | `--format <fmt>` | `-f` | `markdown` | Output format: `markdown`, `html`, or `json` |
37
+ | `--output <path>` | `-o` | stdout | Write report to a file |
38
+ | `--analyzers <list>` | `-a` | all | Comma-separated analyzer names |
39
+ | `--include-asc` | | false | Run App Store Connect validators |
40
+ | `--changed-since <ref>` | | | Git ref for incremental scanning |
41
+ | `--config <path>` | `-c` | auto | Path to `.ios-review-rules.json` |
42
+ | `--badge` | | false | Generate `badge.svg` alongside the report |
43
+ | `--save-history` | | false | Persist results for `compare_scans` |
44
+
45
+ **Analyzer names:** `info-plist`, `privacy`, `entitlements`, `code`, `deprecated-api`, `private-api`, `security`, `ui-ux`, `asc-metadata`, `asc-screenshots`, `asc-version`, `asc-iap`.
46
+
47
+ ### help
48
+
49
+ ```
50
+ ios-app-review help
51
+ ios-app-review --help
52
+ ios-app-review -h
53
+ ```
54
+
55
+ Print usage information and exit.
56
+
57
+ ### version
58
+
59
+ ```
60
+ ios-app-review version
61
+ ios-app-review --version
62
+ ios-app-review -v
63
+ ```
64
+
65
+ Print the version number and exit.
66
+
67
+ ## Exit Codes
68
+
69
+ | Code | Meaning |
70
+ |------|---------|
71
+ | `0` | All checks passed -- no errors found |
72
+ | `1` | One or more error-severity issues detected |
73
+ | `2` | Invalid arguments or a runtime error |
74
+
75
+ ## Examples
76
+
77
+ **Basic scan with default settings (markdown to stdout):**
78
+
79
+ ```bash
80
+ ios-app-review scan ./MyApp.xcodeproj
81
+ ```
82
+
83
+ **Generate an HTML report file:**
84
+
85
+ ```bash
86
+ ios-app-review scan ./MyApp.xcodeproj --format html --output reports/review.html
87
+ ```
88
+
89
+ **JSON report for CI pipeline parsing:**
90
+
91
+ ```bash
92
+ ios-app-review scan ./MyApp.xcodeproj --format json --output report.json
93
+ ```
94
+
95
+ **Run only code and security analyzers:**
96
+
97
+ ```bash
98
+ ios-app-review scan ./MyApp.xcodeproj --analyzers code,security
99
+ ```
100
+
101
+ **Incremental scan (only changed files since main branch):**
102
+
103
+ ```bash
104
+ ios-app-review scan ./MyApp.xcodeproj --changed-since main
105
+ ```
106
+
107
+ **Full scan with ASC validation, badge, and history:**
108
+
109
+ ```bash
110
+ export ASC_KEY_ID="XXXXXXXXXX"
111
+ export ASC_ISSUER_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
112
+ export ASC_PRIVATE_KEY_PATH="$HOME/.appstoreconnect/AuthKey_XXXXXXXXXX.p8"
113
+
114
+ ios-app-review scan ./MyApp.xcodeproj \
115
+ --include-asc \
116
+ --badge \
117
+ --save-history \
118
+ --format json \
119
+ --output report.json
120
+ ```
121
+
122
+ **Scan with custom rules:**
123
+
124
+ ```bash
125
+ ios-app-review scan ./MyApp.xcodeproj --config ./team-rules.json
126
+ ```
127
+
128
+ **Use in a CI gate (rely on exit code):**
129
+
130
+ ```bash
131
+ ios-app-review scan ./MyApp.xcodeproj --format json --output report.json
132
+ # exit code 0 = pass, 1 = fail, 2 = error
133
+ ```
134
+
135
+ ## Output Behavior
136
+
137
+ - When `--output` is specified, the formatted report is written to that file and a confirmation message is printed to stderr.
138
+ - When `--output` is omitted, the report is printed to stdout.
139
+ - When `--badge` is specified, `badge.svg` is written next to the output file (or in the current directory if no `--output`).
140
+ - Diagnostic/progress messages are always written to stderr so they do not interfere with piped stdout.