chore: sync upstream PR #7831 - fix(ios): fix URL resolution when external frameworks are loaded #29
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Auto-merge Upstream Sync PRs | |
| on: | |
| pull_request: | |
| types: | |
| - opened | |
| - synchronize | |
| - reopened | |
| workflow_run: | |
| workflows: ["CI"] | |
| types: | |
| - completed | |
| jobs: | |
| claude-review: | |
| runs-on: ubuntu-latest | |
| # Only run for upstream-sync labeled PRs after CI passes | |
| if: | | |
| (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') || | |
| github.event_name == 'pull_request' | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| outputs: | |
| should_merge: ${{ steps.claude-review.outputs.should_merge }} | |
| pr_number: ${{ steps.check-label.outputs.pr_number }} | |
| review_category: ${{ steps.claude-review.outputs.review_category }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| with: | |
| fetch-depth: 0 | |
| - name: Check if PR is from upstream sync | |
| id: check-label | |
| env: | |
| GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |
| run: | | |
| # Get PR number from different event types | |
| if [ "${{ github.event_name }}" == "workflow_run" ]; then | |
| # Find PRs associated with this workflow run | |
| PR_NUMBER=$(gh pr list --state open --label "upstream-sync" --json number -q '.[0].number') | |
| else | |
| PR_NUMBER=${{ github.event.pull_request.number }} | |
| fi | |
| if [ -z "$PR_NUMBER" ]; then | |
| echo "No PR found" | |
| echo "is_sync_pr=false" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT | |
| # Check if PR has upstream-sync label | |
| LABELS=$(gh pr view $PR_NUMBER --json labels -q '.labels[].name') | |
| if echo "$LABELS" | grep -q "upstream-sync"; then | |
| echo "PR has upstream-sync label" | |
| echo "is_sync_pr=true" >> $GITHUB_OUTPUT | |
| else | |
| echo "PR does not have upstream-sync label" | |
| echo "is_sync_pr=false" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Check all CI status | |
| if: steps.check-label.outputs.is_sync_pr == 'true' | |
| id: ci-status | |
| env: | |
| GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |
| PR_NUMBER: ${{ steps.check-label.outputs.pr_number }} | |
| run: | | |
| # Get the status of all checks | |
| CHECKS=$(gh pr checks $PR_NUMBER --json name,state,conclusion 2>/dev/null || echo "[]") | |
| echo "Current checks status:" | |
| echo "$CHECKS" | jq -r '.[] | "\(.name): \(.state) - \(.conclusion)"' 2>/dev/null || true | |
| # Check if any checks are still pending | |
| PENDING=$(echo "$CHECKS" | jq '[.[] | select(.state == "pending" or .state == "queued")] | length' 2>/dev/null || echo "0") | |
| if [ "$PENDING" -gt 0 ]; then | |
| echo "Some checks are still pending" | |
| echo "all_passed=false" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| # Check if any checks failed (excluding this workflow) | |
| FAILED=$(echo "$CHECKS" | jq '[.[] | select((.conclusion == "failure" or .conclusion == "cancelled") and .name != "claude-review")] | length' 2>/dev/null || echo "0") | |
| if [ "$FAILED" -gt 0 ]; then | |
| echo "Some checks failed" | |
| echo "all_passed=false" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| echo "All checks passed!" | |
| echo "all_passed=true" >> $GITHUB_OUTPUT | |
| - name: Get PR diff for Claude review | |
| if: steps.check-label.outputs.is_sync_pr == 'true' && steps.ci-status.outputs.all_passed == 'true' | |
| id: get-diff | |
| env: | |
| GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |
| PR_NUMBER: ${{ steps.check-label.outputs.pr_number }} | |
| run: | | |
| # Get the PR diff | |
| gh pr diff $PR_NUMBER > /tmp/pr_diff.txt | |
| # Get PR details | |
| gh pr view $PR_NUMBER --json title,body,commits > /tmp/pr_details.json | |
| echo "PR diff saved to /tmp/pr_diff.txt" | |
| echo "diff_ready=true" >> $GITHUB_OUTPUT | |
| - name: Setup Node.js | |
| if: steps.get-diff.outputs.diff_ready == 'true' | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Install Claude Code | |
| if: steps.get-diff.outputs.diff_ready == 'true' | |
| run: npm install -g @anthropic-ai/claude-code | |
| - name: Claude Code Comprehensive Review | |
| if: steps.get-diff.outputs.diff_ready == 'true' | |
| id: claude-review | |
| env: | |
| ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} | |
| PR_NUMBER: ${{ steps.check-label.outputs.pr_number }} | |
| run: | | |
| # Create comprehensive review prompt | |
| cat > /tmp/review_prompt.txt << 'PROMPT_EOF' | |
| You are a security-focused code reviewer for Capacitor+, a cross-platform mobile app framework. | |
| Your job is to thoroughly analyze this upstream sync PR for ANY issues that could harm users. | |
| ## CRITICAL: Check for these categories of issues | |
| ### 1. SECURITY VULNERABILITIES | |
| - Command injection (shell commands with user input) | |
| - SQL injection | |
| - XSS (Cross-site scripting) | |
| - Path traversal attacks | |
| - Insecure deserialization | |
| - Hardcoded secrets, API keys, or credentials | |
| - Insecure cryptographic practices | |
| - Missing input validation/sanitization | |
| - Insecure file operations | |
| - Privilege escalation possibilities | |
| - Unsafe use of eval(), Function(), or similar | |
| - CORS misconfigurations | |
| - Insecure network requests (HTTP instead of HTTPS) | |
| - Memory safety issues (buffer overflows in native code) | |
| ### 2. BREAKING CHANGES | |
| - Removed or renamed public APIs (functions, classes, interfaces, types) | |
| - Changed function signatures (parameters added/removed/reordered, return type changes) | |
| - Removed or renamed exported constants/enums | |
| - Changes to configuration file formats | |
| - Minimum version requirement changes (Node.js, iOS, Android SDK, etc.) | |
| - Behavioral changes that would break existing code | |
| ### 3. STABILITY & CRASH RISKS | |
| - Null pointer dereferences | |
| - Unhandled exceptions that could crash the app | |
| - Race conditions | |
| - Deadlocks | |
| - Memory leaks | |
| - Infinite loops | |
| - Resource exhaustion | |
| - Missing error handling for critical operations | |
| - Unsafe force unwrapping (Swift) or non-null assertions | |
| - Array/index out of bounds access | |
| ### 4. DATA INTEGRITY & PRIVACY | |
| - Data loss scenarios | |
| - Unintended data exposure | |
| - Privacy violations (logging sensitive data, etc.) | |
| - Insecure data storage | |
| - Missing data validation | |
| ### 5. MALICIOUS CODE PATTERNS | |
| - Obfuscated code | |
| - Suspicious network calls to unknown domains | |
| - Cryptocurrency mining | |
| - Data exfiltration | |
| - Backdoors | |
| - Unexpected permission requests | |
| ## SAFE changes (OK to auto-merge): | |
| - Bug fixes that don't change public API | |
| - New features (additions only, no removals) | |
| - Documentation updates | |
| - Internal refactoring that doesn't affect public API | |
| - Performance improvements | |
| - Dev dependency updates (unless they introduce vulnerabilities) | |
| - Test changes | |
| - Typo fixes | |
| - Code style/formatting changes | |
| ## Your Response | |
| After careful analysis, respond with EXACTLY ONE of these formats: | |
| If ALL checks pass and the code is safe: | |
| SAFE_TO_MERGE | |
| If ANY issues are found, respond with the category and description: | |
| SECURITY_ISSUE: <brief description> | |
| BREAKING_CHANGE: <brief description> | |
| CRASH_RISK: <brief description> | |
| DATA_RISK: <brief description> | |
| MALICIOUS_CODE: <brief description> | |
| Be thorough but practical. Minor issues that don't pose real risks should not block the merge. | |
| Focus on actual vulnerabilities, not theoretical edge cases. | |
| Do not include any other text in your response besides the verdict line. | |
| PR Details: | |
| PROMPT_EOF | |
| cat /tmp/pr_details.json >> /tmp/review_prompt.txt | |
| echo -e "\n\nDiff to review:\n" >> /tmp/review_prompt.txt | |
| # Limit diff size to avoid token limits | |
| head -c 100000 /tmp/pr_diff.txt >> /tmp/review_prompt.txt | |
| # Run Claude Code review | |
| REVIEW_RESULT=$(claude -p "$(cat /tmp/review_prompt.txt)" --output-format text 2>&1) || { | |
| echo "Claude review failed, defaulting to manual review required" | |
| echo "should_merge=false" >> $GITHUB_OUTPUT | |
| echo "review_result=REVIEW_FAILED: Claude Code analysis could not complete" >> $GITHUB_OUTPUT | |
| echo "review_category=error" >> $GITHUB_OUTPUT | |
| exit 0 | |
| } | |
| echo "Claude Review Result: $REVIEW_RESULT" | |
| # Parse the result and determine category | |
| if echo "$REVIEW_RESULT" | grep -q "^SAFE_TO_MERGE"; then | |
| echo "Claude approved: All security and stability checks passed" | |
| echo "should_merge=true" >> $GITHUB_OUTPUT | |
| echo "review_result=SAFE_TO_MERGE" >> $GITHUB_OUTPUT | |
| echo "review_category=safe" >> $GITHUB_OUTPUT | |
| elif echo "$REVIEW_RESULT" | grep -q "^SECURITY_ISSUE"; then | |
| echo "BLOCKED: Security vulnerability detected" | |
| echo "should_merge=false" >> $GITHUB_OUTPUT | |
| echo "review_result=$REVIEW_RESULT" >> $GITHUB_OUTPUT | |
| echo "review_category=security" >> $GITHUB_OUTPUT | |
| elif echo "$REVIEW_RESULT" | grep -q "^BREAKING_CHANGE"; then | |
| echo "BLOCKED: Breaking change detected" | |
| echo "should_merge=false" >> $GITHUB_OUTPUT | |
| echo "review_result=$REVIEW_RESULT" >> $GITHUB_OUTPUT | |
| echo "review_category=breaking" >> $GITHUB_OUTPUT | |
| elif echo "$REVIEW_RESULT" | grep -q "^CRASH_RISK"; then | |
| echo "BLOCKED: Potential crash/stability issue detected" | |
| echo "should_merge=false" >> $GITHUB_OUTPUT | |
| echo "review_result=$REVIEW_RESULT" >> $GITHUB_OUTPUT | |
| echo "review_category=stability" >> $GITHUB_OUTPUT | |
| elif echo "$REVIEW_RESULT" | grep -q "^DATA_RISK"; then | |
| echo "BLOCKED: Data integrity/privacy risk detected" | |
| echo "should_merge=false" >> $GITHUB_OUTPUT | |
| echo "review_result=$REVIEW_RESULT" >> $GITHUB_OUTPUT | |
| echo "review_category=data" >> $GITHUB_OUTPUT | |
| elif echo "$REVIEW_RESULT" | grep -q "^MALICIOUS_CODE"; then | |
| echo "BLOCKED: Potentially malicious code detected" | |
| echo "should_merge=false" >> $GITHUB_OUTPUT | |
| echo "review_result=$REVIEW_RESULT" >> $GITHUB_OUTPUT | |
| echo "review_category=malicious" >> $GITHUB_OUTPUT | |
| else | |
| echo "Unexpected response format, requiring manual review" | |
| echo "should_merge=false" >> $GITHUB_OUTPUT | |
| echo "review_result=MANUAL_REVIEW_REQUIRED: $REVIEW_RESULT" >> $GITHUB_OUTPUT | |
| echo "review_category=unknown" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Comment on PR with review result | |
| if: steps.claude-review.outputs.review_result != '' | |
| env: | |
| GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |
| PR_NUMBER: ${{ steps.check-label.outputs.pr_number }} | |
| REVIEW_RESULT: ${{ steps.claude-review.outputs.review_result }} | |
| REVIEW_CATEGORY: ${{ steps.claude-review.outputs.review_category }} | |
| SHOULD_MERGE: ${{ steps.claude-review.outputs.should_merge }} | |
| run: | | |
| if [ "$SHOULD_MERGE" == "true" ]; then | |
| COMMENT=$(cat <<'EOF' | |
| ## ✅ Claude Code Review: Approved | |
| **Security Check:** ✅ Passed | |
| **Breaking Changes:** ✅ None detected | |
| **Stability Check:** ✅ Passed | |
| **Data Safety:** ✅ Passed | |
| **Malicious Code:** ✅ None detected | |
| This PR will be automatically merged. | |
| --- | |
| *Comprehensive security review by Claude Code* | |
| EOF | |
| ) | |
| else | |
| case "$REVIEW_CATEGORY" in | |
| security) | |
| ICON="🔴" | |
| TITLE="Security Issue Detected" | |
| URGENCY="**URGENT:** This PR contains potential security vulnerabilities and must NOT be merged without careful review." | |
| ;; | |
| breaking) | |
| ICON="🟠" | |
| TITLE="Breaking Change Detected" | |
| URGENCY="This PR contains breaking changes that may affect existing users." | |
| ;; | |
| stability) | |
| ICON="🟡" | |
| TITLE="Stability Risk Detected" | |
| URGENCY="This PR contains code that may cause crashes or stability issues." | |
| ;; | |
| data) | |
| ICON="🟣" | |
| TITLE="Data/Privacy Risk Detected" | |
| URGENCY="This PR contains changes that may affect data integrity or user privacy." | |
| ;; | |
| malicious) | |
| ICON="⛔" | |
| TITLE="Potentially Malicious Code Detected" | |
| URGENCY="**CRITICAL:** This PR contains suspicious code patterns. Do NOT merge without thorough investigation." | |
| ;; | |
| *) | |
| ICON="⚪" | |
| TITLE="Manual Review Required" | |
| URGENCY="This PR requires manual review before merging." | |
| ;; | |
| esac | |
| COMMENT=$(cat <<EOF | |
| ## $ICON Claude Code Review: $TITLE | |
| **Finding:** $REVIEW_RESULT | |
| $URGENCY | |
| ### Review Checklist | |
| - [ ] Reviewed the flagged changes | |
| - [ ] Verified the concern is addressed or is a false positive | |
| - [ ] Tested the changes locally if applicable | |
| --- | |
| *Comprehensive security review by Claude Code* | |
| EOF | |
| ) | |
| fi | |
| gh pr comment $PR_NUMBER --body "$COMMENT" | |
| auto-merge: | |
| runs-on: ubuntu-latest | |
| needs: claude-review | |
| if: needs.claude-review.outputs.should_merge == 'true' | |
| permissions: | |
| contents: write | |
| pull-requests: write | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v5 | |
| - name: Auto-merge PR | |
| env: | |
| GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |
| PR_NUMBER: ${{ needs.claude-review.outputs.pr_number }} | |
| run: | | |
| echo "Claude approved. Merging PR #$PR_NUMBER..." | |
| gh pr merge $PR_NUMBER \ | |
| --squash \ | |
| --auto \ | |
| --delete-branch \ | |
| --body "Auto-merged after CI passed and Claude Code review approved (no breaking changes)" | |
| echo "PR #$PR_NUMBER has been merged!" | |
| - name: Trigger release workflow | |
| env: | |
| GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |
| run: | | |
| # Wait a moment for merge to complete | |
| sleep 10 | |
| # Trigger the release workflow after merge | |
| gh workflow run publish-capacitor-plus.yml --ref plus | |
| notify-issues: | |
| runs-on: ubuntu-latest | |
| needs: claude-review | |
| if: needs.claude-review.outputs.should_merge == 'false' && needs.claude-review.outputs.pr_number != '' | |
| steps: | |
| - name: Create issue for review | |
| env: | |
| GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |
| PR_NUMBER: ${{ needs.claude-review.outputs.pr_number }} | |
| REVIEW_CATEGORY: ${{ needs.claude-review.outputs.review_category }} | |
| run: | | |
| # Determine labels and priority based on category | |
| case "$REVIEW_CATEGORY" in | |
| security) | |
| LABELS="upstream-sync,needs-attention,security,priority-critical" | |
| TITLE="🔴 SECURITY: Manual review required for PR #$PR_NUMBER" | |
| PRIORITY="**Priority: CRITICAL**" | |
| ;; | |
| malicious) | |
| LABELS="upstream-sync,needs-attention,security,priority-critical,suspicious" | |
| TITLE="⛔ CRITICAL: Suspicious code in PR #$PR_NUMBER" | |
| PRIORITY="**Priority: CRITICAL - DO NOT MERGE WITHOUT INVESTIGATION**" | |
| ;; | |
| breaking) | |
| LABELS="upstream-sync,needs-attention,breaking-change,priority-high" | |
| TITLE="🟠 Breaking change in PR #$PR_NUMBER" | |
| PRIORITY="**Priority: High**" | |
| ;; | |
| stability) | |
| LABELS="upstream-sync,needs-attention,stability,priority-high" | |
| TITLE="🟡 Stability risk in PR #$PR_NUMBER" | |
| PRIORITY="**Priority: High**" | |
| ;; | |
| data) | |
| LABELS="upstream-sync,needs-attention,data-privacy,priority-high" | |
| TITLE="🟣 Data/Privacy concern in PR #$PR_NUMBER" | |
| PRIORITY="**Priority: High**" | |
| ;; | |
| *) | |
| LABELS="upstream-sync,needs-attention" | |
| TITLE="Manual review required for PR #$PR_NUMBER" | |
| PRIORITY="**Priority: Normal**" | |
| ;; | |
| esac | |
| BODY=$(cat <<EOF | |
| ## Claude Code Review Alert | |
| $PRIORITY | |
| Claude Code's comprehensive review flagged potential issues in upstream sync PR #$PR_NUMBER. | |
| **Category:** $REVIEW_CATEGORY | |
| ### Action Required | |
| 1. Review the PR carefully: https://github.com/${{ github.repository }}/pull/$PR_NUMBER | |
| 2. Check Claude's detailed comment on the PR | |
| 3. Verify the flagged concerns | |
| 4. Merge manually if the concerns are addressed or false positives | |
| ### Review Areas | |
| - [ ] Security implications | |
| - [ ] Breaking changes for existing users | |
| - [ ] Stability and crash risks | |
| - [ ] Data integrity and privacy | |
| - [ ] Code authenticity | |
| --- | |
| *This issue was automatically created by the Capacitor+ security review pipeline* | |
| EOF | |
| ) | |
| gh issue create \ | |
| --repo ${{ github.repository }} \ | |
| --title "$TITLE" \ | |
| --body "$BODY" \ | |
| --label "$LABELS" |