-
Notifications
You must be signed in to change notification settings - Fork 277
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
AND-116: SDK size reporting (APK comparison) (#5539)
* Compare APKs to calculate SDK sizes * Use release to build the comparison table * Trigger updates on merging to develop * changes after rebasing from develop which contains version catalog and kts refactoring * add a single android application project for metrics * rename build flavors to simplify logic in the CI script * check sizes using the single metrics android project * update sizes using the single metrics android project * Update SDK size metrics * Update SDK size badges * Remove test setup * Add a README note for the SDK sizes * Use GITHUB_TOKEN instead of the personal token * test * Fix * Push changes * Remove multiple metrics modules * Remove test setup --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
- Loading branch information
1 parent
521b42f
commit e71d2ce
Showing
9 changed files
with
375 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
name: SDK size checks | ||
|
||
on: | ||
pull_request: | ||
|
||
env: | ||
METRICS_PROJECT: "stream-chat-android-metrics" | ||
MODULES: "stream-chat-android-client stream-chat-android-offline stream-chat-android-ui-components stream-chat-android-compose" | ||
METRICS_FILE: "metrics/size.json" | ||
MAX_TOLERANCE: 500 | ||
FINE_TOLERANCE: 250 | ||
|
||
jobs: | ||
compare-sdk-sizes: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v3 | ||
- uses: ./.github/actions/setup-java | ||
- uses: ./.github/actions/gradle-cache | ||
with: | ||
key-prefix: gradle-build | ||
|
||
- name: Assemble release for metrics | ||
run: ./gradlew :metrics:$METRICS_PROJECT:assembleRelease | ||
|
||
- name: Get current SDK sizes | ||
run: | | ||
# Reads current SDK sizes from the metrics file | ||
# and define to a variable using a compact JSON format | ||
# so it can be exported for the next job step | ||
CURRENT_SDK_SIZES=$(jq -c .release $METRICS_FILE) | ||
echo "CURRENT_SDK_SIZES=$CURRENT_SDK_SIZES" >> $GITHUB_ENV | ||
- name: Calculate PR branch SDK sizes | ||
run: | | ||
echo '{}' > pr_sdk_sizes.json | ||
# Calculate sizes from the .apk files and save them into a temporary JSON file | ||
# so it can be exported for the next job step | ||
for module in $MODULES; do | ||
baselineFile="metrics/$METRICS_PROJECT/build/outputs/apk/$module-baseline/release/$METRICS_PROJECT-$module-baseline-release.apk" | ||
streamFile="metrics/$METRICS_PROJECT/build/outputs/apk/$module-stream/release/$METRICS_PROJECT-$module-stream-release.apk" | ||
baselineSize=$(du -k "$baselineFile" | awk '{print $1}') | ||
streamSize=$(du -k "$streamFile" | awk '{print $1}') | ||
size=$((streamSize - baselineSize)) | ||
jq -c --arg sdk "$module" --arg size "$size" '. + {($sdk): ($size | tonumber)}' pr_sdk_sizes.json > temp.json && mv temp.json pr_sdk_sizes.json | ||
done | ||
echo "PR_SDK_SIZES=$(cat pr_sdk_sizes.json)" >> $GITHUB_ENV | ||
- name: Post comment on PR | ||
uses: actions/github-script@v6 | ||
with: | ||
script: | | ||
const maxTolerance = process.env.MAX_TOLERANCE | ||
const fineTolerance = process.env.FINE_TOLERANCE | ||
const currentSdkSizes = process.env.CURRENT_SDK_SIZES ? JSON.parse(process.env.CURRENT_SDK_SIZES) : {}; | ||
const prSdkSizes = JSON.parse(process.env.PR_SDK_SIZES); | ||
const commentHeader = '## SDK Size Comparison 📏'; | ||
// Prepare the comparison table | ||
let commentBody = ` | ||
${commentHeader} | ||
| SDK | Before | After | Difference | Status | | ||
|-|-|-|-|-| | ||
`; | ||
Object.keys(prSdkSizes).forEach(sdk => { | ||
const currentSize = currentSdkSizes[sdk] || 0; | ||
const prSize = prSdkSizes[sdk]; | ||
const diff = prSize - currentSize; | ||
const currentSizeInMb = (currentSize / 1024).toFixed(2); | ||
const prSizeInMb = (prSize / 1024).toFixed(2); | ||
const diffInMb = (diff / 1024).toFixed(2); | ||
let status = "🟢"; | ||
if (diff < 0) { | ||
status = "🚀"; | ||
} else if (diff >= maxTolerance) { | ||
status = "🔴"; | ||
} else if (diff >= fineTolerance) { | ||
status = "🟡"; | ||
} | ||
commentBody += `| ${sdk} | ${currentSizeInMb} MB | ${prSizeInMb} MB | ${diffInMb} MB | ${status} |\n`; | ||
}); | ||
// Post or update the PR comment | ||
// Find existing comment | ||
const { data: comments } = await github.rest.issues.listComments({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
issue_number: context.payload.pull_request.number, | ||
}); | ||
const comment = comments.find(c => c.body.includes(commentHeader)); | ||
if (comment) { | ||
// Update the existing comment | ||
await github.rest.issues.updateComment({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
comment_id: comment.id, | ||
body: commentBody, | ||
}); | ||
} else { | ||
// Create a new comment | ||
await github.rest.issues.createComment({ | ||
owner: context.repo.owner, | ||
repo: context.repo.repo, | ||
issue_number: context.payload.pull_request.number, | ||
body: commentBody, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
name: SDK size updates | ||
|
||
on: | ||
push: | ||
branches: | ||
- develop | ||
|
||
workflow_dispatch: | ||
|
||
concurrency: | ||
group: ${{ github.ref }} | ||
cancel-in-progress: true | ||
|
||
env: | ||
METRICS_PROJECT: "stream-chat-android-metrics" | ||
MODULES: "stream-chat-android-client stream-chat-android-offline stream-chat-android-ui-components stream-chat-android-compose" | ||
VARIANTS: "debug release" | ||
METRICS_FILE: "metrics/size.json" | ||
BRANCH_NAME: ${{ github.head_ref || github.ref_name }} | ||
|
||
jobs: | ||
update-sdk-sizes: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v3 | ||
with: | ||
persist-credentials: false | ||
- uses: ./.github/actions/setup-java | ||
- uses: ./.github/actions/gradle-cache | ||
with: | ||
key-prefix: gradle-build | ||
|
||
- name: Assemble release and debug for metrics | ||
run: ./gradlew :metrics:$METRICS_PROJECT:assemble | ||
|
||
- name: Update size metrics | ||
run: | | ||
# Create temporary JSON file | ||
echo '{}' > metrics.json | ||
# Calculate sizes | ||
for module in $MODULES; do | ||
for variant in $VARIANTS; do | ||
baselineFile="metrics/$METRICS_PROJECT/build/outputs/apk/$module-baseline/$variant/$METRICS_PROJECT-$module-baseline-$variant.apk" | ||
streamFile="metrics/$METRICS_PROJECT/build/outputs/apk/$module-stream/$variant/$METRICS_PROJECT-$module-stream-$variant.apk" | ||
# Ensure files exist | ||
if [[ -f "$baselineFile" && -f "$streamFile" ]]; then | ||
baselineSize=$(du -k "$baselineFile" | awk '{print $1}') | ||
streamSize=$(du -k "$streamFile" | awk '{print $1}') | ||
size=$((streamSize - baselineSize)) | ||
else | ||
echo "Warning: $baselineFile or $streamFile not found. Setting size to 0." | ||
size=0 | ||
fi | ||
# Update JSON | ||
jq --arg module "$module" --arg variant "$variant" --argjson size "$size" \ | ||
".\"$variant\".\"$module\" = $size" metrics.json > temp.json && mv temp.json metrics.json | ||
done | ||
done | ||
# Validate Generated JSON | ||
jq . metrics.json | ||
# Move temporary JSON file to the final file | ||
mv metrics.json $METRICS_FILE | ||
- name: Update size badges | ||
run: | | ||
for module in $MODULES; do | ||
size=$(jq --arg module "$module" ".release.\"$module\"" $METRICS_FILE) | ||
sizeInMb=$(echo "scale=2; $size / 1024" | bc) | ||
badgeUrl="https://img.shields.io/badge/${module//-/--}-$sizeInMb%20MB-lightgreen" | ||
sed -i "s|!\[$module\](.*)|![$module](${badgeUrl})|" README.md | ||
done | ||
- name: Commit changes | ||
run: | | ||
git fetch origin $BRANCH_NAME | ||
git checkout $BRANCH_NAME | ||
git config user.name "github-actions[bot]" | ||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | ||
git add $METRICS_FILE README.md | ||
git commit -m "Update SDK sizes" || echo "No changes to commit" | ||
- name: Push changes | ||
uses: ad-m/github-push-action@master | ||
with: | ||
github_token: ${{ secrets.STREAM_PUBLIC_BOT_TOKEN }} | ||
branch: ${{ env.BRANCH_NAME }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"debug": { | ||
"stream-chat-android-client": 15036, | ||
"stream-chat-android-offline": 15336, | ||
"stream-chat-android-ui-components": 21028, | ||
"stream-chat-android-compose": 22716 | ||
}, | ||
"release": { | ||
"stream-chat-android-client": 3116, | ||
"stream-chat-android-offline": 3324, | ||
"stream-chat-android-ui-components": 8096, | ||
"stream-chat-android-compose": 9256 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
plugins { | ||
alias(libs.plugins.android.application) | ||
alias(libs.plugins.kotlin.android) | ||
} | ||
|
||
apply(from = "$rootDir/scripts/android.gradle") | ||
|
||
android { | ||
namespace = "io.getstream.chat.android.metrics" | ||
buildTypes { | ||
release { | ||
signingConfig = signingConfigs.findByName("debug") | ||
} | ||
} | ||
|
||
flavorDimensions += "sdk" | ||
|
||
productFlavors { | ||
create("stream-chat-android-client-baseline") { | ||
dimension = "sdk" | ||
} | ||
create("stream-chat-android-client-stream") { | ||
dimension = "sdk" | ||
} | ||
create("stream-chat-android-offline-baseline") { | ||
dimension = "sdk" | ||
} | ||
create("stream-chat-android-offline-stream") { | ||
dimension = "sdk" | ||
} | ||
create("stream-chat-android-compose-baseline") { | ||
dimension = "sdk" | ||
} | ||
create("stream-chat-android-compose-stream") { | ||
dimension = "sdk" | ||
} | ||
create("stream-chat-android-ui-components-baseline") { | ||
dimension = "sdk" | ||
} | ||
create("stream-chat-android-ui-components-stream") { | ||
dimension = "sdk" | ||
} | ||
} | ||
} | ||
|
||
afterEvaluate { | ||
android.productFlavors.forEach { flavor -> | ||
val flavorName = flavor.name | ||
// For compose flavors, we apply the compose plugin, | ||
// set up build features and add common compose dependencies. | ||
if (flavorName.contains("compose")) { | ||
val composePlugin = libs.plugins.kotlin.compose.get() | ||
plugins.apply(composePlugin.pluginId) | ||
android.buildFeatures.compose = true | ||
val configurationName = "${flavorName}Implementation" | ||
dependencies.add(configurationName, libs.androidx.compose.ui) | ||
dependencies.add(configurationName, libs.androidx.compose.ui.tooling) | ||
dependencies.add(configurationName, libs.androidx.compose.foundation) | ||
dependencies.add(configurationName, libs.androidx.activity.compose) | ||
dependencies.add(configurationName, libs.androidx.lifecycle.runtime.compose) | ||
dependencies.add(configurationName, libs.androidx.lifecycle.viewmodel.compose) | ||
} | ||
} | ||
} | ||
|
||
dependencies { | ||
detektPlugins(libs.detekt.formatting) | ||
implementation(libs.kotlinx.coroutines.core) | ||
implementation(libs.androidx.appcompat) | ||
|
||
"stream-chat-android-client-streamImplementation"(project(":stream-chat-android-client")) | ||
|
||
"stream-chat-android-offline-streamImplementation"(project(":stream-chat-android-offline")) | ||
|
||
"stream-chat-android-ui-components-streamImplementation"(project(":stream-chat-android-ui-components")) | ||
|
||
"stream-chat-android-compose-streamImplementation"(project(":stream-chat-android-compose")) | ||
} |
33 changes: 33 additions & 0 deletions
33
metrics/stream-chat-android-metrics/src/main/AndroidManifest.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<!-- | ||
Copyright (c) 2014-2024 Stream.io Inc. All rights reserved. | ||
Licensed under the Stream License; | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
https://github.com/GetStream/stream-chat-android/blob/main/LICENSE | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
--> | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
> | ||
|
||
<application> | ||
<activity | ||
android:name=".MainActivity" | ||
android:exported="true" | ||
> | ||
<intent-filter> | ||
<action android:name="android.intent.action.MAIN" /> | ||
|
||
<category android:name="android.intent.category.LAUNCHER" /> | ||
</intent-filter> | ||
</activity> | ||
</application> | ||
|
||
</manifest> |
21 changes: 21 additions & 0 deletions
21
...am-chat-android-metrics/src/main/kotlin/io/getstream/chat/android/metrics/MainActivity.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/* | ||
* Copyright (c) 2014-2024 Stream.io Inc. All rights reserved. | ||
* | ||
* Licensed under the Stream License; | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://github.com/GetStream/stream-chat-android/blob/main/LICENSE | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package io.getstream.chat.android.metrics | ||
|
||
import androidx.activity.ComponentActivity | ||
|
||
class MainActivity : ComponentActivity() |
Oops, something went wrong.