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
@@ -0,0 +1,226 @@
1
+ # Getting Started
2
+
3
+ This tutorial walks through installing the plugin, running your first scan, understanding the results, and fixing common issues.
4
+
5
+ ## Prerequisites
6
+
7
+ - Node.js >= 18
8
+ - An iOS project (`.xcodeproj` or `.xcworkspace`)
9
+ - (Optional) App Store Connect API key for ASC validation
10
+
11
+ ## Step 1: Install
12
+
13
+ ```bash
14
+ git clone https://github.com/ahmetsina/ios-app-review-plugin.git
15
+ cd ios-app-review-plugin
16
+ npm install
17
+ npm run build
18
+ ```
19
+
20
+ To use the CLI globally:
21
+
22
+ ```bash
23
+ npm link
24
+ # or
25
+ npm install -g .
26
+ ```
27
+
28
+ Verify:
29
+
30
+ ```bash
31
+ ios-app-review version
32
+ ```
33
+
34
+ ## Step 2: Run Your First Scan
35
+
36
+ Point the tool at your Xcode project:
37
+
38
+ ```bash
39
+ ios-app-review scan /path/to/MyApp.xcodeproj
40
+ ```
41
+
42
+ This runs all 8 core analyzers and prints a Markdown report to stdout. A typical first run takes 1-5 seconds depending on project size.
43
+
44
+ ### What Happens During a Scan
45
+
46
+ 1. The Xcode project file (`.pbxproj`) is parsed to discover targets, source files, Info.plist paths, and entitlements paths.
47
+ 2. Each analyzer runs in parallel against the relevant files.
48
+ 3. Issues are collected and enriched with guideline cross-references.
49
+ 4. A readiness score (0-100) is calculated.
50
+ 5. The formatted report is printed.
51
+
52
+ ## Step 3: Understand the Results
53
+
54
+ The report has these sections:
55
+
56
+ ### Review Readiness Score
57
+
58
+ A number from 0 to 100. Higher is better. The score is calculated based on the number and severity of issues found, weighted by the corresponding App Store Review Guideline importance.
59
+
60
+ - **80-100:** Ready for submission. Minor tweaks may help.
61
+ - **50-79:** Several issues to address. Likely rejection if errors remain.
62
+ - **0-49:** Significant problems. Address all errors before submitting.
63
+
64
+ ### Summary Table
65
+
66
+ Quick counts of errors, warnings, and info items plus total scan duration.
67
+
68
+ ### Priority Remediation
69
+
70
+ Error-severity issues sorted by guideline severity weight. Fix these first -- they are the most likely rejection causes.
71
+
72
+ ### Issues by Category
73
+
74
+ All issues grouped by category (Info.plist, Privacy, Code Quality, Security, etc.). Each issue includes:
75
+
76
+ - **Severity badge** -- `[ERROR]` must be fixed, `[WARN]` should be fixed, `[INFO]` is advisory
77
+ - **Title** -- Brief description
78
+ - **Description** -- Details and the code/pattern that triggered it
79
+ - **Location** -- File path and line number
80
+ - **Guideline** -- Link to the relevant Apple guideline
81
+ - **Suggestion** -- How to fix it
82
+
83
+ ## Step 4: Fix Common Issues
84
+
85
+ ### Errors (Must Fix)
86
+
87
+ **Missing required Info.plist keys:**
88
+
89
+ ```xml
90
+ <!-- Add to Info.plist -->
91
+ <key>CFBundleExecutable</key>
92
+ <string>$(EXECUTABLE_NAME)</string>
93
+ ```
94
+
95
+ **Hardcoded API keys:**
96
+
97
+ ```swift
98
+ // BAD
99
+ let apiKey = "sk-1234567890abcdef"
100
+
101
+ // GOOD
102
+ let apiKey = ProcessInfo.processInfo.environment["API_KEY"] ?? ""
103
+ ```
104
+
105
+ **UIWebView usage:**
106
+
107
+ Replace all `UIWebView` instances with `WKWebView`:
108
+
109
+ ```swift
110
+ // BAD
111
+ let webView = UIWebView()
112
+
113
+ // GOOD
114
+ import WebKit
115
+ let webView = WKWebView()
116
+ ```
117
+
118
+ **Missing privacy manifest:**
119
+
120
+ Create `PrivacyInfo.xcprivacy` in your project and declare Required Reason APIs:
121
+
122
+ ```xml
123
+ <?xml version="1.0" encoding="UTF-8"?>
124
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "...">
125
+ <plist version="1.0">
126
+ <dict>
127
+ <key>NSPrivacyAccessedAPITypes</key>
128
+ <array>
129
+ <dict>
130
+ <key>NSPrivacyAccessedAPIType</key>
131
+ <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
132
+ <key>NSPrivacyAccessedAPITypeReasons</key>
133
+ <array>
134
+ <string>CA92.1</string>
135
+ </array>
136
+ </dict>
137
+ </array>
138
+ </dict>
139
+ </plist>
140
+ ```
141
+
142
+ ### Warnings (Should Fix)
143
+
144
+ **ATS allows arbitrary loads:**
145
+
146
+ Remove the global bypass and use exception domains for specific servers:
147
+
148
+ ```xml
149
+ <key>NSAppTransportSecurity</key>
150
+ <dict>
151
+ <key>NSExceptionDomains</key>
152
+ <dict>
153
+ <key>legacy-api.example.com</key>
154
+ <dict>
155
+ <key>NSExceptionAllowsInsecureHTTPLoads</key>
156
+ <true/>
157
+ </dict>
158
+ </dict>
159
+ </dict>
160
+ ```
161
+
162
+ **Hardcoded IPv4 addresses:**
163
+
164
+ ```swift
165
+ // BAD
166
+ let server = "192.168.1.100"
167
+
168
+ // GOOD
169
+ let server = "api.myapp.com"
170
+ ```
171
+
172
+ **Short permission descriptions:**
173
+
174
+ ```xml
175
+ <!-- BAD -->
176
+ <key>NSCameraUsageDescription</key>
177
+ <string>Camera</string>
178
+
179
+ <!-- GOOD -->
180
+ <key>NSCameraUsageDescription</key>
181
+ <string>MyApp uses the camera to scan QR codes for quick login.</string>
182
+ ```
183
+
184
+ ## Step 5: Re-scan and Track Progress
185
+
186
+ After fixing issues, run the scan again:
187
+
188
+ ```bash
189
+ ios-app-review scan /path/to/MyApp.xcodeproj --save-history
190
+ ```
191
+
192
+ On subsequent scans with `--save-history`, you can compare progress:
193
+
194
+ ```bash
195
+ ios-app-review scan /path/to/MyApp.xcodeproj --save-history
196
+ ```
197
+
198
+ Use the `view_scan_history` MCP tool or compare scans to see your score trend over time.
199
+
200
+ ## Step 6: Set Up as MCP Server (Optional)
201
+
202
+ To use the plugin from Claude Code as an MCP server, add to `~/.claude/mcp_servers.json`:
203
+
204
+ ```json
205
+ {
206
+ "ios-app-review": {
207
+ "command": "node",
208
+ "args": ["/path/to/ios-app-review-plugin/dist/index.js"]
209
+ }
210
+ }
211
+ ```
212
+
213
+ Then in Claude Code, simply ask:
214
+
215
+ ```
216
+ Analyze my iOS app at /path/to/MyApp.xcodeproj for App Store compliance
217
+ ```
218
+
219
+ Claude will call the `analyze_ios_app` tool and present the results conversationally.
220
+
221
+ ## Next Steps
222
+
223
+ - [CI Integration Tutorial](./CI_INTEGRATION.md) -- Automate scans in your build pipeline
224
+ - [Custom Rules Tutorial](./CUSTOM_RULES.md) -- Add team-specific checks
225
+ - [ASC Setup Tutorial](./ASC_SETUP.md) -- Validate App Store Connect metadata
226
+ - [Analyzers Reference](../ANALYZERS.md) -- Full list of checks performed
@@ -0,0 +1,106 @@
1
+ # Video Script: Introduction to iOS App Review Plugin
2
+
3
+ **Duration:** 3 minutes
4
+ **Audience:** iOS developers who submit apps to the App Store
5
+ **Goal:** Explain the problem, show the tool, and demonstrate a first scan
6
+
7
+ ---
8
+
9
+ ## Opening (0:00 - 0:30)
10
+
11
+ **Hook:** "If you have ever had an app rejected by Apple, you know the frustration. A single missing privacy description or a leftover debug URL can cost you days."
12
+
13
+ **Problem statement:**
14
+ - App Store rejections are time-consuming.
15
+ - Apple checks dozens of criteria: privacy manifests, deprecated APIs, metadata completeness, icon sizes, security patterns.
16
+ - Manual checks are error-prone and tedious.
17
+
18
+ **Transition:** "The iOS App Review Plugin automates these checks before you submit."
19
+
20
+ ---
21
+
22
+ ## What It Does (0:30 - 1:15)
23
+
24
+ **Overview narration with on-screen text/graphics:**
25
+
26
+ The plugin is two things:
27
+ 1. A CLI tool you run locally or in CI.
28
+ 2. An MCP server that integrates with Claude Code.
29
+
30
+ **On screen: Show the architecture diagram.**
31
+
32
+ It runs 12 analyzers across two domains:
33
+
34
+ **Codebase (8 analyzers):**
35
+ - Info.plist validation
36
+ - Privacy manifest (iOS 17+)
37
+ - Entitlements
38
+ - Code scanning (secrets, debug code, IPv6)
39
+ - Deprecated APIs
40
+ - Private APIs
41
+ - Security vulnerabilities
42
+ - UI/UX compliance (icons, launch screen, accessibility)
43
+
44
+ **App Store Connect (4 analyzers):**
45
+ - Metadata completeness
46
+ - Screenshot validation
47
+ - Version comparison
48
+ - In-app purchase readiness
49
+
50
+ **Transition:** "Let me show you what it looks like in practice."
51
+
52
+ ---
53
+
54
+ ## Demo: First Scan (1:15 - 2:30)
55
+
56
+ **Terminal recording:**
57
+
58
+ ```bash
59
+ # Install
60
+ npm install -g ios-app-review-plugin
61
+
62
+ # Run a scan
63
+ ios-app-review scan ./SampleApp.xcodeproj
64
+ ```
65
+
66
+ **Narrate the output as it appears:**
67
+
68
+ 1. "The report starts with a readiness score -- 68 out of 100."
69
+ 2. "The summary shows 2 errors, 5 warnings, and 3 info items."
70
+ 3. "Priority Remediation lists the errors that will most likely cause rejection."
71
+ 4. "Scrolling down, issues are grouped by category."
72
+ 5. "Each issue includes the file, line number, Apple guideline reference, and a fix suggestion."
73
+
74
+ **Show fixing one issue:**
75
+
76
+ ```bash
77
+ # The scan found a hardcoded API key
78
+ # Fix it, then re-scan
79
+ ios-app-review scan ./SampleApp.xcodeproj
80
+ # Score improved to 78/100
81
+ ```
82
+
83
+ ---
84
+
85
+ ## What's Next (2:30 - 3:00)
86
+
87
+ **Closing narration:**
88
+
89
+ - "You can run this in CI to block PRs with errors."
90
+ - "Add --include-asc to validate your App Store Connect metadata too."
91
+ - "Custom rules let you enforce your team's own conventions."
92
+ - "Check the docs for setup guides on GitHub Actions, Fastlane, Bitrise, and Xcode Cloud."
93
+
94
+ **Call to action:**
95
+ - Link to GitHub repository
96
+ - Link to Getting Started tutorial
97
+ - "Star the repo if you find it useful."
98
+
99
+ ---
100
+
101
+ ## Production Notes
102
+
103
+ - Use a real sample project with deliberate issues for the demo.
104
+ - Terminal should use a large font (24pt+) with dark background.
105
+ - Highlight key parts of the output with colored overlays.
106
+ - Keep the pace brisk -- this is a 3-minute overview, not a deep dive.
@@ -0,0 +1,120 @@
1
+ # Video Script: CLI Usage
2
+
3
+ **Duration:** 2 minutes
4
+ **Audience:** Developers who have installed the plugin and want to learn the CLI
5
+ **Goal:** Cover the main CLI options through practical examples
6
+
7
+ ---
8
+
9
+ ## Opening (0:00 - 0:15)
10
+
11
+ "Let me walk through the CLI options you will use most often. The tool has one main command: scan."
12
+
13
+ ---
14
+
15
+ ## Basic Scan (0:15 - 0:35)
16
+
17
+ **Terminal:**
18
+
19
+ ```bash
20
+ ios-app-review scan ./MyApp.xcodeproj
21
+ ```
22
+
23
+ "By default, this runs all 8 core analyzers and prints a Markdown report to the terminal."
24
+
25
+ "The exit code is 0 for pass, 1 for errors found."
26
+
27
+ ---
28
+
29
+ ## Output Formats (0:35 - 0:55)
30
+
31
+ **Terminal:**
32
+
33
+ ```bash
34
+ # JSON for CI parsing
35
+ ios-app-review scan ./MyApp.xcodeproj --format json --output report.json
36
+
37
+ # HTML for sharing with the team
38
+ ios-app-review scan ./MyApp.xcodeproj --format html --output report.html
39
+ ```
40
+
41
+ "JSON is best for CI pipelines. HTML gives you a styled report with dark mode support and collapsible sections."
42
+
43
+ **Quick flash of the HTML report in a browser.**
44
+
45
+ ---
46
+
47
+ ## Selective Analyzers (0:55 - 1:10)
48
+
49
+ **Terminal:**
50
+
51
+ ```bash
52
+ # Only run code and security checks
53
+ ios-app-review scan ./MyApp.xcodeproj --analyzers code,security
54
+
55
+ # Only check privacy manifest
56
+ ios-app-review scan ./MyApp.xcodeproj --analyzers privacy
57
+ ```
58
+
59
+ "Use --analyzers with a comma-separated list to focus on specific areas. Useful when you are working on a targeted fix."
60
+
61
+ ---
62
+
63
+ ## Incremental Scanning (1:10 - 1:25)
64
+
65
+ **Terminal:**
66
+
67
+ ```bash
68
+ # Only scan files changed since main branch
69
+ ios-app-review scan ./MyApp.xcodeproj --changed-since main
70
+ ```
71
+
72
+ "This is the key option for CI. It scans only the files you changed, so PR checks run in seconds instead of minutes on large projects."
73
+
74
+ ---
75
+
76
+ ## Badge and History (1:25 - 1:40)
77
+
78
+ **Terminal:**
79
+
80
+ ```bash
81
+ ios-app-review scan ./MyApp.xcodeproj --badge --save-history
82
+
83
+ # badge.svg is created
84
+ # Scan is saved for future comparison
85
+ ```
86
+
87
+ "The --badge flag generates an SVG badge you can embed in your README. The --save-history flag persists the scan so you can track your score over time."
88
+
89
+ **Show the badge image.**
90
+
91
+ ---
92
+
93
+ ## ASC Validation (1:40 - 1:55)
94
+
95
+ **Terminal:**
96
+
97
+ ```bash
98
+ export ASC_KEY_ID="..."
99
+ export ASC_ISSUER_ID="..."
100
+ export ASC_PRIVATE_KEY_PATH="..."
101
+
102
+ ios-app-review scan ./MyApp.xcodeproj --include-asc
103
+ ```
104
+
105
+ "Add --include-asc to also validate your App Store Connect metadata, screenshots, and in-app purchases. You need an API key from App Store Connect."
106
+
107
+ ---
108
+
109
+ ## Closing (1:55 - 2:00)
110
+
111
+ "That covers the main CLI options. For the full reference, check docs/CLI.md in the repository."
112
+
113
+ ---
114
+
115
+ ## Production Notes
116
+
117
+ - All commands should be executed live (not simulated).
118
+ - Use a sample project that produces diverse output.
119
+ - Split-screen: terminal on left, brief explanation text on right.
120
+ - Keep each section snappy -- under 20 seconds per option.
@@ -0,0 +1,198 @@
1
+ # Video Script: CI Integration
2
+
3
+ **Duration:** 5 minutes
4
+ **Audience:** iOS developers setting up automated review checks in CI
5
+ **Goal:** Walk through GitHub Actions setup end-to-end, then briefly cover other platforms
6
+
7
+ ---
8
+
9
+ ## Opening (0:00 - 0:20)
10
+
11
+ "Catching App Store issues before they reach code review saves everyone time. In this video, I will set up automated review checks in GitHub Actions from scratch, then show how to adapt this for Fastlane, Bitrise, and Xcode Cloud."
12
+
13
+ ---
14
+
15
+ ## Part 1: GitHub Actions (0:20 - 3:00)
16
+
17
+ ### Create the Workflow (0:20 - 0:50)
18
+
19
+ **Editor (VS Code or similar):**
20
+
21
+ "Create a new file at .github/workflows/app-review.yml."
22
+
23
+ ```yaml
24
+ name: App Store Review Check
25
+ on:
26
+ pull_request:
27
+ branches: [main]
28
+ ```
29
+
30
+ "This triggers on pull requests to main."
31
+
32
+ ### Add the Job (0:50 - 1:30)
33
+
34
+ ```yaml
35
+ jobs:
36
+ review-check:
37
+ runs-on: macos-latest
38
+ steps:
39
+ - uses: actions/checkout@v4
40
+ with:
41
+ fetch-depth: 0
42
+
43
+ - uses: actions/setup-node@v4
44
+ with:
45
+ node-version: '20'
46
+
47
+ - name: Install ios-app-review
48
+ run: npm install -g ios-app-review-plugin
49
+
50
+ - name: Run review check
51
+ run: |
52
+ ios-app-review scan ./MyApp.xcodeproj \
53
+ --format json \
54
+ --output report.json
55
+ ```
56
+
57
+ "fetch-depth 0 gives us full git history, which we need for incremental scanning."
58
+
59
+ ### Add Artifact Upload (1:30 - 1:50)
60
+
61
+ ```yaml
62
+ - name: Upload report
63
+ if: always()
64
+ uses: actions/upload-artifact@v4
65
+ with:
66
+ name: review-report
67
+ path: report.json
68
+ ```
69
+
70
+ "'if: always()' ensures the report is uploaded even when the check fails."
71
+
72
+ ### Push and Test (1:50 - 2:15)
73
+
74
+ **Terminal:**
75
+
76
+ ```bash
77
+ git add .github/workflows/app-review.yml
78
+ git commit -m "Add App Store review CI check"
79
+ git push
80
+ ```
81
+
82
+ "Now I will open a PR to trigger it."
83
+
84
+ **Show GitHub PR checks tab with the workflow running. Show it completing with pass or fail.**
85
+
86
+ ### Add Incremental Scanning (2:15 - 2:35)
87
+
88
+ "For faster PR checks, scan only changed files:"
89
+
90
+ ```yaml
91
+ - name: Incremental scan
92
+ run: |
93
+ ios-app-review scan ./MyApp.xcodeproj \
94
+ --changed-since origin/main \
95
+ --format json \
96
+ --output report.json
97
+ ```
98
+
99
+ "This typically finishes in under 5 seconds."
100
+
101
+ ### Make It a Required Check (2:35 - 3:00)
102
+
103
+ **Browser -- GitHub Settings:**
104
+
105
+ 1. Settings > Branches > Branch protection rules
106
+ 2. Edit rule for `main`
107
+ 3. Enable "Require status checks"
108
+ 4. Select "App Store Review Check"
109
+
110
+ "Now PRs cannot merge until the review check passes."
111
+
112
+ ---
113
+
114
+ ## Part 2: Other Platforms (3:00 - 4:30)
115
+
116
+ ### Fastlane (3:00 - 3:30)
117
+
118
+ **Editor:**
119
+
120
+ ```ruby
121
+ # fastlane/Fastfile
122
+ lane :review_check do
123
+ sh("ios-app-review scan ../MyApp.xcodeproj --format json --output ../report.json")
124
+
125
+ report = JSON.parse(File.read("../report.json"))
126
+ if report["summary"]["errors"] > 0
127
+ UI.user_error!("Review check failed")
128
+ end
129
+ end
130
+
131
+ lane :release do
132
+ review_check # gate before submit
133
+ build_app
134
+ upload_to_app_store
135
+ end
136
+ ```
137
+
138
+ "Put it before upload_to_app_store so it gates your release lane."
139
+
140
+ ### Bitrise (3:30 - 3:55)
141
+
142
+ **Editor:**
143
+
144
+ ```yaml
145
+ - script@1:
146
+ title: Run ios-app-review
147
+ inputs:
148
+ - content: |
149
+ npm install -g ios-app-review-plugin
150
+ ios-app-review scan ./MyApp.xcodeproj \
151
+ --format json \
152
+ --output "$BITRISE_DEPLOY_DIR/report.json"
153
+ ```
154
+
155
+ "Bitrise deploys the report artifact automatically with the deploy-to-bitrise-io step."
156
+
157
+ ### Xcode Cloud (3:55 - 4:20)
158
+
159
+ **Editor:**
160
+
161
+ ```bash
162
+ # ci_scripts/ci_post_clone.sh
163
+ #!/bin/bash
164
+ set -e
165
+ brew install node 2>/dev/null || true
166
+ npm install -g ios-app-review-plugin
167
+ ios-app-review scan "$CI_PRIMARY_REPOSITORY_PATH/MyApp.xcodeproj" \
168
+ --format json --output "$CI_PRIMARY_REPOSITORY_PATH/report.json"
169
+ ```
170
+
171
+ "Xcode Cloud runs scripts in the ci_scripts directory automatically. Just make it executable and commit it."
172
+
173
+ ---
174
+
175
+ ## Part 3: Best Practices (4:20 - 4:50)
176
+
177
+ "Quick tips from running this in production:"
178
+
179
+ 1. "Use incremental scanning on PRs, full scans on main."
180
+ 2. "Save history on main branch pushes to track your score over time."
181
+ 3. "Start with errors-only blocking. The tool already only returns exit code 1 for errors, not warnings."
182
+ 4. "Cache node_modules to speed up installs."
183
+ 5. "Keep ASC credentials in your CI platform's secrets manager."
184
+
185
+ ---
186
+
187
+ ## Closing (4:50 - 5:00)
188
+
189
+ "That is CI integration in 5 minutes. All of these configurations are in the docs/CI_CD.md file in the repository. Check the links in the description."
190
+
191
+ ---
192
+
193
+ ## Production Notes
194
+
195
+ - Pre-record the GitHub Actions run to avoid waiting on CI during the video.
196
+ - Show the actual PR checks UI -- green check or red X.
197
+ - For the Fastlane/Bitrise/Xcode Cloud sections, show the config file briefly (10-15 seconds each).
198
+ - End card: link to repo, docs, and the Getting Started tutorial.
@@ -0,0 +1,33 @@
1
+ const typescript = require('@typescript-eslint/eslint-plugin');
2
+ const parser = require('@typescript-eslint/parser');
3
+
4
+ module.exports = [
5
+ {
6
+ files: ['src/**/*.ts'],
7
+ languageOptions: {
8
+ parser: parser,
9
+ parserOptions: {
10
+ ecmaVersion: 2022,
11
+ sourceType: 'module',
12
+ project: './tsconfig.json',
13
+ },
14
+ },
15
+ plugins: {
16
+ '@typescript-eslint': typescript,
17
+ },
18
+ rules: {
19
+ ...typescript.configs['recommended'].rules,
20
+ '@typescript-eslint/explicit-function-return-type': 'warn',
21
+ '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
22
+ '@typescript-eslint/no-explicit-any': 'error',
23
+ '@typescript-eslint/prefer-nullish-coalescing': 'warn',
24
+ '@typescript-eslint/prefer-optional-chain': 'warn',
25
+ 'no-console': ['warn', { allow: ['warn', 'error'] }],
26
+ 'eqeqeq': ['error', 'always'],
27
+ 'curly': ['error', 'all'],
28
+ },
29
+ },
30
+ {
31
+ ignores: ['dist/**', 'node_modules/**', 'coverage/**', '*.js'],
32
+ },
33
+ ];