Skip to content

chore: Add PR update preview#86

Open
thierryskoda wants to merge 7 commits intomainfrom
ts/pr-updates
Open

chore: Add PR update preview#86
thierryskoda wants to merge 7 commits intomainfrom
ts/pr-updates

Conversation

@thierryskoda
Copy link
Copy Markdown
Contributor

@thierryskoda thierryskoda commented Jun 7, 2025

Add PR update preview functionality by implementing GitHub Actions workflow for EAS updates and configuring application for preview builds

📍Where to Start

Start with the GitHub Actions workflow in .github/workflows/pr-preview.yml to understand the PR preview automation, then review the configuration changes in app.config.ts.


Macroscope summarized 20efa82.

Summary by CodeRabbit

  • New Features

    • Added an "Updates Menu" to the debug menu, offering update-related actions such as viewing update info, switching to a PR branch (in preview), and checking for updates.
    • Introduced a GitHub Actions workflow to automatically create preview updates or full builds for pull requests based on runtime compatibility.
    • Added a runtime compatibility check script to support automated update or build decisions.
    • Added configuration to control anti-bricking measures per environment.
  • Improvements

    • Animation for new messages is now shown only for messages that are both the newest and still sending.
    • Update runtime version policy changed to use "fingerprint" for improved consistency.
  • Refactor

    • Streamlined logic for determining when to synchronize and merge message data in conversation queries.
  • Chores

    • Disabled preloading of recent conversations to optimize performance.

@thierryskoda thierryskoda requested a review from a team as a code owner June 7, 2025 14:03
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jun 7, 2025

Walkthrough

The updates introduce a new GitHub Actions workflow for PR preview updates that conditionally creates lightweight EAS updates or full builds based on runtime compatibility. They extend environment configuration with update-related options, add an "Updates Menu" to the debug menu for managing updates, refine animation and query logic in conversation features, comment out a conversation preloading hook, add native fingerprinting ignore rules and configuration, add a runtime compatibility check script, and rename several plugin functions from arrow to named functions.

Changes

File(s) Change Summary
.github/workflows/pr-preview.yml Added a new GitHub Actions workflow triggered on pull requests to check runtime compatibility and conditionally create EAS preview updates or full builds with detailed PR comments and caching.
app.config.ts Extended EnvironmentConfig with an updates property including disableAntiBrickingMeasures; set to true for development and preview, false for production; changed runtimeVersion.policy from "nativeVersion" to "fingerprint".
components/debug-menu.tsx Added an "Updates Menu" submenu in the debug menu with options to display update info, list branches, override PR branch (preview only), reset branch override, check for updates, and cancel; includes input validation, error handling, alerts, and toast notifications.
features/conversation/conversation-chat/conversation-messages.query.ts Introduced isFirstPage boolean to centralize logic controlling synchronization and cache merging, replacing previous cursor-based conditions.
features/conversation/conversation-chat/conversation-messages.tsx Refined animation trigger to only animate newest messages from the current sender that are still in "sending" status.
features/conversation/conversation-list/conversation-list.screen.tsx Commented out the invocation and implementation of the usePreloadRecentConversations hook, disabling conversation screen preloading functionality.
.fingerprintignore Added a new .fingerprintignore file specifying files and directories to exclude from native compatibility fingerprinting, including dev/build artifacts, logs, tests, docs, and most GitHub workflows except the PR preview workflow.
fingerprint.config.js Added new Expo fingerprinting tool configuration exporting a config object that customizes ignored files, concurrency, hash algorithm, and sources to skip during fingerprinting.
package.json Added @expo/fingerprint as a new devDependency with version ^0.12.4.
plugins/notification-service-extension/plugin/src/with-my-plugin-ios.ts Changed several ConfigPlugin functions from arrow functions to named function expressions without altering logic or behavior.
plugins/notification-service-extension/plugin/src/with-my-plugin.ts Changed export of withMyPluginTwo from an arrow function to a named function expression without altering functionality.
scripts/check-runtime-compatibility.js Added a new Node.js script to check runtime compatibility by comparing current fingerprint with latest preview build runtime version via EAS CLI, outputting compatibility status and setting GitHub Actions outputs accordingly.

Sequence Diagram(s)

sequenceDiagram
    participant Developer
    participant GitHub
    participant GitHub Actions
    participant Expo EAS
    participant PR Preview Channel

    Developer->>GitHub: Open/Synchronize/Reopen PR
    GitHub->>GitHub Actions: Trigger PR Preview workflow
    GitHub Actions->>GitHub Actions: Checkout code, setup Node.js & Yarn
    GitHub Actions->>GitHub Actions: Install dependencies, build plugin
    GitHub Actions->>Expo EAS: Setup EAS CLI
    GitHub Actions->>scripts/check-runtime-compatibility.js: Run compatibility check
    alt Compatible (JS-only changes)
        GitHub Actions->>Expo EAS: Create preview update (PR branch)
        Expo EAS->>PR Preview Channel: Publish update
        GitHub Actions->>GitHub: Comment PR with update info
    else Incompatible (native changes)
        GitHub Actions->>Expo EAS: Trigger full EAS build (iOS preview profile)
        Expo EAS->>GitHub Actions: Build progress and completion notifications
        GitHub Actions->>GitHub: Post multiple PR comments with build status and instructions
    end
    GitHub Actions->>Developer: PR preview update or build available
Loading

Suggested reviewers

  • nplasterer

Poem

🐰 In code’s green fields I hop and play,
PR previews light the way.
Updates menu, swift and bright,
Fingerprints guard through day and night.
Conversations dance with grace,
Preloads paused, a gentler pace.
With every change, I leap, hooray! 🌿✨

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
features/conversation/conversation-list/conversation-list.screen.tsx (1)

198-228: Consider removing commented code if permanently disabled.

If the usePreloadRecentConversations hook is permanently disabled, consider removing the commented implementation to keep the codebase clean. If it's temporarily disabled for debugging, consider adding a TODO comment explaining when it should be re-enabled.

Apply this change if permanently removing:

-// function usePreloadRecentConversations(args: { conversationsIds: IXmtpConversationId[] }) {
-//   const { conversationsIds } = args
-//   const router = useRouter()
-//   const currentSender = useSafeCurrentSender()
-//   const preloadedConversationsRef = useRef(new Set<IXmtpConversationId>())
-
-//   useEffectAfterInteractions(() => {
-//     if (conversationsIds) {
-//       conversationsIds.forEach((conversationId) => {
-//         // Skip if already preloaded
-//         if (preloadedConversationsRef.current.has(conversationId)) {
-//           return
-//         }
-
-//         const conversation = getConversationQueryData({
-//           clientInboxId: currentSender.inboxId,
-//           xmtpConversationId: conversationId,
-//         })
-
-//         if (conversation) {
-//           router.preload("Conversation", {
-//             xmtpConversationId: conversation.xmtpId,
-//           })
-
-//           // Mark as preloaded
-//           preloadedConversationsRef.current.add(conversationId)
-//         }
-//       })
-//     }
-//   }, [conversationsIds])
-// }
components/debug-menu.tsx (1)

1123-1338: Well-implemented updates menu with good error handling.

The new showUpdatesMenu function provides comprehensive update management functionality with proper error handling and user feedback. The environment-specific features (PR branch switching for preview only) are well-designed.

However, consider the following improvements:

Suggestion: Extract hardcoded update URL to configuration

The update URL "https://u.expo.dev/f9089dfa-8871-4aff-93ea-da08af0370d2" appears multiple times (lines 1193, 1232). Consider extracting this to a configuration constant for better maintainability.

+ const UPDATE_URL = "https://u.expo.dev/f9089dfa-8871-4aff-93ea-da08af0370d2"

- updateUrl: "https://u.expo.dev/f9089dfa-8871-4aff-93ea-da08af0370d2",
+ updateUrl: UPDATE_URL,

Note: Verify PR number validation

The PR number validation on line 1186 checks for isNaN(Number(prNumber)) but doesn't validate if it's a positive integer. Consider adding additional validation to ensure the PR number is a valid positive integer.

.github/workflows/pr-preview.yml (1)

1-48: Well-structured GitHub Actions workflow following best practices.

The workflow is properly configured with:

  • Appropriate trigger events for PR previews
  • Correct permissions (read contents, write pull-requests)
  • Proper Node.js setup with caching from .nvmrc
  • Secure use of repository secrets for EXPO_TOKEN
  • Environment-specific configuration with EXPO_ENV: preview

Minor suggestion: Consider adding workflow timeout

For better resource management, consider adding a timeout to prevent workflows from running indefinitely:

jobs:
  create-update:
    name: Create EAS Update
    runs-on: ubuntu-latest
+   timeout-minutes: 15
    permissions:
      contents: read
      pull-requests: write

Verify EAS update command compatibility

The command eas update --channel=preview --branch=pr-${{ github.event.number }} creates PR-specific branches. Ensure this aligns with your EAS project configuration and that the preview channel exists.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5f794be and 20efa82.

📒 Files selected for processing (6)
  • .github/workflows/pr-preview.yml (1 hunks)
  • app.config.ts (5 hunks)
  • components/debug-menu.tsx (2 hunks)
  • features/conversation/conversation-chat/conversation-messages.query.ts (3 hunks)
  • features/conversation/conversation-chat/conversation-messages.tsx (1 hunks)
  • features/conversation/conversation-list/conversation-list.screen.tsx (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
features/conversation/conversation-chat/conversation-messages.query.ts (1)
features/xmtp/xmtp-conversations/xmtp-conversations-sync.ts (1)
  • syncOneXmtpConversation (89-104)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: test
  • GitHub Check: Code Review
  • GitHub Check: Create EAS Update
🔇 Additional comments (9)
app.config.ts (3)

29-31: Well-structured configuration extension.

The addition of the updates configuration object to the EnvironmentConfig type is clean and follows the existing pattern.


77-79: Environment-specific update configurations are well-designed.

The configuration values are appropriate for each environment:

  • Development and preview enable disableAntiBrickingMeasures for easier testing
  • Production keeps it disabled with a clear safety comment

The comment on line 142 is particularly valuable for preventing accidental production misconfigurations.

Also applies to: 109-111, 141-144


163-163: Runtime version policy change aligns with update workflow.

Changing from "nativeVersion" to "fingerprint" is appropriate for the new update system, as fingerprint-based versioning provides more granular control over update delivery.

features/conversation/conversation-chat/conversation-messages.tsx (1)

576-580: Improved animation condition for better UX.

The refinement to only animate messages with status === "sending" is excellent. This ensures animations only trigger for messages actively being sent, providing more accurate visual feedback and preventing unnecessary animations for already-sent messages.

features/conversation/conversation-chat/conversation-messages.query.ts (3)

77-77: Good introduction of semantic variable.

The isFirstPage variable clearly expresses the intent and will be used consistently throughout the function.


89-95: Cleaner synchronization logic.

Using isFirstPage instead of the direct cursor check improves readability and ensures consistent first-page detection throughout the function.


124-124: Consistent cache merging condition.

The refactoring maintains the same logic while improving code clarity by using the semantic isFirstPage variable.

features/conversation/conversation-list/conversation-list.screen.tsx (1)

51-51: Clarify the reason for disabling conversation preloading.

The preloading functionality has been commented out. Could you provide context on:

  • Is this a temporary or permanent change?
  • What impact analysis was done on user experience?
  • Are there performance issues with the current preloading implementation?

The preloading hook was designed to improve navigation performance by preloading conversation screens. Understanding the rationale will help assess if alternative optimizations are needed.

components/debug-menu.tsx (1)

1427-1438: Correct integration of the Updates Menu.

The new "Updates Menu" is properly integrated into the primaryMethods object and the dependency array is correctly updated to include showUpdatesMenu.

@macroscopeapp
Copy link
Copy Markdown

macroscopeapp bot commented Jun 7, 2025

Add PR update preview system with automated GitHub Actions workflow for creating EAS updates or builds based on runtime version fingerprint compatibility

Implements an automated PR preview system that uses runtime version fingerprints to determine whether pull request changes require a new native build or can be delivered as an over-the-air update. The system includes:

  • GitHub Actions workflow in .github/workflows/pr-preview.yml that automatically creates EAS updates for JavaScript-only changes or triggers new builds for native changes
  • Runtime compatibility checking script in scripts/check-runtime-compatibility.js that compares fingerprints between the current PR and latest preview build
  • Fingerprint configuration files .fingerprintignore and fingerprint.config.js that define which files affect native compatibility
  • App configuration changes in app.config.ts switching from nativeVersion to fingerprint runtime version policy and adding anti-bricking measure controls
  • Debug menu updates in components/debug-menu.tsx adding an updates management interface with PR branch switching capabilities
  • Performance optimizations in conversation message loading to reduce unnecessary sync operations

📍Where to Start

Start with the GitHub Actions workflow in .github/workflows/pr-preview.yml to understand the overall PR preview automation process, then examine the runtime compatibility checking logic in scripts/check-runtime-compatibility.js.


Macroscope summarized fd26376.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (3)
scripts/check-runtime-compatibility.js (1)

118-143: Consider extracting legacy version check into a separate function.

The legacy version handling logic is nested and makes the main function harder to read. Extracting it would improve maintainability.

Consider applying this refactor:

+/**
+ * Checks if current app version matches legacy runtime version format
+ */
+function checkLegacyVersionCompatibility(previewRuntimeVersion) {
+  if (!previewRuntimeVersion.match(/^\d+\.\d+\.\d+$/)) {
+    return false
+  }
+
+  console.log("\n⚠️  Preview build uses old runtime version format")
+  
+  const configOutput = execCommand("EXPO_ENV=preview npx expo config --json")
+  if (configOutput) {
+    try {
+      const config = JSON.parse(configOutput)
+      const appVersion = config.version
+      return appVersion === previewRuntimeVersion
+    } catch (error) {
+      console.error("Failed to parse expo config:", error.message)
+    }
+  }
+  return false
+}

   // Check if preview build uses old version format (like "1.0.1")
   // and current app version matches
-  if (previewRuntimeVersion.match(/^\d+\.\d+\.\d+$/)) {
-    console.log("\n⚠️  Preview build uses old runtime version format")
-
-    // Get current app version
-    const configOutput = execCommand("EXPO_ENV=preview npx expo config --json")
-    if (configOutput) {
-      try {
-        const config = JSON.parse(configOutput)
-        const appVersion = config.version
-
-        if (appVersion === previewRuntimeVersion) {
-          console.log(`✅ App version (${appVersion}) matches build runtime version`)
-          console.log("can_create_update=true")
-          console.log(
-            "\n💡 Consider creating a new preview build with fingerprint policy for better compatibility detection",
-          )
-          setGitHubOutput("can_create_update", "true")
-          setGitHubOutput("current_fingerprint", currentFingerprint)
-          setGitHubOutput("preview_fingerprint", previewRuntimeVersion)
-          process.exit(0)
-        }
-      } catch (error) {
-        console.error("Failed to parse expo config:", error.message)
-      }
-    }
+  if (checkLegacyVersionCompatibility(previewRuntimeVersion)) {
+    console.log(`✅ App version matches build runtime version`)
+    console.log("can_create_update=true")
+    console.log(
+      "\n💡 Consider creating a new preview build with fingerprint policy for better compatibility detection",
+    )
+    setGitHubOutput("can_create_update", "true")
+    setGitHubOutput("current_fingerprint", currentFingerprint)
+    setGitHubOutput("preview_fingerprint", previewRuntimeVersion)
+    process.exit(0)
   }
.github/workflows/pr-preview.yml (2)

168-232: Fix formatting: Remove trailing spaces.

Multiple lines in the PR comment templates have trailing spaces which violate YAML formatting standards.

Remove trailing spaces from the following lines: 168, 170, 174, 179, 184, 198, 200, 205, 207, 221, 223, 227, 232.

-              🔨 **Native Changes Detected - Creating New Build**
-              
+              🔨 **Native Changes Detected - Creating New Build**
+
               This PR contains native changes that require a new build. A preview build is being created now.
-              
+
               **Runtime Versions:**
               - PR Fingerprint: \`${{ needs.check-compatibility.outputs.current_fingerprint }}\`
               - Latest preview Build: \`${{ needs.check-compatibility.outputs.preview_fingerprint }}\`
-              
+
               **What's happening:**
               - ⏳ Creating new iOS preview build (this takes ~10-15 minutes)
               - 📱 Build will be available on TestFlight internal testing
               - 🔄 You'll get a notification when the build is ready
-              
+
               **To test this PR:**
               1. Wait for the build to complete
               2. Update your TestFlight app to the latest preview build
               3. The new build will include your changes
-              
+
               **Build started at:** ${new Date().toLocaleString()}`
🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 168-168: trailing spaces

(trailing-spaces)


[error] 170-170: trailing spaces

(trailing-spaces)


[error] 174-174: trailing spaces

(trailing-spaces)


[error] 179-179: trailing spaces

(trailing-spaces)


[error] 184-184: trailing spaces

(trailing-spaces)


[error] 198-198: trailing spaces

(trailing-spaces)


[error] 200-200: trailing spaces

(trailing-spaces)


[error] 205-205: trailing spaces

(trailing-spaces)


[error] 207-207: trailing spaces

(trailing-spaces)


[error] 221-221: trailing spaces

(trailing-spaces)


[error] 223-223: trailing spaces

(trailing-spaces)


[error] 227-227: trailing spaces

(trailing-spaces)


[error] 232-232: trailing spaces

(trailing-spaces)


20-44: Consider extracting common environment setup into a reusable workflow.

The Node.js and EAS setup steps are duplicated across all three jobs, which violates the DRY principle and makes maintenance harder.

Consider creating a composite action or reusable workflow for the common setup steps to reduce duplication and improve maintainability.

Also applies to: 62-84, 103-117

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 32947c6 and 87f809a.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (8)
  • .fingerprintignore (1 hunks)
  • .github/workflows/pr-preview.yml (1 hunks)
  • components/debug-menu.tsx (2 hunks)
  • fingerprint.config.js (1 hunks)
  • package.json (1 hunks)
  • plugins/notification-service-extension/plugin/src/with-my-plugin-ios.ts (5 hunks)
  • plugins/notification-service-extension/plugin/src/with-my-plugin.ts (1 hunks)
  • scripts/check-runtime-compatibility.js (1 hunks)
✅ Files skipped from review due to trivial changes (5)
  • package.json
  • plugins/notification-service-extension/plugin/src/with-my-plugin-ios.ts
  • .fingerprintignore
  • fingerprint.config.js
  • plugins/notification-service-extension/plugin/src/with-my-plugin.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/debug-menu.tsx
🧰 Additional context used
🪛 actionlint (1.7.7)
.github/workflows/pr-preview.yml

120-120: "github.event.pull_request.title" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions for more details

(expression)


127-127: "github.event.pull_request.title" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions for more details

(expression)


237-237: property "check-compatibility" is not defined in object type {}

(expression)


240-240: property "check-compatibility" is not defined in object type {}

(expression)


277-277: property "check-compatibility" is not defined in object type {}

(expression)


280-280: property "check-compatibility" is not defined in object type {}

(expression)

🪛 YAMLlint (1.37.1)
.github/workflows/pr-preview.yml

[error] 168-168: trailing spaces

(trailing-spaces)


[error] 170-170: trailing spaces

(trailing-spaces)


[error] 174-174: trailing spaces

(trailing-spaces)


[error] 179-179: trailing spaces

(trailing-spaces)


[error] 184-184: trailing spaces

(trailing-spaces)


[error] 198-198: trailing spaces

(trailing-spaces)


[error] 200-200: trailing spaces

(trailing-spaces)


[error] 205-205: trailing spaces

(trailing-spaces)


[error] 207-207: trailing spaces

(trailing-spaces)


[error] 221-221: trailing spaces

(trailing-spaces)


[error] 223-223: trailing spaces

(trailing-spaces)


[error] 227-227: trailing spaces

(trailing-spaces)


[error] 232-232: trailing spaces

(trailing-spaces)

⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: tsc
  • GitHub Check: test
  • GitHub Check: lint
  • GitHub Check: Check Update Compatibility
  • GitHub Check: Code Review
🔇 Additional comments (1)
scripts/check-runtime-compatibility.js (1)

163-167: Good error handling with catch block.

The script properly handles unexpected errors in the main execution with appropriate logging and GitHub Actions output setting.

Comment on lines +40 to +46
const hashMatch = output.match(/"hash":"([^"]+)"/g)

if (hashMatch && hashMatch.length > 0) {
// Get the last hash (which is the final fingerprint)
const lastHash = hashMatch[hashMatch.length - 1]
const fingerprint = lastHash.match(/"hash":"([^"]+)"/)[1]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve robustness of fingerprint extraction.

The regex-based parsing of JSON output is fragile and could break if the output format changes. The potential null pointer access on line 45 could cause runtime errors.

Apply this diff to make the parsing more robust:

-  // The fingerprint output is a JSON object with a final "hash" field
-  // Extract the last hash value from the output
-  const hashMatch = output.match(/"hash":"([^"]+)"/g)
-
-  if (hashMatch && hashMatch.length > 0) {
-    // Get the last hash (which is the final fingerprint)
-    const lastHash = hashMatch[hashMatch.length - 1]
-    const fingerprint = lastHash.match(/"hash":"([^"]+)"/)[1]
+  try {
+    // Try to parse as JSON first
+    const jsonOutput = JSON.parse(output)
+    if (jsonOutput.hash) {
+      const fingerprint = jsonOutput.hash
+      console.log(`✅ Current fingerprint: ${fingerprint}`)
+      return fingerprint
+    }
+  } catch (jsonError) {
+    // Fallback to regex parsing for non-JSON output
+    const hashMatch = output.match(/"hash":"([^"]+)"/g)
+    if (hashMatch && hashMatch.length > 0) {
+      const lastHash = hashMatch[hashMatch.length - 1]
+      const hashMatches = lastHash.match(/"hash":"([^"]+)"/)
+      if (hashMatches && hashMatches[1]) {
+        const fingerprint = hashMatches[1]
+        console.log(`✅ Current fingerprint: ${fingerprint}`)
+        return fingerprint
+      }
+    }
+  }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In scripts/check-runtime-compatibility.js around lines 40 to 46, the code uses
regex to parse JSON output, which is fragile and risks runtime errors if the
format changes or the match is null. To fix this, parse the output as JSON
instead of using regex, then safely extract the fingerprint property from the
parsed object. Add checks to ensure the property exists before accessing it to
avoid null pointer errors.

Comment on lines +120 to +123
run: |
# Create build with PR-specific message
eas build --platform ios --profile preview --non-interactive --message "PR #${{ github.event.number }}: ${{ github.event.pull_request.title }}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Security vulnerability: Untrusted input in shell command.

Using github.event.pull_request.title directly in shell commands poses a security risk as it can contain malicious content that could be executed.

Apply this diff to fix the security issue:

       - name: Create EAS Build
+        env:
+          PR_TITLE: ${{ github.event.pull_request.title }}
+          PR_NUMBER: ${{ github.event.number }}
         run: |
           # Create build with PR-specific message
-          eas build --platform ios --profile preview --non-interactive --message "PR #${{ github.event.number }}: ${{ github.event.pull_request.title }}"
+          eas build --platform ios --profile preview --non-interactive --message "PR #${PR_NUMBER}: ${PR_TITLE}"

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 actionlint (1.7.7)

120-120: "github.event.pull_request.title" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions for more details

(expression)

🤖 Prompt for AI Agents
In .github/workflows/pr-preview.yml around lines 120 to 123, the shell command
uses the untrusted input github.event.pull_request.title directly, which can
lead to command injection vulnerabilities. To fix this, sanitize or escape the
pull request title before including it in the shell command, or use GitHub
Actions built-in mechanisms to safely pass this value as an environment variable
or argument without direct shell interpolation.

Comment on lines +127 to +158
script: |
const body = `## 🏗️ New Build Started

⏳ **Creating new preview build** for native changes...

### 📊 Build Details
- **Platform:** iOS
- **Profile:** preview
- **Reason:** Native changes detected in PR #${{ github.event.number }}
- **Message:** "${{ github.event.pull_request.title }}"

### ⏱️ Expected Timeline
- **Build time:** ~10-15 minutes
- **TestFlight processing:** ~5-10 minutes
- **Total:** ~15-25 minutes

### 🔔 What's Next
1. **Build will appear in EAS dashboard** when complete
2. **New build will be submitted to TestFlight** automatically
3. **You'll get a notification** when ready for testing
4. **Update your preview app** before testing this PR

---
*You can track build progress in the [EAS dashboard](https://expo.dev/accounts/ephemera/projects/convos/builds).*`;

github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Security vulnerability: Untrusted input in inline script.

The PR title is used directly in the JavaScript code without proper escaping, which could lead to script injection attacks.

Apply this diff to fix the security issue:

       - name: Comment on PR - Build Started
         uses: actions/github-script@v7
+        env:
+          PR_TITLE: ${{ github.event.pull_request.title }}
+          PR_NUMBER: ${{ github.event.number }}
         with:
           script: |
+            const prTitle = process.env.PR_TITLE;
+            const prNumber = process.env.PR_NUMBER;
             const body = `## 🏗️ New Build Started
 
             ⏳ **Creating new preview build** for native changes...
 
             ### 📊 Build Details
             - **Platform:** iOS
             - **Profile:** preview
-            - **Reason:** Native changes detected in PR #${{ github.event.number }}
-            - **Message:** "${{ github.event.pull_request.title }}"
+            - **Reason:** Native changes detected in PR #${prNumber}
+            - **Message:** "${prTitle}"
 
             ### ⏱️ Expected Timeline
             - **Build time:** ~10-15 minutes
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
script: |
const body = `## 🏗️ New Build Started
⏳ **Creating new preview build** for native changes...
### 📊 Build Details
- **Platform:** iOS
- **Profile:** preview
- **Reason:** Native changes detected in PR #${{ github.event.number }}
- **Message:** "${{ github.event.pull_request.title }}"
### ⏱️ Expected Timeline
- **Build time:** ~10-15 minutes
- **TestFlight processing:** ~5-10 minutes
- **Total:** ~15-25 minutes
### 🔔 What's Next
1. **Build will appear in EAS dashboard** when complete
2. **New build will be submitted to TestFlight** automatically
3. **You'll get a notification** when ready for testing
4. **Update your preview app** before testing this PR
---
*You can track build progress in the [EAS dashboard](https://expo.dev/accounts/ephemera/projects/convos/builds).*`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
- name: Comment on PR - Build Started
uses: actions/github-script@v7
env:
PR_TITLE: ${{ github.event.pull_request.title }}
PR_NUMBER: ${{ github.event.number }}
with:
script: |
const prTitle = process.env.PR_TITLE;
const prNumber = process.env.PR_NUMBER;
const body = `## 🏗️ New Build Started
⏳ **Creating new preview build** for native changes...
### 📊 Build Details
- **Platform:** iOS
- **Profile:** preview
- **Reason:** Native changes detected in PR #${prNumber}
- **Message:** "${prTitle}"
### ⏱️ Expected Timeline
- **Build time:** ~10-15 minutes
- **TestFlight processing:** ~5-10 minutes
- **Total:** ~15-25 minutes
### 🔔 What's Next
1. **Build will appear in EAS dashboard** when complete
2. **New build will be submitted to TestFlight** automatically
3. **You'll get a notification** when ready for testing
4. **Update your preview app** before testing this PR
---
*You can track build progress in the [EAS dashboard](https://expo.dev/accounts/ephemera/projects/convos/builds).*`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
🧰 Tools
🪛 actionlint (1.7.7)

127-127: "github.event.pull_request.title" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions for more details

(expression)

🤖 Prompt for AI Agents
In .github/workflows/pr-preview.yml around lines 127 to 158, the PR title is
directly embedded in the JavaScript string without escaping, which risks script
injection. To fix this, sanitize or escape the PR title before including it in
the body string to ensure any special characters are neutralized and cannot
break out of the string context. Use a proper escaping function or method to
safely insert the PR title into the comment body.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
.github/workflows/pr-preview.yml (4)

3-6: Consider adding concurrency controls to the workflow
Prevent redundant preview runs by cancelling in-flight workflows for the same PR.

You can add at the top level:

name: PR Preview
concurrency:
  group: pr-preview-${{ github.event.pull_request.number }}
  cancel-in-progress: true
on:
  pull_request:
    types: [opened, synchronize, reopened]

17-37: Extract shared setup steps into a reusable workflow or composite action
The sequence of checkout → setup-node → corepack → yarn install → plugin build repeats across all jobs. Factor this out with YAML anchors or a composite action to improve maintainability and reduce drift.

Also applies to: 58-86, 145-169


222-233: Remove trailing spaces in the comment body
Several lines in the “Build Complete” comment block have trailing whitespace. Trim them to keep diffs clean and avoid unintended spaces in the posted comment.

🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 223-223: trailing spaces

(trailing-spaces)


[error] 225-225: trailing spaces

(trailing-spaces)


[error] 230-230: trailing spaces

(trailing-spaces)


[error] 232-232: trailing spaces

(trailing-spaces)


245-258: Remove trailing spaces in the failure comment body
The multi-line string for “Preview Build Failed” contains trailing spaces on multiple lines—please remove these to maintain consistency.

🧰 Tools
🪛 YAMLlint (1.37.1)

[error] 246-246: trailing spaces

(trailing-spaces)


[error] 248-248: trailing spaces

(trailing-spaces)


[error] 252-252: trailing spaces

(trailing-spaces)


[error] 257-257: trailing spaces

(trailing-spaces)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 87f809a and fd26376.

📒 Files selected for processing (2)
  • .github/workflows/pr-preview.yml (1 hunks)
  • App.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • App.tsx
🧰 Additional context used
🪛 actionlint (1.7.7)
.github/workflows/pr-preview.yml

210-210: "github.event.pull_request.title" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions for more details

(expression)

🪛 YAMLlint (1.37.1)
.github/workflows/pr-preview.yml

[error] 223-223: trailing spaces

(trailing-spaces)


[error] 225-225: trailing spaces

(trailing-spaces)


[error] 230-230: trailing spaces

(trailing-spaces)


[error] 232-232: trailing spaces

(trailing-spaces)


[error] 246-246: trailing spaces

(trailing-spaces)


[error] 248-248: trailing spaces

(trailing-spaces)


[error] 252-252: trailing spaces

(trailing-spaces)


[error] 257-257: trailing spaces

(trailing-spaces)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Review for correctness
🔇 Additional comments (1)
.github/workflows/pr-preview.yml (1)

11-14:

Details

✅ Verification successful

Verify that the compatibility script sets outputs correctly
Downstream jobs rely on can_create_update, current_fingerprint, and preview_fingerprint. Ensure scripts/check-runtime-compatibility.js writes to $GITHUB_OUTPUT (rather than the deprecated set-output).


🏁 Script executed:

#!/bin/bash
# Confirm the script emits to GITHUB_OUTPUT
rg -n 'GITHUB_OUTPUT' scripts/check-runtime-compatibility.js

Length of output: 173


Outputs correctly set to GITHUB_OUTPUT
The compatibility script writes can_create_update, current_fingerprint, and preview_fingerprint to $GITHUB_OUTPUT via fs.appendFileSync(process.env.GITHUB_OUTPUT, …) in scripts/check-runtime-compatibility.js (lines 156–158). No changes needed.

Comment on lines +211 to +212
eas build --platform ios --profile preview --non-interactive --message "PR #${{ github.event.number }}: ${{ github.event.pull_request.title }}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Security risk: untrusted PR title in build command
The eas build ... --message "PR #${{ github.event.number }}: ${{ github.event.pull_request.title }}" invocation interpolates untrusted input. Use env vars or escape the title to avoid injection.

🤖 Prompt for AI Agents
In .github/workflows/pr-preview.yml at lines 211-212, the eas build command uses
the untrusted PR title directly in the --message argument, which risks command
injection. To fix this, avoid direct interpolation of the PR title in the
command line; instead, assign the PR title to a GitHub Actions environment
variable with proper escaping or sanitization, then reference that variable
safely in the eas build command to prevent injection vulnerabilities.

- name: Create PR preview update
uses: expo/expo-github-action/preview@v8
with:
command: eas update --branch=pr-${{ github.event.number }} --message="PR #${{ github.event.number }}: ${{ github.event.pull_request.title }}"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Security risk: untrusted PR title in update command
Using ${{ github.event.pull_request.title }} directly in the eas update --message flag can lead to command-injection. Pass the title via an environment variable or properly escape/sanitize it.

🤖 Prompt for AI Agents
In .github/workflows/pr-preview.yml at line 92, the PR title is directly used in
the eas update command message, which poses a command injection risk. To fix
this, avoid inserting the raw PR title directly in the command string; instead,
assign the PR title to an environment variable and reference that variable in
the command, or sanitize/escape the title properly before usage to prevent
injection vulnerabilities.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant