Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions .fingerprintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Ignore files that don't affect native compatibility

# Development and build artifacts
node_modules/**/*
.expo/**/*
.git/**/*
*.log
.DS_Store

# Documentation and non-native files
README.md
CONTRIBUTING.md
*.md
docs/**/*

# Test files
**/*.test.ts
**/*.test.tsx
**/__tests__/**/*
jest.config.ts
jest.setup.ts

# Linting and formatting
.eslintrc.*
.prettierrc.*
eslint.config.mjs

# Environment and config files that don't affect native
.env*
.nvmrc
yarn.lock
package-lock.json

# Scripts that don't affect native build
scripts/**/*
!scripts/check-runtime-compatibility.js

# GitHub workflows (except our PR preview)
.github/workflows/**/*
!.github/workflows/pr-preview.yml

# Patches and temporary files
patches/**/*
*.patch
*.tmp

# IDE and editor files
.vscode/**/*
.idea/**/*
*.swp
*.swo

# React Native Metro cache
.metro-health-check*

# Expo development
.expo-shared/**/*

# TypeScript build artifacts
*.tsbuildinfo

# Reassure performance tests
reassure-tests.sh

# Keep important native-affecting files by explicitly not ignoring them:
# - app.config.ts (affects native config)
# - eas.json (affects builds)
# - package.json (affects dependencies)
# - plugins/ (affects native code)
# - ios/ and android/ directories
# - babel.config.js (affects transforms)
# - metro.config.js (affects bundling)
259 changes: 259 additions & 0 deletions .github/workflows/pr-preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
name: PR Preview

on:
pull_request:
types: [opened, synchronize, reopened]

jobs:
check-compatibility:
name: Check Update Compatibility
runs-on: ubuntu-latest
outputs:
can_create_update: ${{ steps.check-runtime.outputs.can_create_update }}
current_fingerprint: ${{ steps.check-runtime.outputs.current_fingerprint }}
preview_fingerprint: ${{ steps.check-runtime.outputs.preview_fingerprint }}

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup node
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: "yarn"
cache-dependency-path: yarn.lock
env:
SKIP_YARN_COREPACK_CHECK: "1"

- run: corepack enable

- name: Install dependencies
run: yarn install

# Need this here because the "Setup EAS" setup will execute npx expo config and will need the "build" folder of the plugin to be there
- name: Build iOS notification extension plugin
run: yarn plugins:build:notification-service-extension

- name: Setup EAS
uses: expo/expo-github-action@v8
with:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}
packager: yarn

- name: Check fingerprint compatibility
id: check-runtime
run: node scripts/check-runtime-compatibility.js

create-update:
name: Create EAS Update
runs-on: ubuntu-latest
needs: check-compatibility
if: needs.check-compatibility.outputs.can_create_update == 'true'
permissions:
contents: read
pull-requests: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup node
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: "yarn"
cache-dependency-path: yarn.lock
env:
SKIP_YARN_COREPACK_CHECK: "1"

- run: corepack enable

- name: Install dependencies
run: yarn install

# Need this here because the "Setup EAS" setup will execute npx expo config and will need the "build" folder of the plugin to be there
- name: Build iOS notification extension plugin
run: yarn plugins:build:notification-service-extension

- name: Setup EAS
uses: expo/expo-github-action@v8
with:
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}
packager: yarn
eas-cache: true
patch-watchers: true

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

env:
EXPO_ENV: preview

- name: Comment on PR - EAS Update Ready
uses: actions/github-script@v7
with:
script: |
const currentFingerprint = '${{ needs.check-compatibility.outputs.current_fingerprint }}';
const previewFingerprint = '${{ needs.check-compatibility.outputs.preview_fingerprint }}';

const body = `## 📱 PR Preview Ready (EAS Update)

✅ **Compatible with current preview builds** - No native changes detected

### 🔄 How to Test
1. **Open the Convos Preview app** (must be on latest preview build)
2. **Long press anywhere** to open debug menu
3. **Tap "Updates Menu"** → **"Switch to PR Branch (Smart)"**
4. **Enter PR number:** \`${{ github.event.number }}\`
5. **Tap "Check & Switch"** - it will verify compatibility first

### 📊 Technical Details
- **Update Type:** EAS Update (JavaScript-only changes)
- **Runtime Version:** \`${currentFingerprint}\`
- **Compatible with builds:** \`${previewFingerprint}\`
- **Branch:** \`pr-${{ github.event.number }}\`
- **Deep Link:** \`convos-preview://expo-development-client/?url=https://u.expo.dev/f9089dfa-8871-4aff-93ea-da08af0370d2?channel-name=pr-${{ github.event.number }}\`

### ⚠️ Important Notes
- Only works with **preview builds** that have runtime version \`${previewFingerprint}\`
- The debug menu will **automatically check compatibility** before switching
- If you're on an older build, you'll see a warning message

---
*This update was created automatically because no native changes were detected.*`;

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

create-build:
name: Create EAS Build for Native Changes
runs-on: ubuntu-latest
needs: check-compatibility
if: needs.check-compatibility.outputs.can_create_update == 'false'
permissions:
contents: read
pull-requests: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup node
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: "yarn"
cache-dependency-path: yarn.lock

- name: Setup EAS
uses: expo/expo-github-action@v8
with:
expo-version: latest
eas-version: latest
token: ${{ secrets.EXPO_TOKEN }}

- name: Install dependencies
run: yarn install --frozen-lockfile

# Need this here because the "Setup EAS" setup will execute npx expo config and will need the "build" folder of the plugin to be there
- name: Build iOS notification extension plugin
run: yarn plugins:build:notification-service-extension

- name: Comment on PR - Build Required
uses: actions/github-script@v7
with:
script: |
const currentFingerprint = '${{ needs.check-compatibility.outputs.current_fingerprint }}';
const previewFingerprint = '${{ needs.check-compatibility.outputs.preview_fingerprint }}';

const body = `## 🔨 PR Preview Requires New Build

⚠️ **Native changes detected** - EAS Update not compatible

### 🏗️ What's Happening
This PR contains native changes (new dependencies, config changes, etc.) that require a new build.

### 📊 Technical Details
- **Current PR fingerprint:** \`${currentFingerprint}\`
- **Latest preview build:** \`${previewFingerprint}\`
- **Compatibility:** ❌ **Incompatible** (different runtime versions)

### 🚀 Next Steps
1. **Wait for new build** - A new preview build will be created automatically
2. **Check TestFlight** - New build will appear in TestFlight when ready
3. **Update your app** - Install the new build before testing this PR

### ⚠️ Important for Testers
- **Don't try to switch to this PR** in the debug menu with old builds
- **It will crash** because of runtime version mismatch
- **Wait for the new build** notification

---
*This PR requires a new build because it contains native changes.*`;

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

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

Comment on lines +211 to +212

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: Comment on PR - Build Complete
if: success()
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `✅ **Preview Build Complete!**

The new preview build for this PR is ready.

**To test:**
1. Open TestFlight on your device
2. Update to the latest "Convos Preview" build
3. The build includes the changes from this PR

**Build completed at:** ${new Date().toLocaleString()}

Note: It may take a few minutes for the build to appear in TestFlight.`
})

- name: Comment on PR - Build Failed
if: failure()
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `❌ **Preview Build Failed**

The preview build for this PR failed to create.

**To investigate:**
1. Check the [workflow logs](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})
2. Look for build errors in the EAS dashboard

**Common causes:**
- Build configuration issues
- Native dependency conflicts
- Code signing problems

**Build failed at:** ${new Date().toLocaleString()}`
})
2 changes: 2 additions & 0 deletions App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,5 @@ const Handlers = memo(function Handlers() {

return null
})

const test = ""
15 changes: 14 additions & 1 deletion app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ type EnvironmentConfig = {
backgroundColor: string
}
}
updates: {
disableAntiBrickingMeasures: boolean
}
}

export type IExpoAppConfigExtra = {
Expand Down Expand Up @@ -71,6 +74,9 @@ const settings: Record<Environment, EnvironmentConfig> = {
webDomain: "preview.convos.org",
appName: "Convos Dev",
icon: "./assets/icon-light.png",
updates: {
disableAntiBrickingMeasures: true,
},
},
preview: {
scheme: "convos-preview",
Expand Down Expand Up @@ -100,6 +106,9 @@ const settings: Record<Environment, EnvironmentConfig> = {
webDomain: "preview.convos.org",
appName: "Convos Preview",
icon: "./assets/icon-light.png",
updates: {
disableAntiBrickingMeasures: true,
},
},
production: {
scheme: "convos",
Expand Down Expand Up @@ -129,6 +138,10 @@ const settings: Record<Environment, EnvironmentConfig> = {
webDomain: "convos.org",
appName: "Convos",
icon: "./assets/icon-light.png",
updates: {
// NEVER in production app for now https://docs.expo.dev/eas-update/override/
disableAntiBrickingMeasures: false,
},
},
}

Expand All @@ -147,7 +160,7 @@ export default () => {
version: version,
assetBundlePatterns: ["**/*"],
runtimeVersion: {
policy: "nativeVersion",
policy: "fingerprint",
},
updates: {
url: "https://u.expo.dev/f9089dfa-8871-4aff-93ea-da08af0370d2",
Expand Down
Loading