Skip to content

Commit 6bbf88a

Browse files
authored
ci: add PR-build changelog for TestFlight and Play Store (#7411)
1 parent bf1dbdb commit 6bbf88a

7 files changed

Lines changed: 102 additions & 28 deletions

File tree

.github/actions/upload-android/action.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,20 @@ runs:
3838
shell: bash
3939

4040
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
41-
if: ${{ inputs.trigger == 'develop' }}
41+
if: ${{ inputs.trigger == 'develop' || inputs.trigger == 'pr' }}
4242
with:
4343
name: release-changelog
4444
path: .
4545

4646
- name: Prepare Play Store changelog metadata
47-
if: ${{ inputs.trigger == 'develop' }}
47+
if: ${{ inputs.trigger == 'develop' || inputs.trigger == 'pr' }}
4848
run: |
4949
mkdir -p android/fastlane/metadata/android/en-US/changelogs
5050
51-
if [ -f changelog.txt ]; then
52-
node .github/scripts/prepare-changelog.js
51+
if [[ "${{ inputs.trigger }}" == "pr" ]]; then
52+
cp changelog.txt "android/fastlane/metadata/android/en-US/changelogs/${BUILD_VERSION}.txt"
53+
elif [ -f changelog.txt ]; then
54+
node .github/scripts/changelog.js cap
5355
else
5456
printf "Internal improvements and bug fixes" > "android/fastlane/metadata/android/en-US/changelogs/${BUILD_VERSION}.txt"
5557
fi

.github/actions/upload-ios/action.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ runs:
8383
shell: bash
8484

8585
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
86-
if: ${{ inputs.trigger == 'develop' }}
86+
if: ${{ inputs.trigger == 'develop' || inputs.trigger == 'pr' }}
8787
with:
8888
name: release-changelog
8989
path: .
@@ -100,6 +100,7 @@ runs:
100100
APP_STORE_CONNECT_API_KEY_ID: ${{ inputs.APP_STORE_CONNECT_API_KEY_ID }}
101101
APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ inputs.APP_STORE_CONNECT_API_KEY_ISSUER_ID }}
102102
FASTLANE_REPO_PAT: ${{ inputs.FASTLANE_REPO_PAT }}
103+
TRIGGER: ${{ inputs.trigger }}
103104
shell: bash
104105

105106
- name: Extract version info from Info.plist

.github/scripts/changelog.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
"use strict";
2+
const fs = require("fs");
3+
4+
const segmenter = new Intl.Segmenter("en", { granularity: "grapheme" });
5+
6+
function graphemes(str) {
7+
return Array.from(segmenter.segment(str), s => s.segment);
8+
}
9+
10+
// Hard-cap to `limit` graphemes. When `ellipsis` is true, reserve 3 graphemes
11+
// for a trailing "..." (matches the legacy Play Store preparer). Assumes
12+
// limit >= 4 when ellipsis is true.
13+
function capGraphemes(str, limit, { ellipsis = false } = {}) {
14+
const chars = graphemes(str);
15+
if (chars.length <= limit) return str;
16+
if (ellipsis) return chars.slice(0, limit - 3).join("") + "...";
17+
return chars.slice(0, limit).join("");
18+
}
19+
20+
function formatPrChangelog({ title, number, commits }) {
21+
const header = `${title} (#${number})`;
22+
// Reverse to newest-first; gh pr view --json commits returns oldest-first
23+
const rows = [...commits].reverse().map(c => `${c.oid.slice(0, 7)} ${c.messageHeadline}`);
24+
25+
const build = rs => (rs.length > 0 ? [header, "", ...rs] : [header]).join("\n");
26+
27+
let output = build(rows);
28+
if (graphemes(output).length <= 500) return output;
29+
30+
// Drop oldest rows (end of newest-first list) until within limit
31+
while (rows.length > 0) {
32+
rows.pop();
33+
output = build(rows);
34+
if (graphemes(output).length <= 500) return output;
35+
}
36+
37+
// Header alone exceeds 500: hard-slice, no ellipsis
38+
return capGraphemes(output, 500);
39+
}
40+
41+
module.exports = { formatPrChangelog, capGraphemes, graphemes };
42+
43+
if (require.main === module) {
44+
const mode = process.argv[2];
45+
46+
if (mode === "pr") {
47+
const pr = JSON.parse(fs.readFileSync("pr.json", "utf8"));
48+
fs.writeFileSync("changelog.txt", formatPrChangelog(pr), "utf8");
49+
} else if (mode === "cap") {
50+
const buildVersion = process.env.BUILD_VERSION;
51+
const input = fs.readFileSync("changelog.txt", "utf8");
52+
fs.writeFileSync(
53+
`android/fastlane/metadata/android/en-US/changelogs/${buildVersion}.txt`,
54+
capGraphemes(input, 500, { ellipsis: true }),
55+
"utf8"
56+
);
57+
} else {
58+
console.error(`Unknown mode "${mode}". Usage: node changelog.js <pr|cap>`);
59+
process.exit(1);
60+
}
61+
}

.github/scripts/prepare-changelog.js

Lines changed: 0 additions & 20 deletions
This file was deleted.

.github/workflows/build-pr.yml

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,34 @@ jobs:
1919
if: ${{ github.repository == 'RocketChat/Rocket.Chat.ReactNative' }}
2020
uses: ./.github/workflows/eslint.yml
2121

22+
generate-pr-changelog:
23+
name: Generate PR Changelog
24+
needs: [run-eslint-and-test]
25+
if: ${{ github.repository == 'RocketChat/Rocket.Chat.ReactNative' }}
26+
runs-on: ubuntu-latest
27+
steps:
28+
- name: Checkout Repository
29+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
30+
31+
- name: Generate changelog
32+
env:
33+
GH_TOKEN: ${{ github.token }}
34+
run: |
35+
gh pr view "${{ github.event.pull_request.number }}" --json title,number,commits > pr.json
36+
node .github/scripts/changelog.js pr
37+
38+
- name: Upload changelog artifact
39+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
40+
with:
41+
name: release-changelog
42+
path: changelog.txt
43+
retention-days: 15
44+
2245
android-build-store:
2346
name: Build Android
2447
if: ${{ github.repository == 'RocketChat/Rocket.Chat.ReactNative' }}
2548
uses: ./.github/workflows/build-android.yml
26-
needs: [run-eslint-and-test]
49+
needs: [run-eslint-and-test, generate-pr-changelog]
2750
secrets: inherit
2851
with:
2952
trigger: "pr"
@@ -32,7 +55,7 @@ jobs:
3255
name: Build iOS
3356
if: ${{ github.repository == 'RocketChat/Rocket.Chat.ReactNative' }}
3457
uses: ./.github/workflows/build-ios.yml
35-
needs: [run-eslint-and-test]
58+
needs: [run-eslint-and-test, generate-pr-changelog]
3659
secrets: inherit
3760
with:
3861
trigger: "pr"

android/fastlane/Fastfile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,11 @@ platform :android do
3737
upload_to_play_store(
3838
package_name: 'chat.rocket.android',
3939
track: 'internal',
40-
aab: 'app/build/outputs/bundle/release/app-release.aab'
40+
aab: 'app/build/outputs/bundle/release/app-release.aab',
41+
skip_upload_metadata: true,
42+
skip_upload_changelogs: false,
43+
skip_upload_images: true,
44+
skip_upload_screenshots: true
4145
)
4246
end
4347

ios/fastlane/Fastfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ platform :ios do
5252

5353
if changelog
5454
pilot_options[:changelog] = changelog
55+
end
56+
57+
if ENV["TRIGGER"] == "develop"
5558
pilot_options[:distribute_external] = true
5659
pilot_options[:notify_external_testers] = true
5760
pilot_options[:groups] = ["External Testers"]

0 commit comments

Comments
 (0)