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/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
|
+

|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### With Link to Report
|
|
69
|
+
|
|
70
|
+
```markdown
|
|
71
|
+
[](./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
|
+

|
|
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.
|