mirror of
https://github.com/bitwarden/android.git
synced 2025-12-10 09:56:45 -06:00
Build release bundles and publish to Firebase (#50)
This commit is contained in:
parent
26c22295fc
commit
d32ed06516
60
.github/workflows/build.yml
vendored
60
.github/workflows/build.yml
vendored
@ -76,6 +76,9 @@ jobs:
|
||||
needs:
|
||||
- check
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
matrix:
|
||||
variant: [ "aab", "apk" ]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4.1.4
|
||||
@ -169,6 +172,7 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
- name: Assemble Release APK
|
||||
if: ${{ matrix.variant == 'apk' }}
|
||||
run: |
|
||||
bundle exec fastlane buildRelease \
|
||||
storeFile:${{ github.workspace }}/keystores/authenticator_apk-keystore.jks \
|
||||
@ -178,11 +182,13 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
- name: Create checksum file for Release APK
|
||||
if: ${{ matrix.variant == 'apk' }}
|
||||
run: |
|
||||
sha256sum "app/build/outputs/apk/release/com.bitwarden.authenticator-release.apk" \
|
||||
> ./authenticator-android-apk-sha256.txt
|
||||
|
||||
- name: Upload release APK to GitHub
|
||||
if: ${{ matrix.variant == 'apk' }}
|
||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
|
||||
with:
|
||||
name: com.bitwarden.authenticator.apk
|
||||
@ -190,6 +196,7 @@ jobs:
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload checksum file for Release .apk
|
||||
if: ${{ matrix.variant == 'apk' }}
|
||||
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
|
||||
with:
|
||||
name: authenticator-android-apk-sha256.txt
|
||||
@ -201,10 +208,61 @@ jobs:
|
||||
run: bundle exec fastlane add_plugin firebase_app_distribution
|
||||
|
||||
- name: Publish release APK to Firebase
|
||||
if: ${{ github.ref_name == 'main' }}
|
||||
if: ${{ github.ref_name == 'main' && matrix.variant == 'apk' }}
|
||||
env:
|
||||
FIREBASE_CREDS_PATH: ${{ github.workspace }}/secrets/authenticator_play_firebase-creds.json
|
||||
run: |
|
||||
bundle exec fastlane distributeReleaseToFirebase \
|
||||
serviceCredentialsFile:${{ env.FIREBASE_CREDS_PATH }}
|
||||
shell: bash
|
||||
|
||||
- name: Bundle release AAB
|
||||
if: ${{ matrix.variant == 'aab' }}
|
||||
run: |
|
||||
bundle exec fastlane bundleRelease \
|
||||
storeFile:${{ github.workspace }}/keystores/authenticator_aab-keystore.jks \
|
||||
storePassword:'${{ secrets.AAB_KEYSTORE_STORE_PASSWORD }}' \
|
||||
keyAlias:authenticatorupload \
|
||||
keyPassword:'${{ secrets.AAB_KEYSTORE_KEY_PASSWORD }}'
|
||||
shell: bash
|
||||
|
||||
- name: Create checksum file for Release AAB
|
||||
if: ${{ matrix.variant == 'aab' }}
|
||||
run: |
|
||||
sha256sum "app/build/outputs/bundle/release/com.bitwarden.authenticator-release.aab" \
|
||||
> ./authenticator-android-aab-sha256.txt
|
||||
shell: bash
|
||||
|
||||
- name: Upload release AAB to GitHub
|
||||
if: ${{ matrix.variant == 'aab' }}
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
with:
|
||||
name: com.bitwarden.authenticator.aab
|
||||
path: app/build/outputs/bundle/release/com.bitwarden.authenticator-release.aab
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload checksum file for Release .aab
|
||||
if: ${{ matrix.variant == 'aab' }}
|
||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
|
||||
with:
|
||||
name: authenticator-android-aab-sha256.txt
|
||||
path: ./authenticator-android-aab-sha256.txt
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Publish release AAB to Firebase
|
||||
if: ${{ github.ref_name == 'main' && matrix.variant == 'aab' }}
|
||||
env:
|
||||
FIREBASE_CREDS_PATH: ${{ github.workspace }}/secrets/authenticator_play_firebase-creds.json
|
||||
run: |
|
||||
bundle exec fastlane distributeReleaseBundleToFirebase \
|
||||
serviceCredentialsFile:${{ env.FIREBASE_CREDS_PATH }}
|
||||
shell: bash
|
||||
|
||||
# - name: Publish release AAB to Google Play Store
|
||||
# if: ${{ github.ref_name == 'main' && matrix.variant == 'aab'}}
|
||||
# env:
|
||||
# PLAY_STORE_CREDS_FILE: ${{ github.workspace }}/secrets/authenticator_play_firebase-creds.json
|
||||
# run: |
|
||||
# bundle exec fastlane publishReleaseToGooglePlayStore \
|
||||
# serviceCredentialsFile:${{ env.PLAY_STORE_CREDS_FILE }} \
|
||||
# shell: bash
|
||||
|
||||
@ -61,7 +61,7 @@ android {
|
||||
}
|
||||
packaging {
|
||||
resources {
|
||||
excludes += "/META-INF/{AL2.0,LGPL2.1}"
|
||||
excludes += "/META-INF/{AL2.0,LGPL2.1,LICENSE*.md}"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -124,4 +124,6 @@ dependencies {
|
||||
testImplementation(libs.robolectric.robolectric)
|
||||
testImplementation(libs.square.okhttp.mockwebserver)
|
||||
testImplementation(libs.square.turbine)
|
||||
|
||||
androidTestImplementation(libs.bundles.tests.instrumented)
|
||||
}
|
||||
|
||||
@ -0,0 +1,136 @@
|
||||
package com.x8bit.bitwarden.android.authenticator
|
||||
|
||||
import androidx.compose.ui.test.assertIsDisplayed
|
||||
import androidx.compose.ui.test.isDisplayed
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.test.onNodeWithText
|
||||
import androidx.compose.ui.test.performClick
|
||||
import com.bitwarden.authenticator.ui.platform.feature.settings.appearance.model.AppTheme
|
||||
import com.bitwarden.authenticator.ui.platform.feature.tutorial.TutorialScreen
|
||||
import com.bitwarden.authenticator.ui.platform.feature.tutorial.TutorialViewModel
|
||||
import com.bitwarden.authenticator.ui.platform.theme.AuthenticatorTheme
|
||||
import org.junit.ClassRule
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import tools.fastlane.screengrab.Screengrab
|
||||
import tools.fastlane.screengrab.locale.LocaleTestRule
|
||||
|
||||
class ExampleInstrumentedTest {
|
||||
|
||||
@get:Rule
|
||||
val composeTestRule = createComposeRule()
|
||||
|
||||
@Test
|
||||
fun screenshotTutorialSlides_Dark() {
|
||||
val viewModel = TutorialViewModel()
|
||||
|
||||
composeTestRule.setContent {
|
||||
AuthenticatorTheme(theme = AppTheme.DARK) {
|
||||
TutorialScreen(
|
||||
viewModel = viewModel,
|
||||
onTutorialFinished = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
composeTestRule.waitForIdle()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Continue")
|
||||
.isDisplayed()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Secure your accounts with Bitwarden Authenticator")
|
||||
.isDisplayed()
|
||||
|
||||
Screengrab.screenshot("IntroSlide_Dark")
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Continue")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Use your device camera to scan codes")
|
||||
.assertIsDisplayed()
|
||||
|
||||
Screengrab.screenshot("QrCodeSlide_Dark")
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Continue")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Sign in using unique codes")
|
||||
.assertIsDisplayed()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Continue")
|
||||
.assertDoesNotExist()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Get started")
|
||||
.isDisplayed()
|
||||
|
||||
Screengrab.screenshot("UniqueCodesSlide_Dark")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun screenshotTutorialSlides_Light() {
|
||||
val viewModel = TutorialViewModel()
|
||||
|
||||
composeTestRule.setContent {
|
||||
AuthenticatorTheme(theme = AppTheme.LIGHT) {
|
||||
TutorialScreen(
|
||||
viewModel = viewModel,
|
||||
onTutorialFinished = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
composeTestRule.waitForIdle()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Continue")
|
||||
.isDisplayed()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Secure your accounts with Bitwarden Authenticator")
|
||||
.isDisplayed()
|
||||
|
||||
Screengrab.screenshot("IntroSlide_Light")
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Continue")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Use your device camera to scan codes")
|
||||
.assertIsDisplayed()
|
||||
|
||||
Screengrab.screenshot("QrCodeSlide_Light")
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Continue")
|
||||
.performClick()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Sign in using unique codes")
|
||||
.assertIsDisplayed()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Continue")
|
||||
.assertDoesNotExist()
|
||||
|
||||
composeTestRule
|
||||
.onNodeWithText("Get started")
|
||||
.isDisplayed()
|
||||
|
||||
Screengrab.screenshot("UniqueCodesSlide_Light")
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
@ClassRule
|
||||
val localeTestRule: LocaleTestRule = LocaleTestRule()
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,14 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<!-- Allows unlocking your device and activating its screen so UI tests can succeed -->
|
||||
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
|
||||
<!-- Allows changing locales -->
|
||||
<uses-permission
|
||||
android:name="android.permission.CHANGE_CONFIGURATION"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
<application tools:ignore="MissingApplicationIcon">
|
||||
<!-- Disable Crashlytics for debug builds -->
|
||||
<meta-data
|
||||
|
||||
@ -1,2 +1 @@
|
||||
json_key_file("secrets/authenticator_play_firebase-creds.json") # Path to the json secret file
|
||||
package_name("com.bitwarden.authenticator")
|
||||
|
||||
@ -42,7 +42,7 @@ platform :android do
|
||||
# Current date used to derive next version name.
|
||||
currentDate = Time.new
|
||||
major = currentDate.year.to_s
|
||||
minor = currentDate.strftime "%m"
|
||||
minor = "5"
|
||||
|
||||
# Determine the next revision number to apply.
|
||||
revision = 0
|
||||
@ -94,8 +94,42 @@ platform :android do
|
||||
)
|
||||
end
|
||||
|
||||
desc "Bundle and sign release AAB"
|
||||
lane :bundleRelease do |options|
|
||||
gradle(
|
||||
task: "bundle",
|
||||
build_type: "Release",
|
||||
properties: {
|
||||
"android.injected.signing.store.file" => options[:storeFile],
|
||||
"android.injected.signing.store.password" => options[:storePassword],
|
||||
"android.injected.signing.key.alias" => options[:keyAlias],
|
||||
"android.injected.signing.key.password" => options[:keyPassword]
|
||||
},
|
||||
print_command: false,
|
||||
)
|
||||
end
|
||||
|
||||
desc "Publish release to Firebase"
|
||||
lane :distributeReleaseToFirebase do |options|
|
||||
lane :distributeReleaseToFirebase do |options|
|
||||
release_notes = changelog_from_git_commits(
|
||||
commits_count: 1,
|
||||
pretty: "- %s"
|
||||
)
|
||||
|
||||
puts "Release notes #{release_notes}"
|
||||
|
||||
firebase_app_distribution(
|
||||
app: "1:867301491091:android:50b626dba42a361651e866",
|
||||
android_artifact_type: "APK",
|
||||
android_artifact_path: "app/build/outputs/apk/release/com.bitwarden.authenticator-release.apk",
|
||||
service_credentials_file: options[:serviceCredentialsFile],
|
||||
groups: "internal-prod-group",
|
||||
release_notes: release_notes,
|
||||
)
|
||||
end
|
||||
|
||||
desc "Publish release AAB to Firebase"
|
||||
lane :distributeReleaseBundleToFirebase do |options|
|
||||
release_notes = changelog_from_git_commits(
|
||||
commits_count: 1,
|
||||
pretty: "- %s"
|
||||
@ -105,11 +139,21 @@ platform :android do
|
||||
|
||||
firebase_app_distribution(
|
||||
app: "1:867301491091:android:50b626dba42a361651e866",
|
||||
android_artifact_type: "APK",
|
||||
android_artifact_path: "app/build/outputs/apk/release/com.bitwarden.authenticator-release.apk",
|
||||
android_artifact_type: "AAB",
|
||||
android_artifact_path: "app/build/outputs/bundle/release/com.bitwarden.authenticator-release.aab",
|
||||
service_credentials_file: options[:serviceCredentialsFile],
|
||||
groups: "internal-prod-group",
|
||||
release_notes: release_notes,
|
||||
)
|
||||
end
|
||||
|
||||
desc "Publish release to Google Play Store"
|
||||
lane :publishReleaseToGooglePlayStore do |options|
|
||||
upload_to_play_store(
|
||||
json_key: options[:serviceCredentialsFile],
|
||||
track: "internal",
|
||||
aab: "app/build/outputs/bundle/release/com.bitwarden.authenticator-release.aab",
|
||||
mapping: "app/build/outputs/mapping/release/mapping.txt",
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@ -13,6 +13,7 @@ androidXBiometrics = "1.2.0-alpha05"
|
||||
androidxBrowser = "1.8.0"
|
||||
androidxCamera = "1.3.2"
|
||||
androidxComposeBom = "2024.04.01"
|
||||
androidxComposeUiTest = "1.6.6"
|
||||
androidxCore = "1.12.0"
|
||||
androidxHiltNavigationCompose = "1.2.0"
|
||||
androidxLifecycle = "2.7.0"
|
||||
@ -20,11 +21,14 @@ androidxNavigation = "2.7.7"
|
||||
androidxRoom = "2.6.1"
|
||||
androidXSecurityCrypto = "1.1.0-alpha06"
|
||||
androidxSplash = "1.1.0-rc01"
|
||||
androidxTest = "1.5.0"
|
||||
androidXAppCompat = "1.6.1"
|
||||
androdixAutofill = "1.1.0"
|
||||
androidxWork = "2.9.0"
|
||||
bitwardenSdk = "0.4.0-20240314.115913-173"
|
||||
crashlytics = "2.9.9"
|
||||
espresso = "3.5.1"
|
||||
fastlaneScreengrab = "2.1.1"
|
||||
firebaseBom = "32.8.0"
|
||||
glide = "1.0.0-beta01"
|
||||
googleServices = "4.4.1"
|
||||
@ -67,7 +71,7 @@ androidx-compose-material3 = { module = "androidx.compose.material3:material3" }
|
||||
androidx-compose-runtime = { module = "androidx.compose.runtime:runtime" }
|
||||
androidx-compose-ui = { module = "androidx.compose.ui:ui" }
|
||||
androidx-compose-ui-graphics = { module = "androidx.compose.ui:ui-graphics" }
|
||||
androidx-compose-ui-test = { module = "androidx.compose.ui:ui-test-junit4" }
|
||||
androidx-compose-ui-test = { module = "androidx.compose.ui:ui-test-junit4", version.ref = "androidxComposeUiTest" }
|
||||
androidx-compose-ui-test-manifest = { module = "androidx.compose.ui:ui-test-manifest" }
|
||||
androidx-compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling" }
|
||||
androidx-compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview" }
|
||||
@ -82,9 +86,13 @@ androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "androidx
|
||||
androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "androidxRoom" }
|
||||
androidx-security-crypto = { module = "androidx.security:security-crypto", version.ref = "androidXSecurityCrypto" }
|
||||
androidx-splashscreen = { module = "androidx.core:core-splashscreen", version.ref = "androidxSplash" }
|
||||
androidx-test-runner = { module = "androidx.test:runner", version.ref = "androidxTest" }
|
||||
androidx-test-rules = { module = "androidx.test:rules", version.ref = "androidxTest" }
|
||||
androidx-test-espresso = { module = "androidx.test.espresso:espresso-core", version.ref = "espresso" }
|
||||
androidx-work-runtime-ktx = { module = "androidx.work:work-runtime-ktx", version.ref = "androidxWork" }
|
||||
bitwarden-sdk = { module = "com.bitwarden:sdk-android", version.ref = "bitwardenSdk" }
|
||||
bumptech-glide = { module = "com.github.bumptech.glide:compose", version.ref = "glide" }
|
||||
fastlane-screengrab = { module = "tools.fastlane:screengrab", version.ref = "fastlaneScreengrab"}
|
||||
google-firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "firebaseBom" }
|
||||
google-firebase-cloud-messaging = { module = "com.google.firebase:firebase-messaging-ktx" }
|
||||
google-firebase-crashlytics = { module = "com.google.firebase:firebase-crashlytics-ktx" }
|
||||
@ -98,6 +106,7 @@ kotlinx-collections-immutable = { module = "org.jetbrains.kotlinx:kotlinx-collec
|
||||
kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "kotlinxCoroutines" }
|
||||
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinxCoroutines" }
|
||||
kotlinx-serialization = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerialization" }
|
||||
mockk-android = { module = "io.mockk:mockk-android", version.ref = "mockk" }
|
||||
mockk-mockk = { module = "io.mockk:mockk", version.ref = "mockk" }
|
||||
robolectric-robolectric = { module = "org.robolectric:robolectric", version.ref = "roboelectric" }
|
||||
square-okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
|
||||
@ -117,3 +126,15 @@ kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref =
|
||||
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
|
||||
kotlinx-kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kotlinxKover" }
|
||||
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
|
||||
|
||||
[bundles]
|
||||
tests-instrumented = [
|
||||
"androidx-compose-ui-test",
|
||||
"androidx-test-espresso",
|
||||
"androidx-test-runner",
|
||||
"androidx-test-rules",
|
||||
"fastlane-screengrab",
|
||||
"junit-junit5",
|
||||
"junit-vintage",
|
||||
"mockk-android",
|
||||
]
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user