feat: WebSocket client mode for remote DimOS connection #38
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: PR Trigger Reality Sync | |
| on: | |
| issue_comment: | |
| types: [created] | |
| pull_request_target: | |
| types: [synchronize] | |
| jobs: | |
| # Post a helpful message when unauthorized users try to trigger sync | |
| unauthorized-message: | |
| if: | | |
| github.event_name == 'issue_comment' && | |
| github.event.issue.pull_request && | |
| contains(github.event.comment.body, '@rerun-bot reality-sync') && | |
| github.event.comment.user.type != 'Bot' && | |
| github.event.comment.author_association != 'OWNER' && | |
| github.event.comment.author_association != 'MEMBER' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Create GitHub App token | |
| id: app-token | |
| uses: actions/create-github-app-token@v2 | |
| with: | |
| app-id: ${{ vars.SYNC_APP_ID }} | |
| private-key: ${{ secrets.SYNC_APP_PRIVATE_KEY }} | |
| owner: rerun-io | |
| repositories: rerun | |
| - name: Post unauthorized message | |
| env: | |
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | |
| run: | | |
| gh pr comment ${{ github.event.issue.number }} \ | |
| --repo ${{ github.repository }} \ | |
| --body "Sorry, only organization members can trigger reality-sync." | |
| trigger-import: | |
| # For issue_comment: org members (OWNER/MEMBER) can trigger with '@rerun-bot reality-sync' | |
| # For pull_request_target: only auto-sync non-fork PRs (fork PRs require explicit comment trigger) | |
| if: | | |
| ( | |
| github.event_name == 'issue_comment' && | |
| github.event.issue.pull_request && | |
| contains(github.event.comment.body, '@rerun-bot reality-sync') && | |
| github.event.comment.user.type != 'Bot' && | |
| ( | |
| github.event.comment.author_association == 'OWNER' || | |
| github.event.comment.author_association == 'MEMBER' | |
| ) | |
| ) || ( | |
| github.event_name == 'pull_request_target' && | |
| github.event.pull_request.head.repo.full_name == github.repository | |
| ) | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| shell: bash --noprofile --norc -euo pipefail {0} | |
| steps: | |
| - name: Create GitHub App token | |
| id: app-token | |
| uses: actions/create-github-app-token@v2 | |
| with: | |
| app-id: ${{ vars.SYNC_APP_ID }} | |
| private-key: ${{ secrets.SYNC_APP_PRIVATE_KEY }} | |
| owner: rerun-io | |
| repositories: | | |
| reality | |
| rerun | |
| - name: Determine PR number | |
| id: pr-info | |
| run: | | |
| if [ "${{ github.event_name }}" = "issue_comment" ]; then | |
| echo "pr_number=${{ github.event.issue.number }}" >> $GITHUB_OUTPUT | |
| echo "triggered_by=${{ github.event.comment.user.login }}" >> $GITHUB_OUTPUT | |
| echo "trigger_type=comment" >> $GITHUB_OUTPUT | |
| else | |
| echo "pr_number=${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT | |
| echo "triggered_by=${{ github.event.sender.login }}" >> $GITHUB_OUTPUT | |
| echo "trigger_type=push" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Check for existing sync comment (push events only) | |
| if: github.event_name == 'pull_request_target' | |
| id: check-sync-comment | |
| env: | |
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | |
| run: | | |
| PR_NUMBER="${{ steps.pr-info.outputs.pr_number }}" | |
| echo "Checking PR #${PR_NUMBER} for existing sync comment…" | |
| # Look for "Sync complete" comment from the sync bot (GitHub App) | |
| # Check performed_via_github_app.id matches our app to prevent spoofing | |
| SYNC_APP_ID="${{ vars.SYNC_APP_ID }}" | |
| SYNC_COMMENT=$(gh api "repos/${{ github.repository }}/issues/${PR_NUMBER}/comments" \ | |
| | jq -r --arg app_id "$SYNC_APP_ID" '.[] | select((.performed_via_github_app.id | tostring == $app_id) and (.body | contains("Sync complete. Mirror PR in reality:"))) | .id' \ | |
| | head -1) | |
| if [ -n "$SYNC_COMMENT" ]; then | |
| echo "has_sync=true" >> $GITHUB_OUTPUT | |
| echo "✓ Found existing sync comment, will re-sync on push" | |
| else | |
| echo "has_sync=false" >> $GITHUB_OUTPUT | |
| echo "No existing sync comment found, skipping auto-sync" | |
| fi | |
| - name: Get PR details | |
| if: | | |
| github.event_name == 'issue_comment' || | |
| steps.check-sync-comment.outputs.has_sync == 'true' | |
| env: | |
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | |
| run: | | |
| PR_NUMBER="${{ steps.pr-info.outputs.pr_number }}" | |
| echo "Fetching PR details for PR #${PR_NUMBER}…" | |
| gh pr view "$PR_NUMBER" \ | |
| --repo ${{ github.repository }} \ | |
| --json headRefName,headRepositoryOwner,headRepository,number,title,body,labels \ | |
| > /tmp/pr_data.json | |
| echo "PR data:" | |
| jq '.' /tmp/pr_data.json | |
| - name: Trigger reality sync workflow | |
| if: | | |
| github.event_name == 'issue_comment' || | |
| steps.check-sync-comment.outputs.has_sync == 'true' | |
| env: | |
| GH_TOKEN: ${{ steps.app-token.outputs.token }} | |
| run: | | |
| echo "================================================" | |
| echo "Triggering repository_dispatch to reality repo" | |
| echo "Trigger type: ${{ steps.pr-info.outputs.trigger_type }}" | |
| echo "================================================" | |
| # Construct the entire payload using jq to avoid shell substitution | |
| # This ensures backticks and other special characters in title/body are handled safely | |
| jq -n \ | |
| --arg repo "${{ github.event.repository.name }}" \ | |
| --arg current_repo "${{ github.repository }}" \ | |
| --arg triggered_by "${{ steps.pr-info.outputs.triggered_by }}" \ | |
| --slurpfile pr_data /tmp/pr_data.json \ | |
| '{ | |
| event_type: "sync-import-pr", | |
| client_payload: { | |
| repo: $repo, | |
| pr_number: $pr_data[0].number, | |
| head_ref: $pr_data[0].headRefName, | |
| head_owner: $pr_data[0].headRepositoryOwner.login, | |
| head_repo: $pr_data[0].headRepository.name, | |
| title: $pr_data[0].title, | |
| body: ($pr_data[0].body // ""), | |
| labels: $pr_data[0].labels, | |
| is_fork: (("\($pr_data[0].headRepositoryOwner.login)/\($pr_data[0].headRepository.name)") != $current_repo), | |
| triggered_by: $triggered_by | |
| } | |
| }' > /tmp/dispatch_payload.json | |
| echo "Dispatch payload:" | |
| jq '.' /tmp/dispatch_payload.json | |
| # Make the API call with the JSON payload | |
| if gh api repos/rerun-io/reality/dispatches --input /tmp/dispatch_payload.json 2>&1; then | |
| echo "✓ Successfully dispatched sync-import-pr event to reality repo" | |
| echo "Note: repository_dispatch returns 204 No Content on success" | |
| echo "The reality repo should now be processing the import workflow" | |
| else | |
| echo "::error::Failed to dispatch repository_dispatch event to reality repo" | |
| echo "::error::This could be due to:" | |
| echo "::error:: 1. Insufficient permissions on the GitHub App token" | |
| echo "::error:: 2. Reality repo not found or not accessible" | |
| echo "::error:: 3. Network issues" | |
| exit 1 | |
| fi |