Skip to content

Conversation

@Rohit3523
Copy link
Contributor

@Rohit3523 Rohit3523 commented Jan 8, 2026

Proposed changes

This PR introduce the change where, when a pull request is merged into the develop branch, the CI pipeline will:

  • Collect commit messages from the latest tag (based on creation date)
  • Save the commit messages as a .txt file so the same release notes can be reused for both platforms
  • Trim release notes to meet store limits, App Store allows max 4000 characters and Android allows max 500 characters
  • Upload the generated release notes to both platforms with the build
  • Automatically add external users to the iOS testing group and notify them when the build is available

Build PR Action: https://github.com/RocketChat/Rocket.Chat.ReactNative/actions/runs/20957468091
Build Develop Action: https://github.com/RocketChat/Rocket.Chat.ReactNative/actions/runs/20957466882

Issue(s)

https://rocketchat.atlassian.net/browse/CORE-1634

How to test or reproduce

Screenshots

iOS Build Android Build
Screenshot 2026-01-13 at 10 03 47 PM Screenshot 2026-01-13 at 10 04 14 PM

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • Improvement (non-breaking change which improves a current function)
  • New feature (non-breaking change which adds functionality)
  • Documentation update (if none of the other choices apply)

Checklist

  • I have read the CONTRIBUTING doc
  • I have signed the CLA
  • Lint and unit tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works (if applicable)
  • I have added necessary documentation (if applicable)
  • Any dependent changes have been merged and published in downstream modules

Further comments

Summary by CodeRabbit

  • Chores
    • Added automated changelog generation from commit history
    • Integrated changelog metadata into Android Play Store releases
    • Updated iOS TestFlight uploads to include changelog information
    • Enhanced build workflows to generate and include release notes during app deployment

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 8, 2026

Walkthrough

The PR implements automated changelog generation integrated into the mobile CI/CD pipeline. A new workflow generates changelogs from commits since the latest tag, which is then conditionally downloaded and processed during Android and iOS builds, with truncation logic applied before uploading to Play Store and TestFlight.

Changes

Cohort / File(s) Summary
Changelog Generation & Orchestration
.github/workflows/generate-changelog.yml, .github/workflows/build-develop.yml
New workflow to generate release changelogs from commit history with 15-day artifact retention. Updated develop build workflow to include generate-changelog job as dependency for all mobile builds.
Android Build & Upload
.github/actions/upload-android/action.yml, .github/workflows/build-official-android.yml, android/fastlane/Fastfile
Conditional artifact download for develop trigger; changelog preparation with truncation to 497 bytes and "..." suffix; extended Fastlane logic for multiple trigger/type combinations (beta, experimental_production, official_open_testing); added selective upload flags (skip_upload_metadata, skip_upload_images, etc.). Build version source updated to reference build-android output.
iOS Build & Upload
.github/actions/upload-ios/action.yml, ios/fastlane/Fastfile
Conditional release-changelog artifact download for official+develop; changelog handling with 4000-char truncation; refactored pilot invocation with pilot_options hash; conditional external distribution and tester group assignment based on official flag and changelog presence.

Sequence Diagram(s)

sequenceDiagram
    participant GH as GitHub Actions
    participant GC as generate-changelog
    participant AB as android-build
    participant IB as ios-build
    participant AUA as upload-android
    participant IUA as upload-ios
    participant PS as Play Store
    participant TF as TestFlight

    GH->>GC: Trigger on develop
    GC->>GC: Collect commits since latest tag
    GC->>GC: Generate changelog.txt
    GC->>GH: Upload release-changelog artifact

    par Android Path
        GH->>AB: Build (depends on generate-changelog)
        AB->>AB: Create APK/AAB
        GH->>AUA: Run upload action
        AUA->>GH: Download release-changelog
        AUA->>AUA: Prepare metadata (truncate to 497 bytes)
        AUA->>PS: Upload with changelog via Fastlane
    and iOS Path
        GH->>IB: Build (depends on generate-changelog)
        IB->>IB: Create IPA
        GH->>IUA: Run upload action
        IUA->>GH: Download release-changelog
        IUA->>IUA: Truncate to 4000 chars
        IUA->>TF: Upload with changelog via Fastlane
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Suggested reviewers

  • diegolmello

Poem

🐰 A changelog emerges from the git commits past,
Bundled through workflows, to TestFlight so fast,
Android and iOS in tandem they race,
With truncated tales and metadata grace. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'chore: changelog in beta release' accurately describes the primary change of adding changelog generation and upload for beta releases in the CI pipeline.
Linked Issues check ✅ Passed The PR successfully implements all CORE-1634 requirements: Android official beta testing support with changelog metadata, iOS TestFlight flow for external users with changelog, and both platforms include PR-based changelog with character limits.
Out of Scope Changes check ✅ Passed All changes are directly scoped to CORE-1634 requirements: workflow additions for changelog generation, platform-specific action updates for metadata handling, and fastlane configuration for changelog uploads.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch beta-changelog

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@Rohit3523 Rohit3523 temporarily deployed to official_ios_build January 8, 2026 16:02 — with GitHub Actions Inactive
@Rohit3523 Rohit3523 had a problem deploying to experimental_ios_build January 8, 2026 16:02 — with GitHub Actions Error
@Rohit3523 Rohit3523 temporarily deployed to official_android_build January 8, 2026 16:02 — with GitHub Actions Inactive
@Rohit3523 Rohit3523 had a problem deploying to experimental_android_build January 8, 2026 16:02 — with GitHub Actions Error
@Rohit3523 Rohit3523 had a problem deploying to upload_official_android January 8, 2026 16:30 — with GitHub Actions Error
@github-actions
Copy link

github-actions bot commented Jan 8, 2026

@Rohit3523 Rohit3523 requested a deployment to approve_e2e_testing January 8, 2026 16:34 — with GitHub Actions Waiting
@Rohit3523 Rohit3523 requested a deployment to experimental_ios_build January 8, 2026 16:37 — with GitHub Actions Waiting
@Rohit3523 Rohit3523 requested a deployment to official_ios_build January 8, 2026 16:37 — with GitHub Actions Waiting
@Rohit3523 Rohit3523 requested a deployment to experimental_android_build January 8, 2026 16:37 — with GitHub Actions Waiting
@Rohit3523 Rohit3523 temporarily deployed to official_android_build January 8, 2026 16:37 — with GitHub Actions Inactive
@Rohit3523 Rohit3523 temporarily deployed to upload_official_android January 8, 2026 17:06 — with GitHub Actions Inactive
@Rohit3523 Rohit3523 requested a deployment to approve_e2e_testing January 8, 2026 17:08 — with GitHub Actions Waiting
@Rohit3523 Rohit3523 requested a deployment to experimental_ios_build January 8, 2026 17:11 — with GitHub Actions Waiting
@Rohit3523 Rohit3523 requested a deployment to experimental_android_build January 8, 2026 17:11 — with GitHub Actions Waiting
@Rohit3523 Rohit3523 requested a deployment to official_android_build January 8, 2026 17:11 — with GitHub Actions Waiting
@Rohit3523 Rohit3523 requested a deployment to official_ios_build January 8, 2026 17:11 — with GitHub Actions Waiting
@Rohit3523 Rohit3523 requested a deployment to approve_e2e_testing January 8, 2026 17:55 — with GitHub Actions Waiting
@Rohit3523 Rohit3523 requested a deployment to approve_e2e_testing January 8, 2026 18:04 — with GitHub Actions Waiting
@Rohit3523 Rohit3523 requested a deployment to official_ios_build January 8, 2026 18:07 — with GitHub Actions Waiting
@Rohit3523 Rohit3523 requested a deployment to experimental_android_build January 8, 2026 18:07 — with GitHub Actions Waiting
@Rohit3523 Rohit3523 temporarily deployed to official_ios_build January 13, 2026 12:57 — with GitHub Actions Inactive
@Rohit3523 Rohit3523 deployed to experimental_android_build January 13, 2026 12:57 — with GitHub Actions Active
@Rohit3523 Rohit3523 temporarily deployed to experimental_ios_build January 13, 2026 12:57 — with GitHub Actions Inactive
@Rohit3523 Rohit3523 deployed to official_android_build January 13, 2026 12:57 — with GitHub Actions Active
@Rohit3523 Rohit3523 deployed to upload_official_android January 13, 2026 15:40 — with GitHub Actions Active
@Rohit3523 Rohit3523 deployed to upload_experimental_android January 13, 2026 15:41 — with GitHub Actions Active
@Rohit3523 Rohit3523 temporarily deployed to upload_official_ios January 13, 2026 15:41 — with GitHub Actions Inactive
@github-actions
Copy link

@github-actions
Copy link

Android Build Available

Rocket.Chat Experimental 4.69.0.108127

Internal App Sharing: https://play.google.com/apps/test/RQVpXLytHNc/ahAO29uNTLjf15VmIQmjjtsjvFhrbNCvEF8qSn5_WCpWXUKBuXLWVrX0nbcfqEBuN8Fya3Vy84CdsRCh08m-O5cX3B

@github-actions
Copy link

iOS Build Available

Rocket.Chat Experimental 4.69.0.108125

@github-actions
Copy link

Android Build Available

Rocket.Chat 4.69.0.108124

@github-actions
Copy link

Android Build Available

Rocket.Chat Experimental 4.69.0.108127

@github-actions
Copy link

iOS Build Available

Rocket.Chat 4.69.0.108126

@Rohit3523 Rohit3523 requested a deployment to approve_e2e_testing January 13, 2026 16:40 — with GitHub Actions Waiting
name: Upload
runs-on: ubuntu-latest
needs: [upload-hold]
needs: [build-android, upload-hold]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This change has been made, so I can access BUILD_VERSION from the build-android step

@Rohit3523 Rohit3523 requested a deployment to official_android_build January 13, 2026 16:42 — with GitHub Actions Waiting
@Rohit3523 Rohit3523 requested a deployment to experimental_ios_build January 13, 2026 16:42 — with GitHub Actions Waiting
@Rohit3523 Rohit3523 requested a deployment to experimental_android_build January 13, 2026 16:42 — with GitHub Actions Waiting
@Rohit3523 Rohit3523 marked this pull request as ready for review January 13, 2026 16:44
Copy link
Contributor

@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

🤖 Fix all issues with AI agents
In @.github/actions/upload-android/action.yml:
- Around line 62-81: The changelog handling uses byte-based wc -c/head -c and
unquoted $BUILD_VERSION which can break UTF-8 and fail for names with spaces;
update the script to perform character-based truncation (e.g., use a UTF-8 aware
tool such as awk/printf or a short python/perl one-liner to take the first 500
characters and append "..." only when truncated) instead of wc -c/head -c, and
always quote variables and paths (use "$BUILD_VERSION", quote file expansions
like "android/fastlane/metadata/android/en-US/changelogs/$BUILD_VERSION.txt" and
"changelog.txt") so multi-byte characters remain valid and filenames with
special characters are safe.

In @.github/workflows/generate-changelog.yml:
- Around line 17-26: The workflow currently sets LATEST_RELEASE_TAG and always
runs git log "$LATEST_RELEASE_TAG"..HEAD which expands to an empty range when
there are no tags; modify the "Generate changelog" step to check if
LATEST_RELEASE_TAG is empty and use a different git-log invocation in that case
(e.g., git log --pretty=format:"- %s" --no-merges HEAD > changelog.txt),
otherwise keep the existing git log "$LATEST_RELEASE_TAG"..HEAD > changelog.txt;
ensure the guard uses the LATEST_RELEASE_TAG variable and still writes a
fallback "- Improvements and bug fixes" to changelog.txt if the resulting file
is empty.
🧹 Nitpick comments (3)
.github/actions/upload-ios/action.yml (1)

112-116: Consider adding a descriptive step name for clarity in workflow logs.

The step works correctly but lacks a name field, which makes debugging workflow runs harder.

Suggested improvement
-    - uses: actions/download-artifact@v4
+    - name: Download release changelog
+      uses: actions/download-artifact@v4
       if: ${{ inputs.type == 'official' && inputs.trigger == 'develop' }}
       with:
         name: release-changelog
         path: .
ios/fastlane/Fastfile (1)

57-57: Consider extracting the hardcoded group name.

The "External Testers" group name is hardcoded. If this needs to change or vary by environment, consider extracting it to an environment variable or constant.

.github/actions/upload-android/action.yml (1)

56-61: Consider handling missing artifact gracefully.

If the release-changelog artifact is missing or the generate-changelog job failed, this step will fail the entire workflow. Consider adding continue-on-error: true if a fallback changelog is acceptable, since line 77 already handles the missing changelog.txt case.

💡 Optional: Add continue-on-error for graceful fallback
     - uses: actions/download-artifact@v4
       if: ${{ inputs.trigger == 'develop' }}
+      continue-on-error: true
       with:
         name: release-changelog
         path: .
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ede2569 and fa430f6.

📒 Files selected for processing (7)
  • .github/actions/upload-android/action.yml
  • .github/actions/upload-ios/action.yml
  • .github/workflows/build-develop.yml
  • .github/workflows/build-official-android.yml
  • .github/workflows/generate-changelog.yml
  • android/fastlane/Fastfile
  • ios/fastlane/Fastfile
🧰 Additional context used
🪛 RuboCop (1.82.1)
ios/fastlane/Fastfile

[warning] 39-39: Useless assignment to variable - api_key.

(Lint/UselessAssignment)

🔇 Additional comments (9)
android/fastlane/Fastfile (1)

81-85: LGTM! Upload options align with changelog strategy.

The configuration correctly enables changelog upload (skip_upload_changelogs: false) while skipping unnecessary metadata, images, and screenshots. This aligns with the PR's goal of including release notes in the beta channel.

.github/workflows/generate-changelog.yml (1)

28-33: Artifact configuration looks good.

The 15-day retention is reasonable for CI artifacts, and the artifact name release-changelog matches what the downstream iOS and Android upload actions expect.

ios/fastlane/Fastfile (3)

32-37: Changelog handling logic is correct.

The path resolution and truncation to 4000 characters (App Store limit) with proper ellipsis handling looks good. The conditional assignment correctly returns nil when the file doesn't exist.


39-44: Static analysis false positive - api_key is used implicitly.

The app_store_connect_api_key action stores the key in Fastlane's lane context, making it automatically available to subsequent actions like pilot. This is standard Fastlane behavior.


46-60: Pilot options configuration is well-structured.

The conditional logic correctly:

  • Waits for build processing only when external distribution is needed (!(options[:official] && changelog))
  • Enables external distribution with proper notification settings when a changelog exists for official builds
.github/workflows/build-official-android.yml (1)

75-88: LGTM! Dependency chain and BUILD_VERSION sourcing are correct.

The changes properly:

  1. Add explicit dependency on build-android to ensure the build completes before upload
  2. Source BUILD_VERSION directly from build-android.outputs rather than through the passthrough in upload-hold, which is cleaner and more maintainable

The conditional logic on line 76 correctly handles both manual approval (PR trigger) and automatic flow (develop trigger) scenarios.

.github/workflows/build-develop.yml (2)

22-60: LGTM! Build job dependencies updated correctly.

All four build jobs (android-build-experimental-store, android-build-official-store, ios-build-experimental-store, ios-build-official-store) now correctly depend on both run-eslint-and-test and generate-changelog, ensuring the changelog artifact is available before builds start.


17-20: LGTM! New changelog generation job is well-structured.

The job correctly depends on run-eslint-and-test and references the reusable workflow. The workflow does not require secrets: inherit—it uses only standard GitHub Actions (checkout, git commands, artifact upload) that work with default permissions.

.github/actions/upload-android/action.yml (1)

83-95: LGTM! Fastlane upload logic correctly handles all trigger/type combinations.

The conditional structure covers all expected cases:

  • pr trigger → beta lane
  • develop + experimental → experimental_production
  • develop + official → official_open_testing

Comment on lines +62 to +81
- name: Prepare Play Store changelog metadata
if: ${{ inputs.trigger == 'develop' }}
run: |
mkdir -p android/fastlane/metadata/android/en-US/changelogs
if [ -f changelog.txt ]; then
size=$(wc -c < changelog.txt)
if [ "$size" -gt 500 ]; then
head -c 497 changelog.txt > android/fastlane/metadata/android/en-US/changelogs/$BUILD_VERSION.txt
printf "..." >> android/fastlane/metadata/android/en-US/changelogs/$BUILD_VERSION.txt
else
cat changelog.txt > android/fastlane/metadata/android/en-US/changelogs/$BUILD_VERSION.txt
fi
else
printf "Internal improvements and bug fixes" > android/fastlane/metadata/android/en-US/changelogs/$BUILD_VERSION.txt
fi
shell: bash
env:
BUILD_VERSION: ${{ inputs.BUILD_VERSION }}
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 | 🟡 Minor

UTF-8 truncation may produce invalid characters; variables should be quoted.

Two issues:

  1. Byte vs character mismatch: Play Store limit is 500 characters, but wc -c counts bytes and head -c truncates at byte boundaries. For multi-byte UTF-8 characters (e.g., emojis, accented letters), this could:

    • Truncate mid-character, producing invalid UTF-8
    • Under-count actual characters, leaving room unused
  2. Unquoted variables: $BUILD_VERSION should be quoted to handle unexpected characters safely.

🔧 Proposed fix with character-based truncation
     - name: Prepare Play Store changelog metadata
       if: ${{ inputs.trigger == 'develop' }}
       run: |
         mkdir -p android/fastlane/metadata/android/en-US/changelogs

         if [ -f changelog.txt ]; then
-          size=$(wc -c < changelog.txt)
+          # Count characters, not bytes (for UTF-8 safety)
+          char_count=$(wc -m < changelog.txt)

-          if [ "$size" -gt 500 ]; then
-            head -c 497 changelog.txt > android/fastlane/metadata/android/en-US/changelogs/$BUILD_VERSION.txt
-            printf "..." >> android/fastlane/metadata/android/en-US/changelogs/$BUILD_VERSION.txt
+          if [ "$char_count" -gt 500 ]; then
+            # Truncate by characters to avoid breaking UTF-8
+            cut -c1-497 changelog.txt > "android/fastlane/metadata/android/en-US/changelogs/${BUILD_VERSION}.txt"
+            printf "..." >> "android/fastlane/metadata/android/en-US/changelogs/${BUILD_VERSION}.txt"
           else
-            cat changelog.txt > android/fastlane/metadata/android/en-US/changelogs/$BUILD_VERSION.txt
+            cat changelog.txt > "android/fastlane/metadata/android/en-US/changelogs/${BUILD_VERSION}.txt"
           fi
         else
-          printf "Internal improvements and bug fixes" > android/fastlane/metadata/android/en-US/changelogs/$BUILD_VERSION.txt
+          printf "Internal improvements and bug fixes" > "android/fastlane/metadata/android/en-US/changelogs/${BUILD_VERSION}.txt"
         fi
       shell: bash
       env:
         BUILD_VERSION: ${{ inputs.BUILD_VERSION }}
🤖 Prompt for AI Agents
In @.github/actions/upload-android/action.yml around lines 62 - 81, The
changelog handling uses byte-based wc -c/head -c and unquoted $BUILD_VERSION
which can break UTF-8 and fail for names with spaces; update the script to
perform character-based truncation (e.g., use a UTF-8 aware tool such as
awk/printf or a short python/perl one-liner to take the first 500 characters and
append "..." only when truncated) instead of wc -c/head -c, and always quote
variables and paths (use "$BUILD_VERSION", quote file expansions like
"android/fastlane/metadata/android/en-US/changelogs/$BUILD_VERSION.txt" and
"changelog.txt") so multi-byte characters remain valid and filenames with
special characters are safe.

Comment on lines +17 to +26
- name: Generate changelog
shell: bash
run: |
LATEST_RELEASE_TAG=$(git tag --sort=-creatordate | head -n 1)
git log "$LATEST_RELEASE_TAG"..HEAD --pretty=format:"- %s" --no-merges > changelog.txt
if [ ! -s changelog.txt ]; then
echo "- Improvements and bug fixes" > changelog.txt
fi
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 | 🟡 Minor

Handle the case when no tags exist in the repository.

If the repository has no tags, LATEST_RELEASE_TAG will be empty, causing git log ""..HEAD to output the entire commit history, which could be unexpectedly large. Consider adding a guard:

Proposed fix
         run: |
           LATEST_RELEASE_TAG=$(git tag --sort=-creatordate | head -n 1)
 
+          if [ -z "$LATEST_RELEASE_TAG" ]; then
+            echo "- Improvements and bug fixes" > changelog.txt
+            exit 0
+          fi
+
           git log "$LATEST_RELEASE_TAG"..HEAD --pretty=format:"- %s" --no-merges > changelog.txt
 
           if [ ! -s changelog.txt ]; then
             echo "- Improvements and bug fixes" > changelog.txt
           fi
🤖 Prompt for AI Agents
In @.github/workflows/generate-changelog.yml around lines 17 - 26, The workflow
currently sets LATEST_RELEASE_TAG and always runs git log
"$LATEST_RELEASE_TAG"..HEAD which expands to an empty range when there are no
tags; modify the "Generate changelog" step to check if LATEST_RELEASE_TAG is
empty and use a different git-log invocation in that case (e.g., git log
--pretty=format:"- %s" --no-merges HEAD > changelog.txt), otherwise keep the
existing git log "$LATEST_RELEASE_TAG"..HEAD > changelog.txt; ensure the guard
uses the LATEST_RELEASE_TAG variable and still writes a fallback "- Improvements
and bug fixes" to changelog.txt if the resulting file is empty.

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.

2 participants