Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
35 changes: 35 additions & 0 deletions .github/workflows/expo-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,38 @@ jobs:
run: pnpm install --frozen-lockfile
- name: TypeScript type check
run: npx tsc --noEmit

build:
runs-on: ubuntu-latest
needs: [lint, format, typecheck]
env:
EXPO_TOKEN: ${{ secrets.EXPO_TOKEN }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Setup pnpm
uses: pnpm/action-setup@v3
with:
version: 10.12.1
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Ensure EAS CLI available
run: pnpm dlx eas-cli@latest --version
# No explicit login needed, Expo CLI uses EXPO_TOKEN env automatically
- name: Build Android APK
if: env.EXPO_TOKEN != ''
run: pnpm dlx eas-cli@latest build --platform android --non-interactive --profile preview --clear-cache --wait
- name: Download Android APK
if: env.EXPO_TOKEN != ''
run: pnpm dlx eas-cli@latest build:download --platform android --profile preview --latest --path ./app.apk
Comment on lines +92 to +99
Copy link

Copilot AI Aug 24, 2025

Choose a reason for hiding this comment

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

The EAS CLI version is not pinned, using '@latest' which could lead to unexpected behavior if breaking changes are introduced. Consider pinning to a specific version for reproducible builds.

Suggested change
run: pnpm dlx eas-cli@latest --version
# No explicit login needed, Expo CLI uses EXPO_TOKEN env automatically
- name: Build Android APK
if: env.EXPO_TOKEN != ''
run: pnpm dlx eas-cli@latest build --platform android --non-interactive --profile preview --clear-cache --wait
- name: Download Android APK
if: env.EXPO_TOKEN != ''
run: pnpm dlx eas-cli@latest build:download --platform android --profile preview --latest --path ./app.apk
run: pnpm dlx eas-cli@6.3.0 --version
# No explicit login needed, Expo CLI uses EXPO_TOKEN env automatically
- name: Build Android APK
if: env.EXPO_TOKEN != ''
run: pnpm dlx eas-cli@6.3.0 build --platform android --non-interactive --profile preview --clear-cache --wait
- name: Download Android APK
if: env.EXPO_TOKEN != ''
run: pnpm dlx eas-cli@6.3.0 build:download --platform android --profile preview --latest --path ./app.apk

Copilot uses AI. Check for mistakes.
Comment on lines +92 to +99
Copy link

Copilot AI Aug 24, 2025

Choose a reason for hiding this comment

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

The EAS CLI version is not pinned, using '@latest' which could lead to unexpected behavior if breaking changes are introduced. Consider pinning to a specific version for reproducible builds.

Suggested change
run: pnpm dlx eas-cli@latest --version
# No explicit login needed, Expo CLI uses EXPO_TOKEN env automatically
- name: Build Android APK
if: env.EXPO_TOKEN != ''
run: pnpm dlx eas-cli@latest build --platform android --non-interactive --profile preview --clear-cache --wait
- name: Download Android APK
if: env.EXPO_TOKEN != ''
run: pnpm dlx eas-cli@latest build:download --platform android --profile preview --latest --path ./app.apk
run: pnpm dlx eas-cli@6.3.0 --version
# No explicit login needed, Expo CLI uses EXPO_TOKEN env automatically
- name: Build Android APK
if: env.EXPO_TOKEN != ''
run: pnpm dlx eas-cli@6.3.0 build --platform android --non-interactive --profile preview --clear-cache --wait
- name: Download Android APK
if: env.EXPO_TOKEN != ''
run: pnpm dlx eas-cli@6.3.0 build:download --platform android --profile preview --latest --path ./app.apk

Copilot uses AI. Check for mistakes.
# ...existing code...
- name: Upload Android artifact
if: env.EXPO_TOKEN != ''
Comment on lines +95 to +102
Copy link

Copilot AI Aug 24, 2025

Choose a reason for hiding this comment

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

The condition 'env.EXPO_TOKEN != ''' is repeated three times. Consider using a job-level condition or extracting this to a reusable condition to reduce duplication.

Suggested change
if: env.EXPO_TOKEN != ''
run: pnpm dlx eas-cli@latest build --platform android --non-interactive --profile preview --clear-cache --wait
- name: Download Android APK
if: env.EXPO_TOKEN != ''
run: pnpm dlx eas-cli@latest build:download --platform android --profile preview --latest --path ./app.apk
# ...existing code...
- name: Upload Android artifact
if: env.EXPO_TOKEN != ''
run: pnpm dlx eas-cli@latest build --platform android --non-interactive --profile preview --clear-cache --wait
- name: Download Android APK
run: pnpm dlx eas-cli@latest build:download --platform android --profile preview --latest --path ./app.apk
# ...existing code...
- name: Upload Android artifact

Copilot uses AI. Check for mistakes.
Comment on lines +95 to +102
Copy link

Copilot AI Aug 24, 2025

Choose a reason for hiding this comment

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

The condition 'env.EXPO_TOKEN != ''' is repeated three times. Consider using a job-level condition or extracting this to a reusable condition to reduce duplication.

Suggested change
if: env.EXPO_TOKEN != ''
run: pnpm dlx eas-cli@latest build --platform android --non-interactive --profile preview --clear-cache --wait
- name: Download Android APK
if: env.EXPO_TOKEN != ''
run: pnpm dlx eas-cli@latest build:download --platform android --profile preview --latest --path ./app.apk
# ...existing code...
- name: Upload Android artifact
if: env.EXPO_TOKEN != ''
if: env.HAS_EXPO_TOKEN == 'true'
run: pnpm dlx eas-cli@latest build --platform android --non-interactive --profile preview --clear-cache --wait
- name: Download Android APK
if: env.HAS_EXPO_TOKEN == 'true'
run: pnpm dlx eas-cli@latest build:download --platform android --profile preview --latest --path ./app.apk
# ...existing code...
- name: Upload Android artifact
if: env.HAS_EXPO_TOKEN == 'true'

Copilot uses AI. Check for mistakes.
Comment on lines +95 to +102
Copy link

Copilot AI Aug 24, 2025

Choose a reason for hiding this comment

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

The condition 'env.EXPO_TOKEN != ''' is repeated three times. Consider using a job-level condition or extracting this to a reusable condition to reduce duplication.

Suggested change
if: env.EXPO_TOKEN != ''
run: pnpm dlx eas-cli@latest build --platform android --non-interactive --profile preview --clear-cache --wait
- name: Download Android APK
if: env.EXPO_TOKEN != ''
run: pnpm dlx eas-cli@latest build:download --platform android --profile preview --latest --path ./app.apk
# ...existing code...
- name: Upload Android artifact
if: env.EXPO_TOKEN != ''
run: pnpm dlx eas-cli@latest build --platform android --non-interactive --profile preview --clear-cache --wait
- name: Download Android APK
run: pnpm dlx eas-cli@latest build:download --platform android --profile preview --latest --path ./app.apk
# ...existing code...
- name: Upload Android artifact

Copilot uses AI. Check for mistakes.
uses: actions/upload-artifact@v4
with:
name: android-apk
path: ./app.apk
Comment on lines +99 to +106
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid --latest; tie download to the build you just triggered

--latest can fetch an unrelated artifact from another commit/branch. The previous diff captures BUILD_ID and downloads that exact build.

🤖 Prompt for AI Agents
.github/workflows/expo-build.yml lines 99-106: the workflow currently uses
`--latest` when running `eas-cli build:download`, which can retrieve an
unrelated artifact; change the command to download the exact build by using the
BUILD_ID captured earlier (e.g., replace `--latest` with `--id ${{ env.BUILD_ID
}}` or the equivalent environment variable you set), keeping the platform,
profile and path flags intact so the download step deterministically fetches the
build you just triggered.

3 changes: 2 additions & 1 deletion app.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@
"resizeMode": "contain",
"backgroundColor": "#ffffff"
}
]
],
"./app.plugin.js"
],
"experiments": {
"typedRoutes": true
Expand Down
29 changes: 29 additions & 0 deletions app.plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Inject core-splashscreen dependency to fix Android resource linking errors for Theme.SplashScreen
// This runs during EAS prebuild and modifies android/app/build.gradle
const { withAppBuildGradle, createRunOncePlugin, WarningAggregator } = require('@expo/config-plugins');

const DEP_LINE = 'implementation("androidx.core:core-splashscreen:1.0.1")';

function ensureDependency(contents) {
if (contents.includes(DEP_LINE)) return contents; // already present
return contents.replace(/dependencies\s*\{/m, (match) => `${match}\n ${DEP_LINE}`);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Make detection robust to avoid duplicate entries

Exact string match can miss alternative Gradle syntaxes or different versions, causing duplicate dependencies. Use a regex that matches both with/without parentheses and any version.

Apply this diff:

-const DEP_LINE = 'implementation("androidx.core:core-splashscreen:1.0.1")';
+const DEP_LINE = 'implementation("androidx.core:core-splashscreen:1.0.1")';
+const DEP_REGEX = /implementation\s*\(?["']androidx\.core:core-splashscreen:[^"']+["']\)?/;
@@
-function ensureDependency(contents) {
-  if (contents.includes(DEP_LINE)) return contents; // already present
-  return contents.replace(/dependencies\s*\{/m, (match) => `${match}\n    ${DEP_LINE}`);
-}
+function ensureDependency(contents) {
+  if (DEP_REGEX.test(contents)) return contents;
+  return contents.replace(/dependencies\s*\{/m, (m) => `${m}\n    ${DEP_LINE}`);
+}
📝 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
const DEP_LINE = 'implementation("androidx.core:core-splashscreen:1.0.1")';
function ensureDependency(contents) {
if (contents.includes(DEP_LINE)) return contents; // already present
return contents.replace(/dependencies\s*\{/m, (match) => `${match}\n ${DEP_LINE}`);
}
const DEP_LINE = 'implementation("androidx.core:core-splashscreen:1.0.1")';
const DEP_REGEX = /implementation\s*\(?["']androidx\.core:core-splashscreen:[^"']+["']\)?/;
function ensureDependency(contents) {
if (DEP_REGEX.test(contents)) return contents;
return contents.replace(/dependencies\s*\{/m, (m) => `${m}\n ${DEP_LINE}`);
}


const withCoreSplashscreenDependency = (config) =>
withAppBuildGradle(config, (config) => {
try {
config.modResults.contents = ensureDependency(config.modResults.contents);
} catch (e) {
WarningAggregator.addWarningAndroid(
'core-splashscreen',
`Failed to add androidx.core:core-splashscreen dependency: ${e?.message ?? e}`
);
}
return config;
});

module.exports = createRunOncePlugin(
withCoreSplashscreenDependency,
'with-core-splashscreen-dependency',
'1.0.0'
);
Loading