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
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(xargs:*)",
|
|
5
|
+
"Bash(npm install)",
|
|
6
|
+
"Bash(npm run build:*)",
|
|
7
|
+
"Bash(npm test:*)",
|
|
8
|
+
"Bash(npm run lint:*)",
|
|
9
|
+
"Bash(git add:*)",
|
|
10
|
+
"Bash(git commit -m \"$\\(cat <<''EOF''\nImplement Phase 2: App Store Connect Integration\n\nAdd App Store Connect API integration to validate app metadata, screenshots,\nversions, and in-app purchases before submission.\n\nNew features:\n- JWT authentication using ES256 with token caching and auto-refresh\n- API client with rate limiting \\(500 req/hr\\), exponential backoff, pagination\n- ASC analyzers for metadata, screenshots, versions, and IAP validation\n- 5 new MCP tools: validate_asc_metadata, validate_asc_screenshots,\n compare_versions, validate_iap, full_asc_validation\n- Updated analyze_ios_app with includeASC option\n\nGraceful handling when credentials not configured - returns info-level\nissue rather than failing, allowing local-only analysis to continue.\n\nCo-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>\nEOF\n\\)\")",
|
|
11
|
+
"Bash(git push)",
|
|
12
|
+
"Bash(gh auth status:*)",
|
|
13
|
+
"Bash(gh auth:*)",
|
|
14
|
+
"Bash(gh repo sync:*)",
|
|
15
|
+
"Bash(gh api:*)",
|
|
16
|
+
"Bash(npx tsc:*)",
|
|
17
|
+
"Bash(npx jest:*)",
|
|
18
|
+
"Bash(git -C /Users/austem/Developer/Private/ios-app-review-plugin status)",
|
|
19
|
+
"Bash(git -C /Users/austem/Developer/Private/ios-app-review-plugin diff --stat)",
|
|
20
|
+
"Bash(git -C /Users/austem/Developer/Private/ios-app-review-plugin log --oneline -5)",
|
|
21
|
+
"Bash(git -C /Users/austem/Developer/Private/ios-app-review-plugin diff)",
|
|
22
|
+
"Bash(git -C /Users/austem/Developer/Private/ios-app-review-plugin add package.json src/analyzer.ts src/analyzers/index.ts src/index.ts src/parsers/xcodeproj.ts src/types/index.ts src/analyzers/asc-iap.ts src/analyzers/asc-metadata.ts src/analyzers/asc-screenshots.ts src/analyzers/asc-version.ts src/analyzers/deprecated-api.ts src/analyzers/private-api.ts src/analyzers/security.ts src/analyzers/ui-ux.ts src/asc/ tests/analyzers/asc-iap.test.ts tests/analyzers/asc-metadata.test.ts tests/analyzers/asc-screenshots.test.ts tests/analyzers/asc-version.test.ts tests/analyzers/deprecated-api.test.ts tests/analyzers/private-api.test.ts tests/analyzers/security.test.ts tests/analyzers/ui-ux.test.ts tests/asc/)",
|
|
23
|
+
"Bash(git -C /Users/austem/Developer/Private/ios-app-review-plugin commit -m \"$\\(cat <<''EOF''\nImplement Phase 2 \\(ASC integration\\) and Phase 3 \\(advanced analysis\\)\n\nPhase 2 adds App Store Connect API integration with JWT auth, rate\nlimiting, and validators for metadata, screenshots, versions, and IAP.\nPhase 3 adds deprecated API detection \\(20 APIs with deployment target\nawareness\\), private API scanning \\(selectors, frameworks, URL schemes\\),\nsecurity analysis \\(weak crypto, insecure storage, SQL injection\\), and\nUI/UX compliance checks \\(launch screen, icons, iPad, accessibility\\).\nBumps version to 0.3.0 with 13 MCP tools and 114 passing tests.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>\nEOF\n\\)\")",
|
|
24
|
+
"Bash(git commit:*)",
|
|
25
|
+
"Bash(gh release create:*)",
|
|
26
|
+
"Bash(wc:*)",
|
|
27
|
+
"Bash(ls:*)",
|
|
28
|
+
"Bash(npm run test:*)",
|
|
29
|
+
"Bash(npm list:*)",
|
|
30
|
+
"Bash(chmod:*)",
|
|
31
|
+
"Bash(git -C /Users/austem/Developer/Private/ios-app-review-plugin commit -m \"$\\(cat <<''EOF''\nImplement Phase 5: CI/CD & Polish \\(v1.0.0\\)\n\nDual-mode CLI/MCP entry point, parallel analysis with Promise.allSettled,\nfile caching, incremental git-based scanning, progress reporting, badge\ngeneration, GitHub Actions CI/publish workflows, Fastlane/Bitrise/Xcode\nCloud integrations, comprehensive docs, 486 tests at 80%+ coverage.\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>\nEOF\n\\)\")",
|
|
32
|
+
"Bash(git -C /Users/austem/Developer/Private/ios-app-review-plugin push)",
|
|
33
|
+
"Bash(git -C /Users/austem/Developer/Private/ios-app-review-plugin add docs/ROADMAP.md)",
|
|
34
|
+
"Bash(git -C /Users/austem/Developer/Private/ios-app-review-plugin commit -m \"$\\(cat <<''EOF''\nUpdate ROADMAP to mark Phase 5 as complete\n\nCo-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>\nEOF\n\\)\")",
|
|
35
|
+
"Bash(gh issue list:*)",
|
|
36
|
+
"Bash(gh issue close:*)",
|
|
37
|
+
"Bash(npm whoami:*)",
|
|
38
|
+
"Bash(npm view:*)",
|
|
39
|
+
"Bash(npm publish:*)"
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
name: 'iOS App Review'
|
|
2
|
+
description: 'Scan an iOS project for App Store review issues before submission'
|
|
3
|
+
author: 'ahmetsina'
|
|
4
|
+
|
|
5
|
+
branding:
|
|
6
|
+
icon: 'shield'
|
|
7
|
+
color: 'blue'
|
|
8
|
+
|
|
9
|
+
inputs:
|
|
10
|
+
project-path:
|
|
11
|
+
description: 'Path to the iOS project (.xcodeproj or .xcworkspace directory)'
|
|
12
|
+
required: true
|
|
13
|
+
format:
|
|
14
|
+
description: 'Output format: json, markdown, or html'
|
|
15
|
+
required: false
|
|
16
|
+
default: 'json'
|
|
17
|
+
analyzers:
|
|
18
|
+
description: 'Comma-separated list of analyzers to run (default: all). Options: info-plist, privacy, entitlements, code, deprecated-api, private-api, security, ui-ux'
|
|
19
|
+
required: false
|
|
20
|
+
default: 'all'
|
|
21
|
+
config:
|
|
22
|
+
description: 'Path to custom rules config file (.ios-review-rules.json)'
|
|
23
|
+
required: false
|
|
24
|
+
default: ''
|
|
25
|
+
version:
|
|
26
|
+
description: 'Version of ios-app-review-plugin to install (default: latest)'
|
|
27
|
+
required: false
|
|
28
|
+
default: 'latest'
|
|
29
|
+
|
|
30
|
+
outputs:
|
|
31
|
+
exit-code:
|
|
32
|
+
description: 'Exit code from the scan (0 = passed, 1 = issues found, 2 = error)'
|
|
33
|
+
value: ${{ steps.scan.outputs.exit-code }}
|
|
34
|
+
report-path:
|
|
35
|
+
description: 'Path to the generated report file'
|
|
36
|
+
value: ${{ steps.scan.outputs.report-path }}
|
|
37
|
+
|
|
38
|
+
runs:
|
|
39
|
+
using: 'composite'
|
|
40
|
+
steps:
|
|
41
|
+
- name: Setup Node.js 20
|
|
42
|
+
uses: actions/setup-node@v4
|
|
43
|
+
with:
|
|
44
|
+
node-version: 20
|
|
45
|
+
|
|
46
|
+
- name: Install ios-app-review-plugin
|
|
47
|
+
shell: bash
|
|
48
|
+
run: npm install -g ios-app-review-plugin@${{ inputs.version }}
|
|
49
|
+
|
|
50
|
+
- name: Run iOS App Review scan
|
|
51
|
+
id: scan
|
|
52
|
+
shell: bash
|
|
53
|
+
run: |
|
|
54
|
+
REPORT_DIR="${RUNNER_TEMP}/ios-review-report"
|
|
55
|
+
mkdir -p "$REPORT_DIR"
|
|
56
|
+
|
|
57
|
+
# Determine file extension based on format
|
|
58
|
+
case "${{ inputs.format }}" in
|
|
59
|
+
json) EXT="json" ;;
|
|
60
|
+
html) EXT="html" ;;
|
|
61
|
+
markdown) EXT="md" ;;
|
|
62
|
+
*) EXT="json" ;;
|
|
63
|
+
esac
|
|
64
|
+
|
|
65
|
+
REPORT_PATH="${REPORT_DIR}/report.${EXT}"
|
|
66
|
+
|
|
67
|
+
# Build the command
|
|
68
|
+
CMD="ios-app-review scan ${{ inputs.project-path }} --format ${{ inputs.format }} --output ${REPORT_PATH}"
|
|
69
|
+
|
|
70
|
+
# Add analyzers if not 'all'
|
|
71
|
+
if [ "${{ inputs.analyzers }}" != "all" ]; then
|
|
72
|
+
CMD="${CMD} --analyzers ${{ inputs.analyzers }}"
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
# Add custom config if provided
|
|
76
|
+
if [ -n "${{ inputs.config }}" ]; then
|
|
77
|
+
CMD="${CMD} --config ${{ inputs.config }}"
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# Run the scan and capture exit code
|
|
81
|
+
set +e
|
|
82
|
+
eval "$CMD"
|
|
83
|
+
EXIT_CODE=$?
|
|
84
|
+
set -e
|
|
85
|
+
|
|
86
|
+
echo "exit-code=${EXIT_CODE}" >> "$GITHUB_OUTPUT"
|
|
87
|
+
echo "report-path=${REPORT_PATH}" >> "$GITHUB_OUTPUT"
|
|
88
|
+
|
|
89
|
+
# Print summary
|
|
90
|
+
if [ "$EXIT_CODE" -eq 0 ]; then
|
|
91
|
+
echo "::notice::iOS App Review scan passed with no issues."
|
|
92
|
+
elif [ "$EXIT_CODE" -eq 1 ]; then
|
|
93
|
+
echo "::warning::iOS App Review scan found issues. See report at ${REPORT_PATH}"
|
|
94
|
+
else
|
|
95
|
+
echo "::error::iOS App Review scan failed with exit code ${EXIT_CODE}"
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
exit $EXIT_CODE
|
|
99
|
+
|
|
100
|
+
- name: Upload report artifact
|
|
101
|
+
if: always()
|
|
102
|
+
uses: actions/upload-artifact@v4
|
|
103
|
+
with:
|
|
104
|
+
name: ios-review-report
|
|
105
|
+
path: ${{ steps.scan.outputs.report-path }}
|
|
106
|
+
retention-days: 30
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
lint:
|
|
14
|
+
name: Lint
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- name: Checkout repository
|
|
18
|
+
uses: actions/checkout@v4
|
|
19
|
+
|
|
20
|
+
- name: Setup Node.js
|
|
21
|
+
uses: actions/setup-node@v4
|
|
22
|
+
with:
|
|
23
|
+
node-version: 20
|
|
24
|
+
cache: npm
|
|
25
|
+
|
|
26
|
+
- name: Install dependencies
|
|
27
|
+
run: npm ci
|
|
28
|
+
|
|
29
|
+
- name: Run ESLint
|
|
30
|
+
run: npx eslint src/**/*.ts
|
|
31
|
+
|
|
32
|
+
typecheck:
|
|
33
|
+
name: Type Check
|
|
34
|
+
runs-on: ubuntu-latest
|
|
35
|
+
steps:
|
|
36
|
+
- name: Checkout repository
|
|
37
|
+
uses: actions/checkout@v4
|
|
38
|
+
|
|
39
|
+
- name: Setup Node.js
|
|
40
|
+
uses: actions/setup-node@v4
|
|
41
|
+
with:
|
|
42
|
+
node-version: 20
|
|
43
|
+
cache: npm
|
|
44
|
+
|
|
45
|
+
- name: Install dependencies
|
|
46
|
+
run: npm ci
|
|
47
|
+
|
|
48
|
+
- name: Run TypeScript type checking
|
|
49
|
+
run: npx tsc --noEmit
|
|
50
|
+
|
|
51
|
+
test:
|
|
52
|
+
name: Test (Node ${{ matrix.node-version }})
|
|
53
|
+
runs-on: ubuntu-latest
|
|
54
|
+
strategy:
|
|
55
|
+
fail-fast: false
|
|
56
|
+
matrix:
|
|
57
|
+
node-version: [18, 20, 22]
|
|
58
|
+
steps:
|
|
59
|
+
- name: Checkout repository
|
|
60
|
+
uses: actions/checkout@v4
|
|
61
|
+
|
|
62
|
+
- name: Setup Node.js ${{ matrix.node-version }}
|
|
63
|
+
uses: actions/setup-node@v4
|
|
64
|
+
with:
|
|
65
|
+
node-version: ${{ matrix.node-version }}
|
|
66
|
+
cache: npm
|
|
67
|
+
|
|
68
|
+
- name: Install dependencies
|
|
69
|
+
run: npm ci
|
|
70
|
+
|
|
71
|
+
- name: Run tests with coverage
|
|
72
|
+
run: npx jest --coverage
|
|
73
|
+
|
|
74
|
+
- name: Upload coverage report
|
|
75
|
+
if: matrix.node-version == 20
|
|
76
|
+
uses: actions/upload-artifact@v4
|
|
77
|
+
with:
|
|
78
|
+
name: coverage-report
|
|
79
|
+
path: coverage/
|
|
80
|
+
retention-days: 14
|
|
81
|
+
|
|
82
|
+
build:
|
|
83
|
+
name: Build
|
|
84
|
+
runs-on: ubuntu-latest
|
|
85
|
+
needs: [lint, typecheck, test]
|
|
86
|
+
steps:
|
|
87
|
+
- name: Checkout repository
|
|
88
|
+
uses: actions/checkout@v4
|
|
89
|
+
|
|
90
|
+
- name: Setup Node.js
|
|
91
|
+
uses: actions/setup-node@v4
|
|
92
|
+
with:
|
|
93
|
+
node-version: 20
|
|
94
|
+
cache: npm
|
|
95
|
+
|
|
96
|
+
- name: Install dependencies
|
|
97
|
+
run: npm ci
|
|
98
|
+
|
|
99
|
+
- name: Build package
|
|
100
|
+
run: npm run build
|
|
101
|
+
|
|
102
|
+
- name: Verify dist output exists
|
|
103
|
+
run: test -f dist/index.js
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
name: Publish to npm
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
publish:
|
|
13
|
+
name: Build & Publish
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout repository
|
|
17
|
+
uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Setup Node.js
|
|
20
|
+
uses: actions/setup-node@v4
|
|
21
|
+
with:
|
|
22
|
+
node-version: 20
|
|
23
|
+
cache: npm
|
|
24
|
+
registry-url: https://registry.npmjs.org
|
|
25
|
+
|
|
26
|
+
- name: Install dependencies
|
|
27
|
+
run: npm ci
|
|
28
|
+
|
|
29
|
+
- name: Run linter
|
|
30
|
+
run: npx eslint src/**/*.ts
|
|
31
|
+
|
|
32
|
+
- name: Run type checking
|
|
33
|
+
run: npx tsc --noEmit
|
|
34
|
+
|
|
35
|
+
- name: Run tests
|
|
36
|
+
run: npx jest --coverage
|
|
37
|
+
|
|
38
|
+
- name: Build package
|
|
39
|
+
run: npm run build
|
|
40
|
+
|
|
41
|
+
- name: Verify dist output exists
|
|
42
|
+
run: test -f dist/index.js
|
|
43
|
+
|
|
44
|
+
- name: Verify tag matches package.json version
|
|
45
|
+
run: |
|
|
46
|
+
PACKAGE_VERSION="v$(node -p "require('./package.json').version")"
|
|
47
|
+
TAG_VERSION="${GITHUB_REF#refs/tags/}"
|
|
48
|
+
if [ "$PACKAGE_VERSION" != "$TAG_VERSION" ]; then
|
|
49
|
+
echo "Error: Tag $TAG_VERSION does not match package.json version $PACKAGE_VERSION"
|
|
50
|
+
exit 1
|
|
51
|
+
fi
|
|
52
|
+
echo "Version verified: $TAG_VERSION"
|
|
53
|
+
|
|
54
|
+
- name: Publish to npm
|
|
55
|
+
run: npm publish --access public
|
|
56
|
+
env:
|
|
57
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.0.0] - 2026-02-06
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **CLI mode**: Dual-mode entry point — run as CLI tool (`ios-app-review scan`) or MCP server
|
|
12
|
+
- `scan` command with `--format`, `--output`, `--analyzers`, `--badge`, `--save-history` options
|
|
13
|
+
- `help` and `version` commands
|
|
14
|
+
- Exit codes: 0 (pass), 1 (issues found), 2 (error)
|
|
15
|
+
- **Parallel analysis**: Analyzers run concurrently via `Promise.allSettled`
|
|
16
|
+
- **Incremental scanning**: `--changed-since` flag scans only git-changed files
|
|
17
|
+
- **Progress reporting**: EventEmitter-based progress events per analyzer
|
|
18
|
+
- **File caching**: In-memory cache keyed by path + mtime for MCP server mode
|
|
19
|
+
- **Badge generation**: shields.io-style SVG badges with score and pass/fail status
|
|
20
|
+
- **GitHub Actions**: CI workflow (lint, typecheck, test matrix), publish workflow, reusable composite action
|
|
21
|
+
- **CI/CD integrations**: Fastlane lane, Bitrise step, Xcode Cloud post-clone script
|
|
22
|
+
- **Comprehensive documentation**: API reference, CLI guide, analyzer docs, custom rules guide, CI/CD tutorials, troubleshooting, security policy, video script outlines
|
|
23
|
+
- **Examples**: GitHub Action workflow, Fastlane lane, Bitrise workflow, custom rules config
|
|
24
|
+
- **Benchmarks**: Performance benchmark script for small/medium/large projects
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- README rewritten with full v1.0 feature documentation
|
|
28
|
+
- Jest coverage thresholds raised to 80%
|
|
29
|
+
- Version bumped to 1.0.0
|
|
30
|
+
|
|
31
|
+
## [0.4.0] - 2026-02-06
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
- **Guidelines cross-reference**: `GuidelineMatcher` maps issues to specific App Store Review Guidelines with citations and links
|
|
35
|
+
- **Report generation**: Markdown, HTML, and JSON formatters with score display, severity breakdown, and guideline references
|
|
36
|
+
- **Historical comparison**: `HistoryStore` saves scan results as JSON; `HistoryComparator` diffs between scans showing new/resolved/recurring issues
|
|
37
|
+
- **Custom rule engine**: `RuleLoader` reads `.ios-review-rules.json`; `CustomRuleEngine` evaluates regex-based rules with severity overrides and disable support
|
|
38
|
+
- **Score calculation**: Weighted scoring (error: -10, warning: -3, info: -1) with enriched report output
|
|
39
|
+
|
|
40
|
+
## [0.3.0] - 2026-02-05
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
- **Deprecated API analyzer**: Detects 50+ deprecated iOS APIs including UIWebView, AddressBook, UIAlertView, UIActionSheet, and deprecated UIKit/Foundation methods
|
|
44
|
+
- **Private API analyzer**: Flags undocumented Apple API usage (_UIView, _NS prefixed, dlopen/dlsym, IOKit calls, and known private selectors)
|
|
45
|
+
- **Security analyzer**: ATS exception auditing, weak crypto detection (MD5, SHA1, DES), insecure storage patterns, jailbreak detection code
|
|
46
|
+
- **UI/UX compliance analyzer**: Launch storyboard presence, orientation support, accessibility labels, dynamic type, dark mode assets, minimum touch target hints
|
|
47
|
+
|
|
48
|
+
## [0.2.0] - 2026-02-05
|
|
49
|
+
|
|
50
|
+
### Added
|
|
51
|
+
- **App Store Connect API client**: JWT authentication with auto-refresh, rate limiting with retry, paginated response handling
|
|
52
|
+
- **ASC metadata validator**: App name length, description quality, privacy policy URL, age rating, content rights declaration
|
|
53
|
+
- **ASC screenshots validator**: Screenshot count per device class, dimension validation, missing device coverage
|
|
54
|
+
- **ASC version validator**: Version state checks, build attachment, copyright format, release type
|
|
55
|
+
- **ASC IAP validator**: In-app purchase localization completeness, pricing configuration, review screenshot presence
|
|
56
|
+
|
|
57
|
+
## [0.1.0] - 2026-02-04
|
|
58
|
+
|
|
59
|
+
### Added
|
|
60
|
+
- Initial release as MCP server with 17 tools
|
|
61
|
+
- **Info.plist analyzer**: Required keys (CFBundleIdentifier, CFBundleVersion), privacy usage descriptions, minimum deployment target
|
|
62
|
+
- **Privacy manifest analyzer**: iOS 17+ Required Reason API detection and PrivacyInfo.xcprivacy validation
|
|
63
|
+
- **Entitlements analyzer**: Capability configuration, debug-only entitlements, App Groups/Associated Domains/iCloud format validation
|
|
64
|
+
- **Code scanner**: Hardcoded API keys, debug print statements, force unwraps, TODO/FIXME markers, HTTP URLs
|
|
65
|
+
- **Xcode project parser**: `.xcodeproj` and `.xcworkspace` support, target extraction, build settings, source file discovery
|
|
66
|
+
- **Property list parser**: XML plist and OpenStep (pbxproj) format parsing
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Contributing to iOS App Store Review Plugin
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing! This document provides guidelines and information for contributors.
|
|
4
|
+
|
|
5
|
+
## Development Setup
|
|
6
|
+
|
|
7
|
+
### Prerequisites
|
|
8
|
+
|
|
9
|
+
- Node.js 18+
|
|
10
|
+
- npm or pnpm
|
|
11
|
+
- TypeScript knowledge
|
|
12
|
+
- Familiarity with MCP (Model Context Protocol)
|
|
13
|
+
- macOS recommended (for Xcode project testing)
|
|
14
|
+
|
|
15
|
+
### Getting Started
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Fork and clone the repository
|
|
19
|
+
git clone https://github.com/YOUR_USERNAME/ios-app-review-plugin.git
|
|
20
|
+
cd ios-app-review-plugin
|
|
21
|
+
|
|
22
|
+
# Install dependencies
|
|
23
|
+
npm install
|
|
24
|
+
|
|
25
|
+
# Run in development mode
|
|
26
|
+
npm run dev
|
|
27
|
+
|
|
28
|
+
# Run tests
|
|
29
|
+
npm test
|
|
30
|
+
|
|
31
|
+
# Build for production
|
|
32
|
+
npm run build
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Project Architecture
|
|
36
|
+
|
|
37
|
+
### Core Components
|
|
38
|
+
|
|
39
|
+
1. **MCP Server (`src/index.ts`)**: Entry point that exposes tools to Claude Code
|
|
40
|
+
2. **Analyzers (`src/analyzers/`)**: Individual analysis modules for different checks
|
|
41
|
+
3. **ASC Client (`src/asc/`)**: App Store Connect API integration
|
|
42
|
+
4. **Parsers (`src/parsers/`)**: Xcode project and plist file parsers
|
|
43
|
+
5. **Rules (`src/rules/`)**: App Store Guidelines rule definitions
|
|
44
|
+
|
|
45
|
+
### Adding a New Analyzer
|
|
46
|
+
|
|
47
|
+
1. Create a new file in `src/analyzers/`
|
|
48
|
+
2. Implement the `Analyzer` interface:
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
interface Analyzer {
|
|
52
|
+
name: string;
|
|
53
|
+
description: string;
|
|
54
|
+
analyze(projectPath: string): Promise<AnalysisResult>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
interface AnalysisResult {
|
|
58
|
+
passed: boolean;
|
|
59
|
+
issues: Issue[];
|
|
60
|
+
warnings: Warning[];
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
3. Register the analyzer in `src/analyzers/index.ts`
|
|
65
|
+
4. Add tests in `tests/analyzers/`
|
|
66
|
+
|
|
67
|
+
### Adding New Guidelines
|
|
68
|
+
|
|
69
|
+
Guidelines are defined in `src/rules/guidelines.ts`:
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
const guideline: Guideline = {
|
|
73
|
+
id: "5.1.1",
|
|
74
|
+
title: "Data Collection and Storage",
|
|
75
|
+
description: "Apps that collect user data must have a privacy policy",
|
|
76
|
+
severity: "error",
|
|
77
|
+
check: async (context) => {
|
|
78
|
+
// Implementation
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Code Style
|
|
84
|
+
|
|
85
|
+
- Use TypeScript strict mode
|
|
86
|
+
- Follow ESLint configuration
|
|
87
|
+
- Use meaningful variable and function names
|
|
88
|
+
- Add JSDoc comments for public APIs
|
|
89
|
+
- Keep functions small and focused
|
|
90
|
+
|
|
91
|
+
## Testing
|
|
92
|
+
|
|
93
|
+
### Unit Tests
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
npm test # Run all tests
|
|
97
|
+
npm test -- --watch # Watch mode
|
|
98
|
+
npm test -- --coverage # With coverage
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Test Structure
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
tests/
|
|
105
|
+
├── analyzers/
|
|
106
|
+
│ ├── info-plist.test.ts
|
|
107
|
+
│ └── privacy.test.ts
|
|
108
|
+
├── asc/
|
|
109
|
+
│ └── client.test.ts
|
|
110
|
+
├── fixtures/ # Sample Xcode projects for testing
|
|
111
|
+
│ ├── valid-app/
|
|
112
|
+
│ └── invalid-app/
|
|
113
|
+
└── integration/
|
|
114
|
+
└── full-scan.test.ts
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Adding Fixtures
|
|
118
|
+
|
|
119
|
+
Place sample Xcode projects in `tests/fixtures/`. Include both valid and invalid examples to test detection capabilities.
|
|
120
|
+
|
|
121
|
+
## Pull Request Process
|
|
122
|
+
|
|
123
|
+
1. **Create an issue first** for significant changes
|
|
124
|
+
2. **Fork the repository** and create a feature branch
|
|
125
|
+
3. **Follow the branch naming convention**:
|
|
126
|
+
- `feature/description` for new features
|
|
127
|
+
- `fix/description` for bug fixes
|
|
128
|
+
- `docs/description` for documentation
|
|
129
|
+
4. **Write tests** for new functionality
|
|
130
|
+
5. **Update documentation** as needed
|
|
131
|
+
6. **Submit a PR** with a clear description
|
|
132
|
+
|
|
133
|
+
### PR Checklist
|
|
134
|
+
|
|
135
|
+
- [ ] Tests pass (`npm test`)
|
|
136
|
+
- [ ] Linting passes (`npm run lint`)
|
|
137
|
+
- [ ] Build succeeds (`npm run build`)
|
|
138
|
+
- [ ] Documentation updated
|
|
139
|
+
- [ ] CHANGELOG updated (for significant changes)
|
|
140
|
+
|
|
141
|
+
## Issue Guidelines
|
|
142
|
+
|
|
143
|
+
### Bug Reports
|
|
144
|
+
|
|
145
|
+
Include:
|
|
146
|
+
- iOS/Xcode version
|
|
147
|
+
- Plugin version
|
|
148
|
+
- Steps to reproduce
|
|
149
|
+
- Expected vs. actual behavior
|
|
150
|
+
- Sample project if possible
|
|
151
|
+
|
|
152
|
+
### Feature Requests
|
|
153
|
+
|
|
154
|
+
Include:
|
|
155
|
+
- Use case description
|
|
156
|
+
- Related App Store Guideline (if applicable)
|
|
157
|
+
- Proposed implementation (optional)
|
|
158
|
+
|
|
159
|
+
## Release Process
|
|
160
|
+
|
|
161
|
+
1. Update version in `package.json`
|
|
162
|
+
2. Update CHANGELOG.md
|
|
163
|
+
3. Create a git tag: `git tag v1.0.0`
|
|
164
|
+
4. Push tag: `git push origin v1.0.0`
|
|
165
|
+
5. GitHub Actions will publish to npm
|
|
166
|
+
|
|
167
|
+
## Getting Help
|
|
168
|
+
|
|
169
|
+
- Open an issue for questions
|
|
170
|
+
- Join discussions in GitHub Discussions
|
|
171
|
+
- Check existing issues before creating new ones
|
|
172
|
+
|
|
173
|
+
## License
|
|
174
|
+
|
|
175
|
+
By contributing, you agree that your contributions will be licensed under the MIT License.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ahmetsina
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|