Conversation
WalkthroughThe changes introduce centralized version management for iOS and Android builds using a new Changes
Sequence Diagram(s)sequenceDiagram
participant Developer
participant GitHub Actions
participant update-versions.js
participant versions.json
participant app.config.ts
participant GitHub Release
Developer->>GitHub Actions: Push/Tag/PR triggers workflow
GitHub Actions->>update-versions.js: Run script with platform/env args
update-versions.js->>versions.json: Read and increment build number/code
update-versions.js-->>GitHub Actions: Output new build number/code
GitHub Actions->>app.config.ts: Update with new build number/code
GitHub Actions->>versions.json: Commit and push changes if updated
GitHub Actions->>GitHub Release: (Production) Create release with version/build
Poem
Note ⚡️ AI Code Reviews for VS Code, Cursor, WindsurfCodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback. ✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 5
♻️ Duplicate comments (1)
.github/workflows/preview-deployment.yml (1)
106-111: Duplicate deprecation note:set-outputusage
As with the production workflow, ifupdate-versions.jsor related scripts still emit::set-output, they should adoptecho "new_build_number=$VALUE" >> $GITHUB_OUTPUT.
🧹 Nitpick comments (2)
scripts/update-versions.js (1)
49-49: Apply optional chaining for cleaner code.As suggested by the static analysis tool, this can be simplified using optional chaining.
Apply this improvement:
- const platformConfig = versionsData[platform] && versionsData[platform][env] + const platformConfig = versionsData[platform]?.[env]🧰 Tools
🪛 Biome (1.9.4)
[error] 49-49: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
.github/workflows/production-deployment.yml (1)
36-42: Consider fallback for build number
Currently you only fallbackAPP_VERSIONfrompackage.json. It may be worthwhile to also read the previous build number fromversions.jsonwhen tag parsing fails, to avoid deployment interruptions.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
.github/workflows/preview-deployment.yml(6 hunks).github/workflows/production-deployment.yml(2 hunks).github/workflows/promote-to-production.yml(1 hunks)app.config.ts(12 hunks)eas.json(1 hunks)scripts/update-versions.js(1 hunks)versions.json(1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.7)
.github/workflows/promote-to-production.yml
54-54: workflow command "set-output" was deprecated. use echo "{name}={value}" >> $GITHUB_OUTPUT instead: https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions
(deprecated-commands)
🪛 Biome (1.9.4)
versions.json
[error] 4-4: expected , but instead found // TODO set the right version using eas:version:get (something like this)
Remove // TODO set the right version using eas:version:get (something like this)
(parse)
[error] 7-7: expected , but instead found // TODO set the right version using eas:version:get (something like this)
Remove // TODO set the right version using eas:version:get (something like this)
(parse)
[error] 10-10: expected , but instead found // TODO set the right version using eas:version:get (something like this)
Remove // TODO set the right version using eas:version:get (something like this)
(parse)
scripts/update-versions.js
[error] 49-49: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🔇 Additional comments (37)
eas.json (1)
4-4: LGTM! Correct alignment with local versioning system.This change properly configures EAS to use the local versioning system, which aligns perfectly with the new
versions.jsoncentralized approach introduced in this PR.app.config.ts (5)
3-3: LGTM! Clean import of centralized version data.Great approach to import version data from the centralized
versions.jsonfile, providing a single source of truth for versioning across all environments.
16-16: LGTM! Proper type extensions for version fields.The addition of
buildNumber: stringfor iOS andversionCode: numberfor Android correctly reflects the platform-specific requirements and aligns with Expo's configuration schema.Also applies to: 26-26
59-59: LGTM! Consistent version integration across all environments.The implementation correctly:
- Converts iOS buildNumber to string (as required by iOS)
- Uses Android buildCode as number for versionCode
- Maintains consistency across development, preview, and production environments
Also applies to: 69-69, 91-91, 101-101, 122-122, 132-132
158-160: LGTM! Appropriate runtime version policy change.Changing from a hardcoded string to
nativeVersionpolicy is the correct approach for the new centralized versioning system, ensuring runtime updates are properly managed based on native build versions.
173-173: LGTM! Proper platform-specific version configuration.The final iOS and Android configuration correctly uses the version data from the environment settings, completing the integration of the centralized versioning system.
Also applies to: 215-215
scripts/update-versions.js (4)
8-21: LGTM! Robust argument parsing with proper validation.The argument parsing logic correctly handles both value-based and flag-based arguments, providing flexibility for future enhancements.
28-38: LGTM! Comprehensive input validation.Excellent validation for both platform and environment parameters, with clear error messages that guide proper usage.
40-73: LGTM! Solid error handling and file operations.The script demonstrates excellent error handling practices:
- Proper try-catch blocks for file operations
- Clear error messages with context
- Appropriate exit codes for CI/CD integration
- Validation of data structure before modification
🧰 Tools
🪛 Biome (1.9.4)
[error] 49-49: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
75-77: LGTM! Proper module entry point handling.Good practice to check
require.main === modulefor direct script execution while allowing the function to be imported and used programmatically..github/workflows/promote-to-production.yml (8)
6-7: Permissions scope is correct
Grantingcontents: writeis required for pushing commits and tags from this workflow.
10-17: Job outputs configured for downstream usage
Renaming the job toprepare_and_mergeand exposingrelease_tag,app_version, andbuild_numberaligns perfectly with the new multi-workflow versioning strategy.
19-25: Explicit checkout ofmainwith PAT
Usingactions/checkout@v4withref: main,fetch-depth: 0, and a personal access token ensures you can push commits and tags back tomain.
26-34: Node.js and Yarn setup is solid
Leveraging.nvmrc, Yarn caching,corepack enable, andyarn install --immutableguarantees reproducible installs.
41-50: Robust package.json version extraction
The shell snippet correctly reads and validatespackage.json’sversionfield and exports it using the newGITHUB_OUTPUTsyntax.
58-67: Validating and applying updated build number
The step guards against missing output and then updatesapp.config.tswith the new build number—good error handling and consistency with your versioning flow.
69-91: Commit and tag logic is correct
Conditionally committing only when files changed and then creating an annotated tag (v{version}-ios-build.{build_number}) matches best practices for release management.
92-99: Merge strategy confirmation
You’re usinggit merge main -Xtheirsto favormainon conflict. If that aligns with your release policy, this is a clean approach—otherwise, please verify that automatic theirs-strategy conflicts are acceptable..github/workflows/production-deployment.yml (10)
6-8: Tag-based trigger is precise
Switching from branch pushes to tag patternvX.Y.Z-build.Nensures builds only run for formal releases.
10-11: Scoped concurrency
Usingproduction-deployment-${{ github.ref }}avoids overlaps per tag run—perfect for high-frequency releases.
14-15: Permissions set correctly
id-token: writefor potential OIDC-based steps andcontents: writefor release creation cover the workflow’s needs.
18-19: Job rename aligns with naming conventions
Renaming tobuild_and_deploy(snake_case) improves consistency against the other workflows.
21-25: Checkout of the release tag
Checking out${{ github.ref }}with full history (fetch-depth: 0) is essential for release notes and correct source state.
27-35: Accurate parsing of version and build number
Thesedexpressions reliably extract semver and build components from the tag name; good fallback topackage.jsonfor the version.
45-50: Exporting metadata for later steps
Correct use ofGITHUB_OUTPUTto exposerelease_tag,app_version, andbuild_numberfor downstream EAS and release steps.
57-65: Node.js and Yarn consistency
Aligns with other workflows—.nvmrc, Yarn cache, and--immutablefor reproducibility.
81-83: Passing release tag into EAS build
ExportingRELEASE_TAG_VALensures descriptive build messages and traceability.
94-106: Verify GitHub CLI availability
You invokegh release createdirectly; please confirm the runner environment includes the GitHub CLI or add an install step (e.g.,actions/setup-gh)..github/workflows/preview-deployment.yml (9)
7-7: Clarifiedforce_native_buildinput
The description aptly explains its override behavior for check-changes logic.
21-21: Trigger onversions.jsonupdates
Includingversions.jsonin the path filters ensures preview builds bump appropriately when version metadata changes.
29-31: Scoped concurrency for preview runs
preview-deployment-${{ github.ref }}prevents overlapping workflows on the same ref—excellent for PRs and pushes.
77-79: Exposing preview build number
Outputtingios_preview_build_numberfrom theupdate_versions_json_previewstep makes this data available to other jobs or notifications.
85-87: Checkout with full history and PAT
Usingtoken: ${{ secrets.PAT_GITHUB }}andfetch-depth: 0matches the promote workflow, enabling commits back to the triggering branch.
99-100: Immutable Yarn install
yarn install --immutableenforces lockfile consistency across preview runs.
101-105: Git configuration for preview commits
Distinct bot identity (github-actions-bot-preview) prevents confusion in commit histories.
124-135: Local update ofapp.config.tsis sound
Validating the new build number then updating the config locally ensures the preview build uses the correct metadata.
150-156: Preview EAS submission step
Runningeas build --profile preview --auto-submitagainst the locally bumpedapp.config.tsaligns with the intended preview flow.
| { | ||
| "ios": { | ||
| "production": { | ||
| "buildNumber": 0 // TODO set the right version using eas:version:get (something like this) |
There was a problem hiding this comment.
Fix JSON syntax errors - comments are not valid in JSON.
The TODO comments break JSON parsing and will cause runtime errors when the file is imported by app.config.ts.
Remove the inline comments and fix the JSON syntax:
- "buildNumber": 0 // TODO set the right version using eas:version:get (something like this)
+ "buildNumber": 0Apply this fix to all three iOS environment entries.
Also applies to: 7-7, 10-10
🧰 Tools
🪛 Biome (1.9.4)
[error] 4-4: expected , but instead found // TODO set the right version using eas:version:get (something like this)
Remove // TODO set the right version using eas:version:get (something like this)
(parse)
🤖 Prompt for AI Agents
In versions.json at lines 4, 7, and 10, remove the inline comments from the JSON
entries because JSON does not support comments and these cause parsing errors.
Replace lines like "buildNumber": 0 // TODO ... with just "buildNumber": 0 to
ensure valid JSON syntax for all three iOS environment entries.
| { | ||
| "ios": { | ||
| "production": { | ||
| "buildNumber": 0 // TODO set the right version using eas:version:get (something like this) | ||
| }, | ||
| "preview": { | ||
| "buildNumber": 0 // TODO set the right version using eas:version:get (something like this) | ||
| }, | ||
| "development": { | ||
| "buildNumber": 0 // TODO set the right version using eas:version:get (something like this) | ||
| } | ||
| }, | ||
| "android": { | ||
| "production": { | ||
| "buildCode": 0 | ||
| }, | ||
| "preview": { | ||
| "buildCode": 0 | ||
| }, | ||
| "development": { | ||
| "buildCode": 0 | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Set proper initial version values instead of placeholder zeros.
All version numbers are initialized to 0, which might not reflect the current app store versions. Consider setting these to actual current values to maintain version continuity.
Would you like me to help generate a script to fetch current versions from the app stores or EAS? The TODO comments suggest using eas:version:get command for this purpose.
You can also run this command to get current versions:
🏁 Script executed:
#!/bin/bash
# Get current versions from EAS for each environment
echo "Getting current iOS versions..."
eas version:get --platform=ios --profile=production
eas version:get --platform=ios --profile=preview
eas version:get --platform=ios --profile=development
echo "Getting current Android versions..."
eas version:get --platform=android --profile=production
eas version:get --platform=android --profile=preview
eas version:get --platform=android --profile=developmentLength of output: 1051
Update versions.json with actual build numbers and codes
Please replace all 0 placeholders in versions.json with the real buildNumber (iOS) and buildCode (Android) that match your current App Store and Play Store releases. You’ll need to fetch these values locally, for example by installing and using the EAS CLI:
npm install -g eas-cli
# iOS
eas version:get --platform ios --profile production
eas version:get --platform ios --profile preview
eas version:get --platform ios --profile development
# Android
eas version:get --platform android --profile production
eas version:get --platform android --profile preview
eas version:get --platform android --profile developmentAlternatively, you can look up the current version codes in App Store Connect and Google Play Console and update:
• File: versions.json
– ios.production.buildNumber
– ios.preview.buildNumber
– ios.development.buildNumber
– android.production.buildCode
– android.preview.buildCode
– android.development.buildCode
Ensuring these values are correct will maintain version continuity across your release channels.
🧰 Tools
🪛 Biome (1.9.4)
[error] 4-4: expected , but instead found // TODO set the right version using eas:version:get (something like this)
Remove // TODO set the right version using eas:version:get (something like this)
(parse)
[error] 7-7: expected , but instead found // TODO set the right version using eas:version:get (something like this)
Remove // TODO set the right version using eas:version:get (something like this)
(parse)
[error] 10-10: expected , but instead found // TODO set the right version using eas:version:get (something like this)
Remove // TODO set the right version using eas:version:get (something like this)
(parse)
🤖 Prompt for AI Agents
In versions.json from lines 1 to 24, replace all placeholder zeros for ios
buildNumber and android buildCode with the actual current version numbers for
each environment (production, preview, development). Use the eas-cli commands
eas version:get with the appropriate platform and profile to fetch these values
or retrieve them from App Store Connect and Google Play Console. Update
ios.production.buildNumber, ios.preview.buildNumber,
ios.development.buildNumber, android.production.buildCode,
android.preview.buildCode, and android.development.buildCode accordingly to
maintain version continuity.
| `Successfully updated ${platform}.${env}.${keyToUpdate} to ${newBuildNumber} in versions.json`, | ||
| ) | ||
| // Output the new build number so it can be captured by GitHub Actions | ||
| console.log(`::set-output name=new_build_number::${newBuildNumber}`) |
There was a problem hiding this comment.
Update deprecated GitHub Actions output syntax.
The ::set-output syntax is deprecated and will stop working in future GitHub Actions runners.
Replace with the current syntax:
- console.log(`::set-output name=new_build_number::${newBuildNumber}`)
+ console.log(`new_build_number=${newBuildNumber}` >> process.env.GITHUB_OUTPUT || '/dev/stdout')Or better yet, use the proper environment file approach:
- console.log(`::set-output name=new_build_number::${newBuildNumber}`)
+ if (process.env.GITHUB_OUTPUT) {
+ require('fs').appendFileSync(process.env.GITHUB_OUTPUT, `new_build_number=${newBuildNumber}\n`)
+ } else {
+ console.log(`new_build_number=${newBuildNumber}`)
+ }Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In scripts/update-versions.js at line 66, the use of the deprecated GitHub
Actions output syntax `::set-output` should be replaced. Instead of logging the
output with `::set-output`, write the output value to the file specified by the
environment variable `GITHUB_OUTPUT` using the proper environment file approach.
This involves appending a line with the format
`new_build_number=${newBuildNumber}` to the file path stored in
`process.env.GITHUB_OUTPUT`.
| - name: Update iOS Production Build Number in versions.json | ||
| id: update_versions_json | ||
| run: | | ||
| node scripts/update-versions.js --platform=ios --env=production | ||
| # The script itself uses `::set-output name=new_build_number::VALUE` | ||
|
|
There was a problem hiding this comment.
Deprecation warning: set-output
The update-versions.js script’s internal use of the deprecated ::set-output command will trigger actionlint errors. Please refactor the script to emit:
echo "new_build_number=$VALUE" >> $GITHUB_OUTPUT🧰 Tools
🪛 actionlint (1.7.7)
54-54: workflow command "set-output" was deprecated. use echo "{name}={value}" >> $GITHUB_OUTPUT instead: https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions
(deprecated-commands)
🤖 Prompt for AI Agents
In .github/workflows/promote-to-production.yml around lines 52 to 57, the
update-versions.js script uses the deprecated `::set-output` command to set
outputs, which causes actionlint errors. Modify the script to replace all
instances of `::set-output name=new_build_number::VALUE` with the new syntax by
appending `new_build_number=VALUE` to the file specified by the environment
variable GITHUB_OUTPUT using `echo "new_build_number=$VALUE" >> $GITHUB_OUTPUT`.
| - name: Commit and Push versions.json | ||
| run: | | ||
| if ! git diff --quiet versions.json; then | ||
| echo "versions.json was updated. Committing and pushing..." | ||
| git add versions.json | ||
| COMMIT_MSG="chore: Update iOS preview build number to ${{ steps.update_versions_json_preview.outputs.new_build_number }}" | ||
| git commit -m "$COMMIT_MSG" | ||
| git push origin ${{ github.ref_name }} | ||
| else |
There was a problem hiding this comment.
Infinite loop risk on push trigger
Committing and pushing versions.json to main (or another branch) under a push-triggered workflow will retrigger this same workflow, causing repeated version bumps. Consider limiting the trigger conditions (e.g., exclude pushes made by the bot) or gating commits via if: github.actor != 'github-actions[bot]'.
🤖 Prompt for AI Agents
In .github/workflows/preview-deployment.yml around lines 112 to 120, the current
workflow commits and pushes changes to versions.json on every push, which can
cause an infinite loop by retriggering the workflow. To fix this, add a
condition to skip the commit and push steps if the actor is the GitHub Actions
bot by using an if statement like `if: github.actor != 'github-actions[bot]'`
before running the commit and push commands. This prevents the workflow from
triggering itself repeatedly.
Implement tag-based release process with automated version management using versions.json for iOS and Android builds
Introduces a new release process that transitions from branch-based to tag-based deployments with automated version management. Key changes include:
📍Where to Start
Start with the new versions.json file which defines the structure for version management, then review scripts/update-versions.js which handles the version updating logic.
Macroscope summarized c823def.
Summary by CodeRabbit
New Features
Chores
Documentation