mirror of
https://github.com/element-hq/element-android
synced 2024-11-27 11:59:12 +03:00
Merge pull request #6478 from vector-im/feature/bma/nightly
Nightly build published on Firebase
This commit is contained in:
commit
4ed24b5571
12 changed files with 214 additions and 2 deletions
48
.github/workflows/nightly.yml
vendored
Normal file
48
.github/workflows/nightly.yml
vendored
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
name: Build and release nightly APK
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
# Every nights at 4
|
||||||
|
- cron: "0 4 * * *"
|
||||||
|
|
||||||
|
env:
|
||||||
|
CI_GRADLE_ARG_PROPERTIES: >
|
||||||
|
-Porg.gradle.jvmargs=-Xmx4g
|
||||||
|
-Porg.gradle.parallel=false
|
||||||
|
--no-daemon
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
nightly:
|
||||||
|
name: Build and publish nightly Gplay APK to Firebase
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Set up Python 3.8
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: 3.8
|
||||||
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.gradle/caches
|
||||||
|
~/.gradle/wrapper
|
||||||
|
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-gradle-
|
||||||
|
- name: Install towncrier
|
||||||
|
run: |
|
||||||
|
python3 -m pip install towncrier
|
||||||
|
- name: Prepare changelog file
|
||||||
|
run: |
|
||||||
|
mv towncrier.toml towncrier.toml.bak
|
||||||
|
sed 's/CHANGES\.md/CHANGES_NIGHTLY\.md/' towncrier.toml.bak > towncrier.toml
|
||||||
|
rm towncrier.toml.bak
|
||||||
|
yes n | towncrier --version nightly
|
||||||
|
- name: Build and upload Gplay Nightly APK
|
||||||
|
run: |
|
||||||
|
./gradlew assembleGplayNightly appDistributionUploadGplayNightly $CI_GRADLE_ARG_PROPERTIES --stacktrace
|
||||||
|
env:
|
||||||
|
ELEMENT_ANDROID_NIGHTLY_KEYID: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_KEYID }}
|
||||||
|
ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD }}
|
||||||
|
ELEMENT_ANDROID_NIGHTLY_STOREPASSWORD: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_STOREPASSWORD }}
|
||||||
|
FIREBASE_TOKEN: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_FIREBASE_TOKEN }}
|
|
@ -24,6 +24,7 @@ buildscript {
|
||||||
classpath libs.gradle.gradlePlugin
|
classpath libs.gradle.gradlePlugin
|
||||||
classpath libs.gradle.kotlinPlugin
|
classpath libs.gradle.kotlinPlugin
|
||||||
classpath libs.gradle.hiltPlugin
|
classpath libs.gradle.hiltPlugin
|
||||||
|
classpath 'com.google.firebase:firebase-appdistribution-gradle:3.0.2'
|
||||||
classpath 'com.google.gms:google-services:4.3.13'
|
classpath 'com.google.gms:google-services:4.3.13'
|
||||||
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.4.0.2513'
|
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.4.0.2513'
|
||||||
classpath 'com.google.android.gms:oss-licenses-plugin:0.10.5'
|
classpath 'com.google.android.gms:oss-licenses-plugin:0.10.5'
|
||||||
|
|
1
changelog.d/6478.misc
Normal file
1
changelog.d/6478.misc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Nightly build publication on Firebase
|
54
docs/nightly_build.md
Normal file
54
docs/nightly_build.md
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
# Nightly builds
|
||||||
|
|
||||||
|
<!--- TOC -->
|
||||||
|
|
||||||
|
* [Configuration](#configuration)
|
||||||
|
* [How to register to get nightly build](#how-to-register-to-get-nightly-build)
|
||||||
|
* [Build nightly manually](#build-nightly-manually)
|
||||||
|
|
||||||
|
<!--- END -->
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
The nightly build will contain what's on develop, in release mode, for Gplay variant. It is signed using a dedicated signature, and has a dedicated appId (`im.vector.app.nightly`), so it can be installed along with the production version of Element Android. The only other difference compared to Element Android is a different app icon background. We do not want to change the app name since it will also affect some strings in the app, and we do want to do that.
|
||||||
|
|
||||||
|
Nightly builds are built and released to Firebase every days, and automatically.
|
||||||
|
|
||||||
|
This is recommended to exclusively use this app, with your main account, instead of Element Android, and fallback to Element Android just in case of regression, to discover as soon as possible any regression, and report it to the team. To avoid double notification, you may want to disable the notification from the Element Android production version. Just open Element Android, navigate to `Settings/Notifications` and uncheck `Enable notifications for this session`.
|
||||||
|
|
||||||
|
*Note:* Due to a limitation of Firebase, the nightly build is the universal build, which means that the size of the APK is a bit bigger, but this should not have any other side effect.
|
||||||
|
|
||||||
|
## How to register to get nightly build
|
||||||
|
|
||||||
|
Provide your email to the Android team, who will add it to the list "External testers" on Firebase. You will then receive an invite on the provided email.
|
||||||
|
|
||||||
|
Follow the instructions on the email to install the latest nightly build. This is not clear yet if new nightly build will be automatically installed or not.
|
||||||
|
|
||||||
|
## Build nightly manually
|
||||||
|
|
||||||
|
Nightly build can be built manually from your computer. You will need to retrieved some secrets from Passbolt and add them to your file `~/.gradle/gradle.properties`:
|
||||||
|
|
||||||
|
```
|
||||||
|
signing.element.nightly.storePassword=VALUE_FROM_PASSBOLT
|
||||||
|
signing.element.nightly.keyId=VALUE_FROM_PASSBOLT
|
||||||
|
signing.element.nightly.keyPassword=VALUE_FROM_PASSBOLT
|
||||||
|
```
|
||||||
|
|
||||||
|
You will also need to add the environment variable `FIREBASE_TOKEN`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
export FIREBASE_TOKEN=VALUE_FROM_PASSBOLT
|
||||||
|
```
|
||||||
|
|
||||||
|
Then you can run the following commands (which are also used in the file for [the GitHub action](../.github/workflows/nightly.yml)):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git checkout develop
|
||||||
|
mv towncrier.toml towncrier.toml.bak
|
||||||
|
sed 's/CHANGES\.md/CHANGES_NIGHTLY\.md/' towncrier.toml.bak > towncrier.toml
|
||||||
|
rm towncrier.toml.bak
|
||||||
|
yes n | towncrier --version nightly
|
||||||
|
./gradlew assembleGplayNightly appDistributionUploadGplayNightly $CI_GRADLE_ARG_PROPERTIES --stacktrace
|
||||||
|
```
|
||||||
|
|
||||||
|
Then you can reset the change on the codebase.
|
|
@ -32,3 +32,8 @@ signing.element.storePath=pathTo.keystore
|
||||||
signing.element.storePassword=Secret
|
signing.element.storePassword=Secret
|
||||||
signing.element.keyId=Secret
|
signing.element.keyId=Secret
|
||||||
signing.element.keyPassword=Secret
|
signing.element.keyPassword=Secret
|
||||||
|
|
||||||
|
# Dummy values for signing secrets / nightly
|
||||||
|
signing.element.nightly.storePassword=Secret
|
||||||
|
signing.element.nightly.keyId=Secret
|
||||||
|
signing.element.nightly.keyPassword=Secret
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import com.android.build.OutputFile
|
import com.android.build.OutputFile
|
||||||
|
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
apply plugin: 'com.google.firebase.appdistribution'
|
||||||
apply plugin: 'com.google.android.gms.oss-licenses-plugin'
|
apply plugin: 'com.google.android.gms.oss-licenses-plugin'
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
apply plugin: 'kotlin-parcelize'
|
apply plugin: 'kotlin-parcelize'
|
||||||
|
@ -228,6 +229,12 @@ android {
|
||||||
storeFile file('./signature/debug.keystore')
|
storeFile file('./signature/debug.keystore')
|
||||||
storePassword 'android'
|
storePassword 'android'
|
||||||
}
|
}
|
||||||
|
nightly {
|
||||||
|
keyAlias System.env.ELEMENT_ANDROID_NIGHTLY_KEYID ?: project.property("signing.element.nightly.keyId")
|
||||||
|
keyPassword System.env.ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD ?: project.property("signing.element.nightly.keyPassword")
|
||||||
|
storeFile file('./signature/nightly.keystore')
|
||||||
|
storePassword System.env.ELEMENT_ANDROID_NIGHTLY_STOREPASSWORD ?: project.property("signing.element.nightly.storePassword")
|
||||||
|
}
|
||||||
release {
|
release {
|
||||||
keyAlias project.property("signing.element.keyId")
|
keyAlias project.property("signing.element.keyId")
|
||||||
keyPassword project.property("signing.element.keyPassword")
|
keyPassword project.property("signing.element.keyPassword")
|
||||||
|
@ -240,6 +247,7 @@ android {
|
||||||
debug {
|
debug {
|
||||||
applicationIdSuffix ".debug"
|
applicationIdSuffix ".debug"
|
||||||
resValue "string", "app_name", "Element dbg"
|
resValue "string", "app_name", "Element dbg"
|
||||||
|
resValue "color", "launcher_background", "#0DBD8B"
|
||||||
|
|
||||||
buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false"
|
buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false"
|
||||||
// Set to true if you want to enable strict mode in debug
|
// Set to true if you want to enable strict mode in debug
|
||||||
|
@ -254,10 +262,12 @@ android {
|
||||||
|
|
||||||
release {
|
release {
|
||||||
resValue "string", "app_name", "Element"
|
resValue "string", "app_name", "Element"
|
||||||
|
resValue "color", "launcher_background", "#0DBD8B"
|
||||||
|
|
||||||
buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false"
|
buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false"
|
||||||
buildConfigField "boolean", "ENABLE_STRICT_MODE_LOGS", "false"
|
buildConfigField "boolean", "ENABLE_STRICT_MODE_LOGS", "false"
|
||||||
|
|
||||||
|
// When updating this block, please also update the same block in the `nightly` buildType below
|
||||||
postprocessing {
|
postprocessing {
|
||||||
removeUnusedCode true
|
removeUnusedCode true
|
||||||
removeUnusedResources true
|
removeUnusedResources true
|
||||||
|
@ -268,6 +278,40 @@ android {
|
||||||
}
|
}
|
||||||
// signingConfig signingConfigs.release
|
// signingConfig signingConfigs.release
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nightly {
|
||||||
|
applicationIdSuffix ".nightly"
|
||||||
|
versionNameSuffix "-nightly"
|
||||||
|
|
||||||
|
initWith release
|
||||||
|
// Just override the background color of the launcher icon for the nightly build.
|
||||||
|
resValue "color", "launcher_background", "#07007E"
|
||||||
|
|
||||||
|
// We need to copy paste this block, this is not done automatically by `initWith release`
|
||||||
|
postprocessing {
|
||||||
|
removeUnusedCode true
|
||||||
|
removeUnusedResources true
|
||||||
|
// We do not activate obfuscation as it makes it hard then to read crash reports, and it's a bit useless on an open source project :)
|
||||||
|
obfuscate false
|
||||||
|
optimizeCode true
|
||||||
|
proguardFiles 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
matchingFallbacks = ['release']
|
||||||
|
signingConfig signingConfigs.nightly
|
||||||
|
firebaseAppDistribution {
|
||||||
|
artifactType = "APK"
|
||||||
|
// We upload the universal APK to fix this error:
|
||||||
|
// "App Distribution found more than 1 output file for this variant.
|
||||||
|
// Please contact firebase-support@google.com for help using APK splits with App Distribution."
|
||||||
|
artifactPath = "$rootDir/vector/build/outputs/apk/gplay/nightly/vector-gplay-universal-nightly.apk"
|
||||||
|
// This file will be generated by the GitHub action
|
||||||
|
releaseNotesFile = "CHANGES_NIGHTLY.md"
|
||||||
|
groups = "external-testers"
|
||||||
|
// This should not be required, but if I do not add the appId, I get this error:
|
||||||
|
// "App Distribution halted because it had a problem uploading the APK: [404] Requested entity was not found."
|
||||||
|
appId = "1:912726360885:android:efd8545af52a9f9300427c"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
flavorDimensions "store"
|
flavorDimensions "store"
|
||||||
|
@ -334,6 +378,10 @@ android {
|
||||||
test {
|
test {
|
||||||
java.srcDirs += "src/sharedTest/java"
|
java.srcDirs += "src/sharedTest/java"
|
||||||
}
|
}
|
||||||
|
// Add sourceSets for `release` version when building `nightly`
|
||||||
|
nightly {
|
||||||
|
java.srcDirs += "src/release/java"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
|
|
BIN
vector/signature/nightly.keystore
Normal file
BIN
vector/signature/nightly.keystore
Normal file
Binary file not shown.
40
vector/src/gplay/nightly/google-services.json
Normal file
40
vector/src/gplay/nightly/google-services.json
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
{
|
||||||
|
"project_info": {
|
||||||
|
"project_number": "912726360885",
|
||||||
|
"firebase_url": "https://vector-alpha.firebaseio.com",
|
||||||
|
"project_id": "vector-alpha",
|
||||||
|
"storage_bucket": "vector-alpha.appspot.com"
|
||||||
|
},
|
||||||
|
"client": [
|
||||||
|
{
|
||||||
|
"client_info": {
|
||||||
|
"mobilesdk_app_id": "1:912726360885:android:4ef8f3a0021e774d",
|
||||||
|
"android_client_info": {
|
||||||
|
"package_name": "im.vector.app.nightly"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "912726360885-e87n3jva9uoj4vbidvijq78ebg02asv2.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"api_key": [
|
||||||
|
{
|
||||||
|
"current_key": "AIzaSyAFZX8IhIfgzdOZvxDP_ISO5WYoU7jmQ5c"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"services": {
|
||||||
|
"appinvite_service": {
|
||||||
|
"other_platform_oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "912726360885-rsae0i66rgqt6ivnudu1pv4tksg9i8b2.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"configuration_version": "1"
|
||||||
|
}
|
|
@ -346,6 +346,9 @@ class BugReporter @Inject constructor(
|
||||||
// Special for Element
|
// Special for Element
|
||||||
builder.addFormDataPart("label", "[Element]")
|
builder.addFormDataPart("label", "[Element]")
|
||||||
|
|
||||||
|
// Possible values for BuildConfig.BUILD_TYPE: "debug", "nightly", "release".
|
||||||
|
builder.addFormDataPart("label", BuildConfig.BUILD_TYPE)
|
||||||
|
|
||||||
when (reportType) {
|
when (reportType) {
|
||||||
ReportType.BUG_REPORT -> {
|
ReportType.BUG_REPORT -> {
|
||||||
/* nop */
|
/* nop */
|
||||||
|
|
|
@ -5,6 +5,6 @@
|
||||||
android:viewportHeight="108">
|
android:viewportHeight="108">
|
||||||
<path
|
<path
|
||||||
android:pathData="m0,0h108v108h-108z"
|
android:pathData="m0,0h108v108h-108z"
|
||||||
android:fillColor="#0DBD8B"
|
android:fillColor="@color/launcher_background"
|
||||||
android:fillType="evenOdd"/>
|
android:fillType="evenOdd"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|
7
vector/src/nightly/res/xml/shortcuts.xml
Normal file
7
vector/src/nightly/res/xml/shortcuts.xml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<share-target android:targetClass="im.vector.app.features.share.IncomingShareActivity">
|
||||||
|
<data android:mimeType="*/*" />
|
||||||
|
<category android:name="im.vector.app.nightly.SHORTCUT_SHARE" />
|
||||||
|
</share-target>
|
||||||
|
</shortcuts>
|
|
@ -19,8 +19,13 @@ package im.vector.app.config
|
||||||
import im.vector.app.BuildConfig
|
import im.vector.app.BuildConfig
|
||||||
import im.vector.app.features.analytics.AnalyticsConfig
|
import im.vector.app.features.analytics.AnalyticsConfig
|
||||||
|
|
||||||
|
private val allowedPackageList = listOf(
|
||||||
|
"im.vector.app",
|
||||||
|
"im.vector.app.nightly",
|
||||||
|
)
|
||||||
|
|
||||||
val analyticsConfig: AnalyticsConfig = object : AnalyticsConfig {
|
val analyticsConfig: AnalyticsConfig = object : AnalyticsConfig {
|
||||||
override val isEnabled = BuildConfig.APPLICATION_ID == "im.vector.app"
|
override val isEnabled = BuildConfig.APPLICATION_ID in allowedPackageList
|
||||||
override val postHogHost = "https://posthog.hss.element.io"
|
override val postHogHost = "https://posthog.hss.element.io"
|
||||||
override val postHogApiKey = "phc_Jzsm6DTm6V2705zeU5dcNvQDlonOR68XvX2sh1sEOHO"
|
override val postHogApiKey = "phc_Jzsm6DTm6V2705zeU5dcNvQDlonOR68XvX2sh1sEOHO"
|
||||||
override val policyLink = "https://element.io/cookie-policy"
|
override val policyLink = "https://element.io/cookie-policy"
|
||||||
|
|
Loading…
Reference in a new issue