Merge pull request #106 from ouchadam/release-candidate
[Auto] Release Candidate
This commit is contained in:
commit
c580bcbdab
|
@ -24,4 +24,6 @@ jobs:
|
||||||
- uses: gradle/gradle-build-action@v2
|
- uses: gradle/gradle-build-action@v2
|
||||||
|
|
||||||
- name: Assemble debug variant
|
- name: Assemble debug variant
|
||||||
run: ./gradlew assembleDebug --no-daemon
|
run: |
|
||||||
|
./gradlew assembleDebug --no-daemon
|
||||||
|
./gradlew assembleDebug -Pfoss --no-daemon
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
name: Nightly
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 19 * * *'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check-develop-beta-changes:
|
||||||
|
name: Check if develop is ahead of beta release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version:
|
||||||
|
16
|
||||||
|
- run: npm ci
|
||||||
|
working-directory: ./tools/beta-release/
|
||||||
|
|
||||||
|
- uses: actions/github-script@v6
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const { startReleaseProcess } = await import('${{ github.workspace }}/tools/beta-release/app.js')
|
||||||
|
await startReleaseProcess({github, context, core})
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
name: Generate and publish Release Candidate
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'release'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish-release-candidate:
|
||||||
|
name: Publish release candidate
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
distribution: 'adopt'
|
||||||
|
java-version: '11'
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version:
|
||||||
|
16
|
||||||
|
- run: npm ci
|
||||||
|
working-directory: ./tools/beta-release/
|
||||||
|
|
||||||
|
- name: Write secrets
|
||||||
|
run: |
|
||||||
|
mkdir .secrets
|
||||||
|
touch .secrets/upload-key.jks
|
||||||
|
touch .secrets/service-account.json
|
||||||
|
echo -n '${{ secrets.UPLOAD_KEY }}' | base64 --decode >> .secrets/upload-key.jks
|
||||||
|
echo -n '${{ secrets.SERVICE_ACCOUNT }}' | base64 --decode >> .secrets/service-account.json
|
||||||
|
|
||||||
|
- name: Assemble release variant
|
||||||
|
run: ./tools/generate-release.sh ${{ secrets.STORE_PASS }}
|
||||||
|
|
||||||
|
- uses: actions/github-script@v6
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const { publishRelease } = await import('${{ github.workspace }}/tools/beta-release/app.js')
|
||||||
|
const artifacts = {
|
||||||
|
bundle: '${{ github.workspace }}/app/build/outputs/bundle/release/app-release.aab',
|
||||||
|
mapping: '${{ github.workspace }}/app/build/outputs/mapping/release/mapping.txt',
|
||||||
|
}
|
||||||
|
await publishRelease(github, artifacts)
|
||||||
|
|
|
@ -11,3 +11,5 @@
|
||||||
.cxx
|
.cxx
|
||||||
local.properties
|
local.properties
|
||||||
/benchmark-out
|
/benchmark-out
|
||||||
|
**/node_modules
|
||||||
|
.secrets
|
33
README.md
33
README.md
|
@ -16,8 +16,6 @@
|
||||||
- Focused on reliability and stability.
|
- Focused on reliability and stability.
|
||||||
- Bare-bones feature set.
|
- Bare-bones feature set.
|
||||||
|
|
||||||
##### _*Google play only with automatic crash reporting enabled_
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Feature list
|
### Feature list
|
||||||
|
@ -29,6 +27,7 @@
|
||||||
- Push notifications (DMs always notify, Rooms notify once)
|
- Push notifications (DMs always notify, Rooms notify once)
|
||||||
- Importing of E2E room keys from Element clients
|
- Importing of E2E room keys from Element clients
|
||||||
- [UnifiedPush](https://unifiedpush.org/)
|
- [UnifiedPush](https://unifiedpush.org/)
|
||||||
|
- FOSS variant
|
||||||
|
|
||||||
### Planned
|
### Planned
|
||||||
|
|
||||||
|
@ -57,4 +56,34 @@
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
|
### Building
|
||||||
|
|
||||||
|
|
||||||
|
##### Debug `.apk`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./gradlew assembleDebug
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Release (signed with debug key) `.apk`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./gradlew assembleRelease
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Unsigned release `.apk`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./gradlew assembleRelease -Punsigned
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Unsigned release (FOSS) `.apk`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./gradlew assembleRelease -Punsigned -Pfoss
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
#### Join the conversation @ https://matrix.to/#/#small-talk:iswell.cool
|
#### Join the conversation @ https://matrix.to/#/#small-talk:iswell.cool
|
||||||
|
|
|
@ -24,6 +24,10 @@ android {
|
||||||
} else {
|
} else {
|
||||||
resConfigs "en"
|
resConfigs "en"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isFoss()) {
|
||||||
|
archivesBaseName = "$archivesBaseName-foss"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bundle {
|
bundle {
|
||||||
|
@ -46,8 +50,11 @@ android {
|
||||||
"proguard/serializationx.pro",
|
"proguard/serializationx.pro",
|
||||||
"proguard/olm.pro"
|
"proguard/olm.pro"
|
||||||
|
|
||||||
// actual releases are signed with a different config
|
if (project.hasProperty("unsigned")) {
|
||||||
signingConfig = buildTypes.debug.signingConfig
|
// releases are signed externally
|
||||||
|
} else {
|
||||||
|
signingConfig = buildTypes.debug.signingConfig
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +89,8 @@ dependencies {
|
||||||
implementation project(":domains:android:imageloader")
|
implementation project(":domains:android:imageloader")
|
||||||
implementation project(":domains:olm")
|
implementation project(":domains:olm")
|
||||||
|
|
||||||
|
firebase(it, "messaging")
|
||||||
|
|
||||||
implementation project(":matrix:matrix")
|
implementation project(":matrix:matrix")
|
||||||
implementation project(":matrix:matrix-http-ktor")
|
implementation project(":matrix:matrix-http-ktor")
|
||||||
implementation project(":matrix:services:auth")
|
implementation project(":matrix:services:auth")
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package app.dapk.st
|
package app.dapk.st
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.Intent
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import app.dapk.st.core.CoreAndroidModule
|
import app.dapk.st.core.CoreAndroidModule
|
||||||
import app.dapk.st.core.ModuleProvider
|
import app.dapk.st.core.ModuleProvider
|
||||||
|
@ -11,13 +10,13 @@ import app.dapk.st.core.extensions.ResettableUnsafeLazy
|
||||||
import app.dapk.st.core.extensions.Scope
|
import app.dapk.st.core.extensions.Scope
|
||||||
import app.dapk.st.directory.DirectoryModule
|
import app.dapk.st.directory.DirectoryModule
|
||||||
import app.dapk.st.domain.StoreModule
|
import app.dapk.st.domain.StoreModule
|
||||||
|
import app.dapk.st.firebase.messaging.MessagingModule
|
||||||
import app.dapk.st.graph.AppModule
|
import app.dapk.st.graph.AppModule
|
||||||
import app.dapk.st.home.HomeModule
|
import app.dapk.st.home.HomeModule
|
||||||
import app.dapk.st.login.LoginModule
|
import app.dapk.st.login.LoginModule
|
||||||
import app.dapk.st.messenger.MessengerModule
|
import app.dapk.st.messenger.MessengerModule
|
||||||
import app.dapk.st.notifications.NotificationsModule
|
import app.dapk.st.notifications.NotificationsModule
|
||||||
import app.dapk.st.profile.ProfileModule
|
import app.dapk.st.profile.ProfileModule
|
||||||
import app.dapk.st.push.firebase.FirebasePushService
|
|
||||||
import app.dapk.st.push.PushModule
|
import app.dapk.st.push.PushModule
|
||||||
import app.dapk.st.settings.SettingsModule
|
import app.dapk.st.settings.SettingsModule
|
||||||
import app.dapk.st.share.ShareEntryModule
|
import app.dapk.st.share.ShareEntryModule
|
||||||
|
@ -75,6 +74,7 @@ class SmallTalkApplication : Application(), ModuleProvider {
|
||||||
ProfileModule::class -> featureModules.profileModule
|
ProfileModule::class -> featureModules.profileModule
|
||||||
NotificationsModule::class -> featureModules.notificationsModule
|
NotificationsModule::class -> featureModules.notificationsModule
|
||||||
PushModule::class -> featureModules.pushModule
|
PushModule::class -> featureModules.pushModule
|
||||||
|
MessagingModule::class -> featureModules.messagingModule
|
||||||
MessengerModule::class -> featureModules.messengerModule
|
MessengerModule::class -> featureModules.messengerModule
|
||||||
TaskRunnerModule::class -> appModule.domainModules.taskRunnerModule
|
TaskRunnerModule::class -> appModule.domainModules.taskRunnerModule
|
||||||
CoreAndroidModule::class -> appModule.coreAndroidModule
|
CoreAndroidModule::class -> appModule.coreAndroidModule
|
||||||
|
|
|
@ -16,6 +16,7 @@ import app.dapk.st.core.extensions.ErrorTracker
|
||||||
import app.dapk.st.core.extensions.unsafeLazy
|
import app.dapk.st.core.extensions.unsafeLazy
|
||||||
import app.dapk.st.directory.DirectoryModule
|
import app.dapk.st.directory.DirectoryModule
|
||||||
import app.dapk.st.domain.StoreModule
|
import app.dapk.st.domain.StoreModule
|
||||||
|
import app.dapk.st.firebase.messaging.MessagingModule
|
||||||
import app.dapk.st.home.HomeModule
|
import app.dapk.st.home.HomeModule
|
||||||
import app.dapk.st.home.MainActivity
|
import app.dapk.st.home.MainActivity
|
||||||
import app.dapk.st.imageloader.ImageLoaderModule
|
import app.dapk.st.imageloader.ImageLoaderModule
|
||||||
|
@ -55,6 +56,7 @@ import app.dapk.st.olm.OlmPersistenceWrapper
|
||||||
import app.dapk.st.olm.OlmWrapper
|
import app.dapk.st.olm.OlmWrapper
|
||||||
import app.dapk.st.profile.ProfileModule
|
import app.dapk.st.profile.ProfileModule
|
||||||
import app.dapk.st.push.PushModule
|
import app.dapk.st.push.PushModule
|
||||||
|
import app.dapk.st.push.messaging.MessagingServiceAdapter
|
||||||
import app.dapk.st.settings.SettingsModule
|
import app.dapk.st.settings.SettingsModule
|
||||||
import app.dapk.st.share.ShareEntryModule
|
import app.dapk.st.share.ShareEntryModule
|
||||||
import app.dapk.st.tracking.TrackingModule
|
import app.dapk.st.tracking.TrackingModule
|
||||||
|
@ -208,6 +210,10 @@ internal class FeatureModules internal constructor(
|
||||||
domainModules.pushModule
|
domainModules.pushModule
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val messagingModule by unsafeLazy {
|
||||||
|
domainModules.messaging
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class MatrixModules(
|
internal class MatrixModules(
|
||||||
|
@ -428,23 +434,30 @@ internal class DomainModules(
|
||||||
private val dispatchers: CoroutineDispatchers,
|
private val dispatchers: CoroutineDispatchers,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val pushModule by unsafeLazy {
|
val pushHandler by unsafeLazy {
|
||||||
val store = storeModule.value
|
val store = storeModule.value
|
||||||
val pushHandler = MatrixPushHandler(
|
MatrixPushHandler(
|
||||||
workScheduler = workModule.workScheduler(),
|
workScheduler = workModule.workScheduler(),
|
||||||
credentialsStore = store.credentialsStore(),
|
credentialsStore = store.credentialsStore(),
|
||||||
matrixModules.sync,
|
matrixModules.sync,
|
||||||
store.roomStore(),
|
store.roomStore(),
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val messaging by unsafeLazy { MessagingModule(MessagingServiceAdapter(pushHandler), context) }
|
||||||
|
|
||||||
|
val pushModule by unsafeLazy {
|
||||||
PushModule(
|
PushModule(
|
||||||
errorTracker,
|
errorTracker,
|
||||||
pushHandler,
|
pushHandler,
|
||||||
context,
|
context,
|
||||||
dispatchers,
|
dispatchers,
|
||||||
SharedPreferencesDelegate(context.applicationContext, fileName = "dapk-user-preferences", dispatchers)
|
SharedPreferencesDelegate(context.applicationContext, fileName = "dapk-user-preferences", dispatchers),
|
||||||
|
messaging.messaging,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val taskRunnerModule by unsafeLazy { TaskRunnerModule(TaskRunnerAdapter(matrixModules.matrix::run, AppTaskRunner(matrixModules.push))) }
|
val taskRunnerModule by unsafeLazy { TaskRunnerModule(TaskRunnerAdapter(matrixModules.matrix::run, AppTaskRunner(matrixModules.push))) }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class AndroidImageContentReader(private val contentResolver: ContentResolver) : ImageContentReader {
|
internal class AndroidImageContentReader(private val contentResolver: ContentResolver) : ImageContentReader {
|
||||||
|
|
15
build.gradle
15
build.gradle
|
@ -118,7 +118,7 @@ ext.applyAndroidLibraryModule = { project ->
|
||||||
}
|
}
|
||||||
|
|
||||||
ext.applyCrashlyticsIfRelease = { project ->
|
ext.applyCrashlyticsIfRelease = { project ->
|
||||||
if (isReleaseBuild) {
|
if (isReleaseBuild && !isFoss()) {
|
||||||
project.apply plugin: 'com.google.firebase.crashlytics'
|
project.apply plugin: 'com.google.firebase.crashlytics'
|
||||||
project.afterEvaluate {
|
project.afterEvaluate {
|
||||||
project.tasks.withType(com.google.firebase.crashlytics.buildtools.gradle.tasks.UploadMappingFileTask).configureEach {
|
project.tasks.withType(com.google.firebase.crashlytics.buildtools.gradle.tasks.UploadMappingFileTask).configureEach {
|
||||||
|
@ -151,6 +151,19 @@ ext.androidImportFixturesWorkaround = { project, fixtures ->
|
||||||
project.dependencies.testImplementation fixtures.files("build/libs/${fixtures.name}.jar")
|
project.dependencies.testImplementation fixtures.files("build/libs/${fixtures.name}.jar")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ext.isFoss = {
|
||||||
|
return rootProject.hasProperty("foss")
|
||||||
|
}
|
||||||
|
|
||||||
|
ext.firebase = { dependencies, name ->
|
||||||
|
if (isFoss()) {
|
||||||
|
dependencies.implementation(project(":domains:firebase:$name-noop"))
|
||||||
|
} else {
|
||||||
|
dependencies.implementation(project(":domains:firebase:$name"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (launchTask.contains("codeCoverageReport".toLowerCase())) {
|
if (launchTask.contains("codeCoverageReport".toLowerCase())) {
|
||||||
apply from: 'tools/coverage.gradle'
|
apply from: 'tools/coverage.gradle'
|
||||||
}
|
}
|
|
@ -6,8 +6,9 @@ dependencies {
|
||||||
implementation project(':domains:android:core')
|
implementation project(':domains:android:core')
|
||||||
implementation project(':domains:store')
|
implementation project(':domains:store')
|
||||||
implementation project(':matrix:services:push')
|
implementation project(':matrix:services:push')
|
||||||
implementation platform('com.google.firebase:firebase-bom:29.0.3')
|
|
||||||
implementation 'com.google.firebase:firebase-messaging'
|
firebase(it, "messaging")
|
||||||
|
|
||||||
implementation Dependencies.mavenCentral.kotlinSerializationJson
|
implementation Dependencies.mavenCentral.kotlinSerializationJson
|
||||||
implementation Dependencies.jitPack.unifiedPush
|
implementation Dependencies.jitPack.unifiedPush
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,6 @@
|
||||||
<manifest package="app.dapk.st.push" xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest package="app.dapk.st.push" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<application>
|
<application>
|
||||||
|
|
||||||
<service
|
|
||||||
android:name=".firebase.FirebasePushService"
|
|
||||||
android:exported="false">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
|
|
||||||
</intent-filter>
|
|
||||||
</service>
|
|
||||||
|
|
||||||
<receiver android:exported="true" android:enabled="true" android:name=".unifiedpush.UnifiedPushMessageReceiver">
|
<receiver android:exported="true" android:enabled="true" android:name=".unifiedpush.UnifiedPushMessageReceiver">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="org.unifiedpush.android.connector.MESSAGE"/>
|
<action android:name="org.unifiedpush.android.connector.MESSAGE"/>
|
||||||
|
|
|
@ -7,7 +7,8 @@ import app.dapk.st.core.extensions.ErrorTracker
|
||||||
import app.dapk.st.core.extensions.unsafeLazy
|
import app.dapk.st.core.extensions.unsafeLazy
|
||||||
import app.dapk.st.domain.Preferences
|
import app.dapk.st.domain.Preferences
|
||||||
import app.dapk.st.domain.push.PushTokenRegistrarPreferences
|
import app.dapk.st.domain.push.PushTokenRegistrarPreferences
|
||||||
import app.dapk.st.push.firebase.FirebasePushTokenRegistrar
|
import app.dapk.st.firebase.messaging.Messaging
|
||||||
|
import app.dapk.st.push.messaging.MessagingPushTokenRegistrar
|
||||||
import app.dapk.st.push.unifiedpush.UnifiedPushRegistrar
|
import app.dapk.st.push.unifiedpush.UnifiedPushRegistrar
|
||||||
|
|
||||||
class PushModule(
|
class PushModule(
|
||||||
|
@ -16,15 +17,16 @@ class PushModule(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val dispatchers: CoroutineDispatchers,
|
private val dispatchers: CoroutineDispatchers,
|
||||||
private val preferences: Preferences,
|
private val preferences: Preferences,
|
||||||
|
private val messaging: Messaging,
|
||||||
) : ProvidableModule {
|
) : ProvidableModule {
|
||||||
|
|
||||||
private val registrars by unsafeLazy {
|
private val registrars by unsafeLazy {
|
||||||
PushTokenRegistrars(
|
PushTokenRegistrars(
|
||||||
context,
|
context,
|
||||||
FirebasePushTokenRegistrar(
|
MessagingPushTokenRegistrar(
|
||||||
errorTracker,
|
errorTracker,
|
||||||
context,
|
|
||||||
pushHandler,
|
pushHandler,
|
||||||
|
messaging,
|
||||||
),
|
),
|
||||||
UnifiedPushRegistrar(context),
|
UnifiedPushRegistrar(context),
|
||||||
PushTokenRegistrarPreferences(preferences)
|
PushTokenRegistrarPreferences(preferences)
|
||||||
|
|
|
@ -2,7 +2,7 @@ package app.dapk.st.push
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import app.dapk.st.domain.push.PushTokenRegistrarPreferences
|
import app.dapk.st.domain.push.PushTokenRegistrarPreferences
|
||||||
import app.dapk.st.push.firebase.FirebasePushTokenRegistrar
|
import app.dapk.st.push.messaging.MessagingPushTokenRegistrar
|
||||||
import app.dapk.st.push.unifiedpush.UnifiedPushRegistrar
|
import app.dapk.st.push.unifiedpush.UnifiedPushRegistrar
|
||||||
import org.unifiedpush.android.connector.UnifiedPush
|
import org.unifiedpush.android.connector.UnifiedPush
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ private val NONE = Registrar("None")
|
||||||
|
|
||||||
class PushTokenRegistrars(
|
class PushTokenRegistrars(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val firebasePushTokenRegistrar: FirebasePushTokenRegistrar,
|
private val messagingPushTokenRegistrar: MessagingPushTokenRegistrar,
|
||||||
private val unifiedPushRegistrar: UnifiedPushRegistrar,
|
private val unifiedPushRegistrar: UnifiedPushRegistrar,
|
||||||
private val pushTokenStore: PushTokenRegistrarPreferences,
|
private val pushTokenStore: PushTokenRegistrarPreferences,
|
||||||
) : PushTokenRegistrar {
|
) : PushTokenRegistrar {
|
||||||
|
@ -19,27 +19,36 @@ class PushTokenRegistrars(
|
||||||
private var selection: Registrar? = null
|
private var selection: Registrar? = null
|
||||||
|
|
||||||
fun options(): List<Registrar> {
|
fun options(): List<Registrar> {
|
||||||
return listOf(NONE, FIREBASE_OPTION) + UnifiedPush.getDistributors(context).map { Registrar(it) }
|
val messagingOption = when (messagingPushTokenRegistrar.isAvailable()) {
|
||||||
|
true -> FIREBASE_OPTION
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
return listOfNotNull(NONE, messagingOption) + UnifiedPush.getDistributors(context).map { Registrar(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun currentSelection() = selection ?: (pushTokenStore.currentSelection()?.let { Registrar(it) } ?: FIREBASE_OPTION).also { selection = it }
|
suspend fun currentSelection() = selection ?: (pushTokenStore.currentSelection()?.let { Registrar(it) } ?: defaultSelection()).also { selection = it }
|
||||||
|
|
||||||
|
private fun defaultSelection() = when (messagingPushTokenRegistrar.isAvailable()) {
|
||||||
|
true -> FIREBASE_OPTION
|
||||||
|
else -> NONE
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun makeSelection(option: Registrar) {
|
suspend fun makeSelection(option: Registrar) {
|
||||||
selection = option
|
selection = option
|
||||||
pushTokenStore.store(option.id)
|
pushTokenStore.store(option.id)
|
||||||
when (option) {
|
when (option) {
|
||||||
NONE -> {
|
NONE -> {
|
||||||
firebasePushTokenRegistrar.unregister()
|
messagingPushTokenRegistrar.unregister()
|
||||||
unifiedPushRegistrar.unregister()
|
unifiedPushRegistrar.unregister()
|
||||||
}
|
}
|
||||||
|
|
||||||
FIREBASE_OPTION -> {
|
FIREBASE_OPTION -> {
|
||||||
unifiedPushRegistrar.unregister()
|
unifiedPushRegistrar.unregister()
|
||||||
firebasePushTokenRegistrar.registerCurrentToken()
|
messagingPushTokenRegistrar.registerCurrentToken()
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
firebasePushTokenRegistrar.unregister()
|
messagingPushTokenRegistrar.unregister()
|
||||||
unifiedPushRegistrar.registerSelection(option)
|
unifiedPushRegistrar.registerSelection(option)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,7 +56,7 @@ class PushTokenRegistrars(
|
||||||
|
|
||||||
override suspend fun registerCurrentToken() {
|
override suspend fun registerCurrentToken() {
|
||||||
when (selection) {
|
when (selection) {
|
||||||
FIREBASE_OPTION -> firebasePushTokenRegistrar.registerCurrentToken()
|
FIREBASE_OPTION -> messagingPushTokenRegistrar.registerCurrentToken()
|
||||||
NONE -> {
|
NONE -> {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
@ -58,10 +67,10 @@ class PushTokenRegistrars(
|
||||||
|
|
||||||
override fun unregister() {
|
override fun unregister() {
|
||||||
when (selection) {
|
when (selection) {
|
||||||
FIREBASE_OPTION -> firebasePushTokenRegistrar.unregister()
|
FIREBASE_OPTION -> messagingPushTokenRegistrar.unregister()
|
||||||
NONE -> {
|
NONE -> {
|
||||||
runCatching {
|
runCatching {
|
||||||
firebasePushTokenRegistrar.unregister()
|
messagingPushTokenRegistrar.unregister()
|
||||||
unifiedPushRegistrar.unregister()
|
unifiedPushRegistrar.unregister()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
package app.dapk.st.push.firebase
|
|
||||||
|
|
||||||
import com.google.firebase.messaging.FirebaseMessaging
|
|
||||||
import kotlin.coroutines.resume
|
|
||||||
import kotlin.coroutines.suspendCoroutine
|
|
||||||
|
|
||||||
suspend fun FirebaseMessaging.token() = suspendCoroutine<String> { continuation ->
|
|
||||||
this.token.addOnCompleteListener { task ->
|
|
||||||
when {
|
|
||||||
task.isSuccessful -> continuation.resume(task.result!!)
|
|
||||||
task.isCanceled -> continuation.resumeWith(Result.failure(CancelledTokenFetchingException()))
|
|
||||||
else -> continuation.resumeWith(Result.failure(task.exception ?: UnknownTokenFetchingFailedException()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class CancelledTokenFetchingException : Throwable()
|
|
||||||
private class UnknownTokenFetchingFailedException : Throwable()
|
|
|
@ -1,37 +1,28 @@
|
||||||
package app.dapk.st.push.firebase
|
package app.dapk.st.push.messaging
|
||||||
|
|
||||||
import android.content.ComponentName
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.pm.PackageManager
|
|
||||||
import app.dapk.st.core.AppLogTag
|
import app.dapk.st.core.AppLogTag
|
||||||
import app.dapk.st.core.extensions.CrashScope
|
import app.dapk.st.core.extensions.CrashScope
|
||||||
import app.dapk.st.core.extensions.ErrorTracker
|
import app.dapk.st.core.extensions.ErrorTracker
|
||||||
import app.dapk.st.core.log
|
import app.dapk.st.core.log
|
||||||
|
import app.dapk.st.firebase.messaging.Messaging
|
||||||
import app.dapk.st.push.PushHandler
|
import app.dapk.st.push.PushHandler
|
||||||
import app.dapk.st.push.PushTokenPayload
|
import app.dapk.st.push.PushTokenPayload
|
||||||
import app.dapk.st.push.PushTokenRegistrar
|
import app.dapk.st.push.PushTokenRegistrar
|
||||||
import app.dapk.st.push.unifiedpush.UnifiedPushMessageReceiver
|
|
||||||
import com.google.firebase.messaging.FirebaseMessaging
|
|
||||||
|
|
||||||
private const val SYGNAL_GATEWAY = "https://sygnal.dapk.app/_matrix/push/v1/notify"
|
private const val SYGNAL_GATEWAY = "https://sygnal.dapk.app/_matrix/push/v1/notify"
|
||||||
|
|
||||||
class FirebasePushTokenRegistrar(
|
class MessagingPushTokenRegistrar(
|
||||||
override val errorTracker: ErrorTracker,
|
override val errorTracker: ErrorTracker,
|
||||||
private val context: Context,
|
|
||||||
private val pushHandler: PushHandler,
|
private val pushHandler: PushHandler,
|
||||||
|
private val messaging: Messaging,
|
||||||
) : PushTokenRegistrar, CrashScope {
|
) : PushTokenRegistrar, CrashScope {
|
||||||
|
|
||||||
override suspend fun registerCurrentToken() {
|
override suspend fun registerCurrentToken() {
|
||||||
log(AppLogTag.PUSH, "FCM - register current token")
|
log(AppLogTag.PUSH, "FCM - register current token")
|
||||||
context.packageManager.setComponentEnabledSetting(
|
messaging.enable()
|
||||||
ComponentName(context, FirebasePushService::class.java),
|
|
||||||
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
|
|
||||||
PackageManager.DONT_KILL_APP,
|
|
||||||
)
|
|
||||||
|
|
||||||
kotlin.runCatching {
|
kotlin.runCatching {
|
||||||
FirebaseMessaging.getInstance().token().also {
|
messaging.token().also {
|
||||||
pushHandler.onNewToken(
|
pushHandler.onNewToken(
|
||||||
PushTokenPayload(
|
PushTokenPayload(
|
||||||
token = it,
|
token = it,
|
||||||
|
@ -48,14 +39,10 @@ class FirebasePushTokenRegistrar(
|
||||||
|
|
||||||
override fun unregister() {
|
override fun unregister() {
|
||||||
log(AppLogTag.PUSH, "FCM - unregister")
|
log(AppLogTag.PUSH, "FCM - unregister")
|
||||||
FirebaseMessaging.getInstance().deleteToken()
|
messaging.deleteToken()
|
||||||
context.stopService(Intent(context, FirebasePushService::class.java))
|
messaging.disable()
|
||||||
|
|
||||||
context.packageManager.setComponentEnabledSetting(
|
|
||||||
ComponentName(context, FirebasePushService::class.java),
|
|
||||||
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
|
|
||||||
PackageManager.DONT_KILL_APP,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isAvailable() = messaging.isAvailable()
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package app.dapk.st.push.messaging
|
||||||
|
|
||||||
|
import app.dapk.st.core.AppLogTag
|
||||||
|
import app.dapk.st.core.log
|
||||||
|
import app.dapk.st.firebase.messaging.ServiceDelegate
|
||||||
|
import app.dapk.st.matrix.common.EventId
|
||||||
|
import app.dapk.st.matrix.common.RoomId
|
||||||
|
import app.dapk.st.push.PushHandler
|
||||||
|
import app.dapk.st.push.PushTokenPayload
|
||||||
|
|
||||||
|
private const val SYGNAL_GATEWAY = "https://sygnal.dapk.app/_matrix/push/v1/notify"
|
||||||
|
|
||||||
|
class MessagingServiceAdapter(
|
||||||
|
private val handler: PushHandler,
|
||||||
|
) : ServiceDelegate {
|
||||||
|
|
||||||
|
override fun onNewToken(token: String) {
|
||||||
|
log(AppLogTag.PUSH, "FCM onNewToken")
|
||||||
|
handler.onNewToken(
|
||||||
|
PushTokenPayload(
|
||||||
|
token = token,
|
||||||
|
gatewayUrl = SYGNAL_GATEWAY,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMessageReceived(eventId: EventId?, roomId: RoomId?) {
|
||||||
|
log(AppLogTag.PUSH, "FCM onMessage")
|
||||||
|
handler.onMessageReceived(eventId, roomId)
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,9 +2,5 @@ applyAndroidLibraryModule(project)
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation project(':core')
|
implementation project(':core')
|
||||||
implementation platform('com.google.firebase:firebase-bom:29.0.3')
|
firebase(it, "crashlytics")
|
||||||
implementation 'com.google.firebase:firebase-crashlytics'
|
|
||||||
|
|
||||||
// is it worth the 400kb size increase?
|
|
||||||
// implementation 'com.google.firebase:firebase-analytics'
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,16 +4,12 @@ import android.util.Log
|
||||||
import app.dapk.st.core.AppLogTag
|
import app.dapk.st.core.AppLogTag
|
||||||
import app.dapk.st.core.extensions.ErrorTracker
|
import app.dapk.st.core.extensions.ErrorTracker
|
||||||
import app.dapk.st.core.log
|
import app.dapk.st.core.log
|
||||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
|
||||||
|
|
||||||
class CrashlyticsCrashTracker(
|
class CrashTrackerLogger : ErrorTracker {
|
||||||
private val firebaseCrashlytics: FirebaseCrashlytics,
|
|
||||||
) : ErrorTracker {
|
|
||||||
|
|
||||||
override fun track(throwable: Throwable, extra: String) {
|
override fun track(throwable: Throwable, extra: String) {
|
||||||
Log.e("ST", throwable.message, throwable)
|
Log.e("ST", throwable.message, throwable)
|
||||||
log(AppLogTag.ERROR_NON_FATAL, "${throwable.message ?: "N/A"} extra=$extra")
|
log(AppLogTag.ERROR_NON_FATAL, "${throwable.message ?: "N/A"} extra=$extra")
|
||||||
firebaseCrashlytics.recordException(throwable)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
package app.dapk.st.tracking
|
package app.dapk.st.tracking
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import app.dapk.st.core.extensions.ErrorTracker
|
import app.dapk.st.core.extensions.ErrorTracker
|
||||||
import app.dapk.st.core.extensions.unsafeLazy
|
import app.dapk.st.core.extensions.unsafeLazy
|
||||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
import app.dapk.st.firebase.crashlytics.CrashlyticsModule
|
||||||
|
|
||||||
class TrackingModule(
|
class TrackingModule(
|
||||||
private val isCrashTrackingEnabled: Boolean,
|
private val isCrashTrackingEnabled: Boolean,
|
||||||
|
@ -11,13 +10,18 @@ class TrackingModule(
|
||||||
|
|
||||||
val errorTracker: ErrorTracker by unsafeLazy {
|
val errorTracker: ErrorTracker by unsafeLazy {
|
||||||
when (isCrashTrackingEnabled) {
|
when (isCrashTrackingEnabled) {
|
||||||
true -> CrashlyticsCrashTracker(FirebaseCrashlytics.getInstance())
|
true -> compositeTracker(
|
||||||
false -> object : ErrorTracker {
|
CrashTrackerLogger(),
|
||||||
override fun track(throwable: Throwable, extra: String) {
|
CrashlyticsModule().errorTracker,
|
||||||
Log.e("error", throwable.message, throwable)
|
)
|
||||||
}
|
false -> CrashTrackerLogger()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun compositeTracker(vararg loggers: ErrorTracker) = object : ErrorTracker {
|
||||||
|
override fun track(throwable: Throwable, extra: String) {
|
||||||
|
loggers.forEach { it.track(throwable, extra) }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
plugins { id 'kotlin' }
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation project(':core')
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package app.dapk.st.firebase.crashlytics
|
||||||
|
|
||||||
|
import app.dapk.st.core.extensions.ErrorTracker
|
||||||
|
import app.dapk.st.core.extensions.unsafeLazy
|
||||||
|
|
||||||
|
class CrashlyticsModule {
|
||||||
|
|
||||||
|
val errorTracker: ErrorTracker by unsafeLazy {
|
||||||
|
object : ErrorTracker {
|
||||||
|
override fun track(throwable: Throwable, extra: String) {
|
||||||
|
// no op
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
applyAndroidLibraryModule(project)
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation project(':core')
|
||||||
|
implementation platform('com.google.firebase:firebase-bom:29.0.3')
|
||||||
|
implementation 'com.google.firebase:firebase-crashlytics'
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest package="app.dapk.st.firebase.crashlytics"/>
|
|
@ -0,0 +1,14 @@
|
||||||
|
package app.dapk.st.firebase.crashlytics
|
||||||
|
|
||||||
|
import app.dapk.st.core.extensions.ErrorTracker
|
||||||
|
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||||
|
|
||||||
|
class CrashlyticsCrashTracker(
|
||||||
|
private val firebaseCrashlytics: FirebaseCrashlytics,
|
||||||
|
) : ErrorTracker {
|
||||||
|
|
||||||
|
override fun track(throwable: Throwable, extra: String) {
|
||||||
|
firebaseCrashlytics.recordException(throwable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package app.dapk.st.firebase.crashlytics
|
||||||
|
|
||||||
|
import app.dapk.st.core.extensions.ErrorTracker
|
||||||
|
import app.dapk.st.core.extensions.unsafeLazy
|
||||||
|
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||||
|
|
||||||
|
class CrashlyticsModule {
|
||||||
|
|
||||||
|
val errorTracker: ErrorTracker by unsafeLazy {
|
||||||
|
CrashlyticsCrashTracker(FirebaseCrashlytics.getInstance())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
applyAndroidLibraryModule(project)
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation project(':core')
|
||||||
|
implementation project(':matrix:common')
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest package="app.dapk.st.firebase.messaging"/>
|
|
@ -0,0 +1,23 @@
|
||||||
|
package app.dapk.st.firebase.messaging
|
||||||
|
|
||||||
|
class Messaging {
|
||||||
|
|
||||||
|
fun isAvailable() = false
|
||||||
|
|
||||||
|
fun enable() {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
fun disable() {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteToken() {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun token(): String {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package app.dapk.st.firebase.messaging
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import app.dapk.st.core.ProvidableModule
|
||||||
|
import app.dapk.st.core.extensions.unsafeLazy
|
||||||
|
|
||||||
|
@Suppress("UNUSED")
|
||||||
|
class MessagingModule(
|
||||||
|
val serviceDelegate: ServiceDelegate,
|
||||||
|
val context: Context,
|
||||||
|
) : ProvidableModule {
|
||||||
|
|
||||||
|
val messaging by unsafeLazy {
|
||||||
|
Messaging()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package app.dapk.st.firebase.messaging
|
||||||
|
|
||||||
|
import app.dapk.st.matrix.common.EventId
|
||||||
|
import app.dapk.st.matrix.common.RoomId
|
||||||
|
|
||||||
|
interface ServiceDelegate {
|
||||||
|
fun onNewToken(token: String)
|
||||||
|
fun onMessageReceived(eventId: EventId?, roomId: RoomId?)
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
applyAndroidLibraryModule(project)
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation project(':core')
|
||||||
|
implementation project(':domains:android:core')
|
||||||
|
implementation project(':matrix:common')
|
||||||
|
implementation platform('com.google.firebase:firebase-bom:29.0.3')
|
||||||
|
implementation 'com.google.firebase:firebase-messaging'
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest package="app.dapk.st.firebase.messaging" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<application>
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name=".FirebasePushServiceDelegate"
|
||||||
|
android:exported="false">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
|
||||||
|
</intent-filter>
|
||||||
|
</service>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
|
@ -1,4 +1,4 @@
|
||||||
package app.dapk.st.push.firebase
|
package app.dapk.st.firebase.messaging
|
||||||
|
|
||||||
import app.dapk.st.core.AppLogTag
|
import app.dapk.st.core.AppLogTag
|
||||||
import app.dapk.st.core.extensions.unsafeLazy
|
import app.dapk.st.core.extensions.unsafeLazy
|
||||||
|
@ -6,31 +6,21 @@ import app.dapk.st.core.log
|
||||||
import app.dapk.st.core.module
|
import app.dapk.st.core.module
|
||||||
import app.dapk.st.matrix.common.EventId
|
import app.dapk.st.matrix.common.EventId
|
||||||
import app.dapk.st.matrix.common.RoomId
|
import app.dapk.st.matrix.common.RoomId
|
||||||
import app.dapk.st.push.PushModule
|
|
||||||
import app.dapk.st.push.PushTokenPayload
|
|
||||||
import com.google.firebase.messaging.FirebaseMessagingService
|
import com.google.firebase.messaging.FirebaseMessagingService
|
||||||
import com.google.firebase.messaging.RemoteMessage
|
import com.google.firebase.messaging.RemoteMessage
|
||||||
|
|
||||||
private const val SYGNAL_GATEWAY = "https://sygnal.dapk.app/_matrix/push/v1/notify"
|
class FirebasePushServiceDelegate : FirebaseMessagingService() {
|
||||||
|
|
||||||
class FirebasePushService : FirebaseMessagingService() {
|
private val delegate by unsafeLazy { module<MessagingModule>().serviceDelegate }
|
||||||
|
|
||||||
private val handler by unsafeLazy { module<PushModule>().pushHandler() }
|
|
||||||
|
|
||||||
override fun onNewToken(token: String) {
|
override fun onNewToken(token: String) {
|
||||||
log(AppLogTag.PUSH, "FCM onNewToken")
|
delegate.onNewToken(token)
|
||||||
handler.onNewToken(
|
|
||||||
PushTokenPayload(
|
|
||||||
token = token,
|
|
||||||
gatewayUrl = SYGNAL_GATEWAY,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMessageReceived(message: RemoteMessage) {
|
override fun onMessageReceived(message: RemoteMessage) {
|
||||||
log(AppLogTag.PUSH, "FCM onMessage")
|
log(AppLogTag.PUSH, "FCM onMessage")
|
||||||
val eventId = message.data["event_id"]?.let { EventId(it) }
|
val eventId = message.data["event_id"]?.let { EventId(it) }
|
||||||
val roomId = message.data["room_id"]?.let { RoomId(it) }
|
val roomId = message.data["room_id"]?.let { RoomId(it) }
|
||||||
handler.onMessageReceived(eventId, roomId)
|
delegate.onMessageReceived(eventId, roomId)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package app.dapk.st.firebase.messaging
|
||||||
|
|
||||||
|
import android.content.ComponentName
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.pm.PackageManager
|
||||||
|
import com.google.android.gms.common.ConnectionResult
|
||||||
|
import com.google.android.gms.common.GoogleApiAvailabilityLight
|
||||||
|
import com.google.firebase.messaging.FirebaseMessaging
|
||||||
|
import kotlin.coroutines.resume
|
||||||
|
import kotlin.coroutines.suspendCoroutine
|
||||||
|
|
||||||
|
class Messaging(
|
||||||
|
private val instance: FirebaseMessaging,
|
||||||
|
private val context: Context,
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun isAvailable() = GoogleApiAvailabilityLight.getInstance().isGooglePlayServicesAvailable(context) == ConnectionResult.SUCCESS
|
||||||
|
|
||||||
|
fun enable() {
|
||||||
|
context.packageManager.setComponentEnabledSetting(
|
||||||
|
ComponentName(context, FirebasePushServiceDelegate::class.java),
|
||||||
|
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
|
||||||
|
PackageManager.DONT_KILL_APP,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun disable() {
|
||||||
|
context.stopService(Intent(context, FirebasePushServiceDelegate::class.java))
|
||||||
|
context.packageManager.setComponentEnabledSetting(
|
||||||
|
ComponentName(context, FirebasePushServiceDelegate::class.java),
|
||||||
|
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
|
||||||
|
PackageManager.DONT_KILL_APP,
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteToken() {
|
||||||
|
instance.deleteToken()
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun token() = suspendCoroutine { continuation ->
|
||||||
|
instance.token.addOnCompleteListener { task ->
|
||||||
|
when {
|
||||||
|
task.isSuccessful -> continuation.resume(task.result!!)
|
||||||
|
task.isCanceled -> continuation.resumeWith(Result.failure(CancelledTokenFetchingException()))
|
||||||
|
else -> continuation.resumeWith(Result.failure(task.exception ?: UnknownTokenFetchingFailedException()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class CancelledTokenFetchingException : Throwable()
|
||||||
|
private class UnknownTokenFetchingFailedException : Throwable()
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package app.dapk.st.firebase.messaging
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import app.dapk.st.core.ProvidableModule
|
||||||
|
import app.dapk.st.core.extensions.unsafeLazy
|
||||||
|
import com.google.firebase.messaging.FirebaseMessaging
|
||||||
|
|
||||||
|
class MessagingModule(
|
||||||
|
val serviceDelegate: ServiceDelegate,
|
||||||
|
val context: Context,
|
||||||
|
) : ProvidableModule {
|
||||||
|
|
||||||
|
val messaging by unsafeLazy {
|
||||||
|
Messaging(FirebaseMessaging.getInstance(), context)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package app.dapk.st.firebase.messaging
|
||||||
|
|
||||||
|
import app.dapk.st.matrix.common.EventId
|
||||||
|
import app.dapk.st.matrix.common.RoomId
|
||||||
|
|
||||||
|
interface ServiceDelegate {
|
||||||
|
fun onNewToken(token: String)
|
||||||
|
fun onMessageReceived(eventId: EventId?, roomId: RoomId?)
|
||||||
|
}
|
|
@ -34,6 +34,11 @@ include ':domains:store'
|
||||||
include ':domains:olm-stub'
|
include ':domains:olm-stub'
|
||||||
include ':domains:olm'
|
include ':domains:olm'
|
||||||
|
|
||||||
|
include ':domains:firebase:crashlytics'
|
||||||
|
include ':domains:firebase:crashlytics-noop'
|
||||||
|
include ':domains:firebase:messaging'
|
||||||
|
include ':domains:firebase:messaging-noop'
|
||||||
|
|
||||||
include ':matrix:matrix'
|
include ':matrix:matrix'
|
||||||
include ':matrix:common'
|
include ':matrix:common'
|
||||||
include ':matrix:matrix-http'
|
include ':matrix:matrix-http'
|
||||||
|
|
|
@ -0,0 +1,152 @@
|
||||||
|
import { release } from './release.js'
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
owner: "ouchadam",
|
||||||
|
repo: "small-talk",
|
||||||
|
pathToVersionFile: "version.json",
|
||||||
|
rcBranchesFrom: "main",
|
||||||
|
rcMergesTo: "release",
|
||||||
|
packageName: "app.dapk.st"
|
||||||
|
}
|
||||||
|
|
||||||
|
const rcBranchName = "release-candidate"
|
||||||
|
|
||||||
|
export const startReleaseProcess = async ({ github, context, core }) => {
|
||||||
|
console.log("script start")
|
||||||
|
if (await doesNotHaveInProgressRelease(github) && await isWorkingBranchAhead(github)) {
|
||||||
|
await startRelease(github)
|
||||||
|
} else {
|
||||||
|
console.log(`Release skipped due to being behind`)
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
export const publishRelease = async (github, artifacts) => {
|
||||||
|
const versionFile = await readVersionFile(github, "release")
|
||||||
|
await release(
|
||||||
|
github,
|
||||||
|
versionFile.content,
|
||||||
|
config.packageName,
|
||||||
|
artifacts,
|
||||||
|
config,
|
||||||
|
).catch((error) => console.log(error))
|
||||||
|
}
|
||||||
|
|
||||||
|
const isWorkingBranchAhead = async (github) => {
|
||||||
|
const result = await github.rest.repos.compareCommitsWithBasehead({
|
||||||
|
owner: config.owner,
|
||||||
|
repo: config.repo,
|
||||||
|
basehead: `${config.rcMergesTo}...${config.rcBranchesFrom}`,
|
||||||
|
per_page: 1,
|
||||||
|
page: 1,
|
||||||
|
})
|
||||||
|
return result.data.status === "ahead"
|
||||||
|
}
|
||||||
|
|
||||||
|
const doesNotHaveInProgressRelease = async (github) => {
|
||||||
|
const releasePrs = await github.rest.pulls.list({
|
||||||
|
owner: config.owner,
|
||||||
|
repo: config.repo,
|
||||||
|
state: "open",
|
||||||
|
base: config.rcMergesTo
|
||||||
|
})
|
||||||
|
|
||||||
|
const syncPrs = await github.rest.pulls.list({
|
||||||
|
owner: config.owner,
|
||||||
|
repo: config.repo,
|
||||||
|
state: "open",
|
||||||
|
base: config.rcBranchesFrom,
|
||||||
|
head: `${config.owner}:${config.rcMergesTo}`
|
||||||
|
})
|
||||||
|
|
||||||
|
return releasePrs.data.length === 0 && syncPrs.data.length === 0
|
||||||
|
}
|
||||||
|
|
||||||
|
const startRelease = async (github) => {
|
||||||
|
console.log(`creating release candidate from head of ${config.rcBranchesFrom}`)
|
||||||
|
|
||||||
|
await createBranch(github, "release-candidate", config.rcBranchesFrom)
|
||||||
|
await incrementVersionFile(github, rcBranchName)
|
||||||
|
|
||||||
|
const createdPr = await github.rest.pulls.create({
|
||||||
|
owner: config.owner,
|
||||||
|
repo: config.repo,
|
||||||
|
title: "[Auto] Release Candidate",
|
||||||
|
head: rcBranchName,
|
||||||
|
base: config.rcMergesTo,
|
||||||
|
body: "todo",
|
||||||
|
})
|
||||||
|
|
||||||
|
github.graphql(
|
||||||
|
`
|
||||||
|
mutation ($pullRequestId: ID!, $mergeMethod: PullRequestMergeMethod!) {
|
||||||
|
enablePullRequestAutoMerge(input: {
|
||||||
|
pullRequestId: $pullRequestId,
|
||||||
|
mergeMethod: $mergeMethod
|
||||||
|
}) {
|
||||||
|
pullRequest {
|
||||||
|
autoMergeRequest {
|
||||||
|
enabledAt
|
||||||
|
enabledBy {
|
||||||
|
login
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
{
|
||||||
|
pullRequestId: createdPr.data.node_id,
|
||||||
|
mergeMethod: "MERGE"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const createBranch = async (github, branchName, fromBranch) => {
|
||||||
|
const mainRef = await github.rest.git.getRef({
|
||||||
|
owner: config.owner,
|
||||||
|
repo: config.repo,
|
||||||
|
ref: `heads/${fromBranch}`,
|
||||||
|
})
|
||||||
|
|
||||||
|
await github.rest.git.createRef({
|
||||||
|
owner: config.owner,
|
||||||
|
repo: config.repo,
|
||||||
|
ref: `refs/heads/${branchName}`,
|
||||||
|
sha: mainRef.data.object.sha,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const incrementVersionFile = async (github, branchName) => {
|
||||||
|
const versionFile = await readVersionFile(github, branchName)
|
||||||
|
|
||||||
|
const updatedVersionFile = {
|
||||||
|
...versionFile.content,
|
||||||
|
code: versionFile.content.code + 1,
|
||||||
|
}
|
||||||
|
const encodedContentUpdate = Buffer.from(JSON.stringify(updatedVersionFile, null, 2)).toString('base64')
|
||||||
|
await github.rest.repos.createOrUpdateFileContents({
|
||||||
|
owner: config.owner,
|
||||||
|
repo: config.repo,
|
||||||
|
content: encodedContentUpdate,
|
||||||
|
path: config.pathToVersionFile,
|
||||||
|
sha: versionFile.sha,
|
||||||
|
branch: branchName,
|
||||||
|
message: "updating version for release",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const readVersionFile = async (github, branch) => {
|
||||||
|
const result = await github.rest.repos.getContent({
|
||||||
|
owner: config.owner,
|
||||||
|
repo: config.repo,
|
||||||
|
path: config.pathToVersionFile,
|
||||||
|
ref: branch,
|
||||||
|
})
|
||||||
|
|
||||||
|
const content = Buffer.from(result.data.content, result.data.encoding).toString()
|
||||||
|
return {
|
||||||
|
content: JSON.parse(content),
|
||||||
|
sha: result.data.sha,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,767 @@
|
||||||
|
{
|
||||||
|
"name": "beta-release",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 2,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "beta-release",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@googleapis/androidpublisher": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@googleapis/androidpublisher": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@googleapis/androidpublisher/-/androidpublisher-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-r4JfmLlcu/VI4hObZuQ8RW5OeWRFtOxqE9xU8C2GAp3GTu2ZcemEICu69xy/rchpzMNQY4lrr8WiqUG1LE1L5Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"googleapis-common": "^5.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/abort-controller": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
|
||||||
|
"dependencies": {
|
||||||
|
"event-target-shim": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/agent-base": {
|
||||||
|
"version": "6.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/arrify": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/base64-js": {
|
||||||
|
"version": "1.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
|
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/bignumber.js": {
|
||||||
|
"version": "9.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz",
|
||||||
|
"integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/buffer-equal-constant-time": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
|
||||||
|
},
|
||||||
|
"node_modules/call-bind": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
|
||||||
|
"dependencies": {
|
||||||
|
"function-bind": "^1.1.1",
|
||||||
|
"get-intrinsic": "^1.0.2"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/debug": {
|
||||||
|
"version": "4.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||||
|
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"ms": "2.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"supports-color": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ecdsa-sig-formatter": {
|
||||||
|
"version": "1.0.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
||||||
|
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"safe-buffer": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/event-target-shim": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/extend": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
||||||
|
},
|
||||||
|
"node_modules/fast-text-encoding": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-x6lDDm/tBAzX9kmsPcZsNbvDs3Zey3+scsxaZElS8xWLgUMAg/oFLeewfUz0mu1CblHhhsu15jGkraldkFh8KQ=="
|
||||||
|
},
|
||||||
|
"node_modules/function-bind": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
|
||||||
|
},
|
||||||
|
"node_modules/gaxios": {
|
||||||
|
"version": "4.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.3.tgz",
|
||||||
|
"integrity": "sha512-gSaYYIO1Y3wUtdfHmjDUZ8LWaxJQpiavzbF5Kq53akSzvmVg0RfyOcFDbO1KJ/KCGRFz2qG+lS81F0nkr7cRJA==",
|
||||||
|
"dependencies": {
|
||||||
|
"abort-controller": "^3.0.0",
|
||||||
|
"extend": "^3.0.2",
|
||||||
|
"https-proxy-agent": "^5.0.0",
|
||||||
|
"is-stream": "^2.0.0",
|
||||||
|
"node-fetch": "^2.6.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/gcp-metadata": {
|
||||||
|
"version": "4.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.3.1.tgz",
|
||||||
|
"integrity": "sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==",
|
||||||
|
"dependencies": {
|
||||||
|
"gaxios": "^4.0.0",
|
||||||
|
"json-bigint": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/get-intrinsic": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
|
||||||
|
"dependencies": {
|
||||||
|
"function-bind": "^1.1.1",
|
||||||
|
"has": "^1.0.3",
|
||||||
|
"has-symbols": "^1.0.3"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/google-auth-library": {
|
||||||
|
"version": "7.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.14.1.tgz",
|
||||||
|
"integrity": "sha512-5Rk7iLNDFhFeBYc3s8l1CqzbEBcdhwR193RlD4vSNFajIcINKI8W8P0JLmBpwymHqqWbX34pJDQu39cSy/6RsA==",
|
||||||
|
"dependencies": {
|
||||||
|
"arrify": "^2.0.0",
|
||||||
|
"base64-js": "^1.3.0",
|
||||||
|
"ecdsa-sig-formatter": "^1.0.11",
|
||||||
|
"fast-text-encoding": "^1.0.0",
|
||||||
|
"gaxios": "^4.0.0",
|
||||||
|
"gcp-metadata": "^4.2.0",
|
||||||
|
"gtoken": "^5.0.4",
|
||||||
|
"jws": "^4.0.0",
|
||||||
|
"lru-cache": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/google-p12-pem": {
|
||||||
|
"version": "3.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.4.tgz",
|
||||||
|
"integrity": "sha512-HHuHmkLgwjdmVRngf5+gSmpkyaRI6QmOg77J8tkNBHhNEI62sGHyw4/+UkgyZEI7h84NbWprXDJ+sa3xOYFvTg==",
|
||||||
|
"dependencies": {
|
||||||
|
"node-forge": "^1.3.1"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"gp12-pem": "build/src/bin/gp12-pem.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/googleapis-common": {
|
||||||
|
"version": "5.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-5.1.0.tgz",
|
||||||
|
"integrity": "sha512-RXrif+Gzhq1QAzfjxulbGvAY3FPj8zq/CYcvgjzDbaBNCD6bUl+86I7mUs4DKWHGruuK26ijjR/eDpWIDgNROA==",
|
||||||
|
"dependencies": {
|
||||||
|
"extend": "^3.0.2",
|
||||||
|
"gaxios": "^4.0.0",
|
||||||
|
"google-auth-library": "^7.14.0",
|
||||||
|
"qs": "^6.7.0",
|
||||||
|
"url-template": "^2.0.8",
|
||||||
|
"uuid": "^8.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/gtoken": {
|
||||||
|
"version": "5.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.3.2.tgz",
|
||||||
|
"integrity": "sha512-gkvEKREW7dXWF8NV8pVrKfW7WqReAmjjkMBh6lNCCGOM4ucS0r0YyXXl0r/9Yj8wcW/32ISkfc8h5mPTDbtifQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"gaxios": "^4.0.0",
|
||||||
|
"google-p12-pem": "^3.1.3",
|
||||||
|
"jws": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/has": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||||
|
"dependencies": {
|
||||||
|
"function-bind": "^1.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/has-symbols": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.4"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/https-proxy-agent": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
|
||||||
|
"dependencies": {
|
||||||
|
"agent-base": "6",
|
||||||
|
"debug": "4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-stream": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/json-bigint": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"bignumber.js": "^9.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/jwa": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==",
|
||||||
|
"dependencies": {
|
||||||
|
"buffer-equal-constant-time": "1.0.1",
|
||||||
|
"ecdsa-sig-formatter": "1.0.11",
|
||||||
|
"safe-buffer": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/jws": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
|
||||||
|
"dependencies": {
|
||||||
|
"jwa": "^2.0.0",
|
||||||
|
"safe-buffer": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/lru-cache": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||||
|
"dependencies": {
|
||||||
|
"yallist": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ms": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||||
|
},
|
||||||
|
"node_modules/node-fetch": {
|
||||||
|
"version": "2.6.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||||
|
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"whatwg-url": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "4.x || >=6.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"encoding": "^0.1.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"encoding": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/node-forge": {
|
||||||
|
"version": "1.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
|
||||||
|
"integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6.13.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/object-inspect": {
|
||||||
|
"version": "1.12.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
|
||||||
|
"integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/qs": {
|
||||||
|
"version": "6.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
|
||||||
|
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
|
||||||
|
"dependencies": {
|
||||||
|
"side-channel": "^1.0.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/safe-buffer": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node_modules/side-channel": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
|
||||||
|
"dependencies": {
|
||||||
|
"call-bind": "^1.0.0",
|
||||||
|
"get-intrinsic": "^1.0.2",
|
||||||
|
"object-inspect": "^1.9.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tr46": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||||
|
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||||
|
},
|
||||||
|
"node_modules/url-template": {
|
||||||
|
"version": "2.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz",
|
||||||
|
"integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw=="
|
||||||
|
},
|
||||||
|
"node_modules/uuid": {
|
||||||
|
"version": "8.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||||
|
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/webidl-conversions": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||||
|
},
|
||||||
|
"node_modules/whatwg-url": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||||
|
"dependencies": {
|
||||||
|
"tr46": "~0.0.3",
|
||||||
|
"webidl-conversions": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/yallist": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@googleapis/androidpublisher": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@googleapis/androidpublisher/-/androidpublisher-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-r4JfmLlcu/VI4hObZuQ8RW5OeWRFtOxqE9xU8C2GAp3GTu2ZcemEICu69xy/rchpzMNQY4lrr8WiqUG1LE1L5Q==",
|
||||||
|
"requires": {
|
||||||
|
"googleapis-common": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"abort-controller": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
|
||||||
|
"requires": {
|
||||||
|
"event-target-shim": "^5.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"agent-base": {
|
||||||
|
"version": "6.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
|
||||||
|
"requires": {
|
||||||
|
"debug": "4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"arrify": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug=="
|
||||||
|
},
|
||||||
|
"base64-js": {
|
||||||
|
"version": "1.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||||
|
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
|
||||||
|
},
|
||||||
|
"bignumber.js": {
|
||||||
|
"version": "9.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.0.tgz",
|
||||||
|
"integrity": "sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A=="
|
||||||
|
},
|
||||||
|
"buffer-equal-constant-time": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
|
||||||
|
},
|
||||||
|
"call-bind": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
|
||||||
|
"requires": {
|
||||||
|
"function-bind": "^1.1.1",
|
||||||
|
"get-intrinsic": "^1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"version": "4.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||||
|
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||||
|
"requires": {
|
||||||
|
"ms": "2.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ecdsa-sig-formatter": {
|
||||||
|
"version": "1.0.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
||||||
|
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
|
||||||
|
"requires": {
|
||||||
|
"safe-buffer": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"event-target-shim": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="
|
||||||
|
},
|
||||||
|
"extend": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
|
||||||
|
},
|
||||||
|
"fast-text-encoding": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-x6lDDm/tBAzX9kmsPcZsNbvDs3Zey3+scsxaZElS8xWLgUMAg/oFLeewfUz0mu1CblHhhsu15jGkraldkFh8KQ=="
|
||||||
|
},
|
||||||
|
"function-bind": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
|
||||||
|
},
|
||||||
|
"gaxios": {
|
||||||
|
"version": "4.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.3.tgz",
|
||||||
|
"integrity": "sha512-gSaYYIO1Y3wUtdfHmjDUZ8LWaxJQpiavzbF5Kq53akSzvmVg0RfyOcFDbO1KJ/KCGRFz2qG+lS81F0nkr7cRJA==",
|
||||||
|
"requires": {
|
||||||
|
"abort-controller": "^3.0.0",
|
||||||
|
"extend": "^3.0.2",
|
||||||
|
"https-proxy-agent": "^5.0.0",
|
||||||
|
"is-stream": "^2.0.0",
|
||||||
|
"node-fetch": "^2.6.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gcp-metadata": {
|
||||||
|
"version": "4.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.3.1.tgz",
|
||||||
|
"integrity": "sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==",
|
||||||
|
"requires": {
|
||||||
|
"gaxios": "^4.0.0",
|
||||||
|
"json-bigint": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"get-intrinsic": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
|
||||||
|
"requires": {
|
||||||
|
"function-bind": "^1.1.1",
|
||||||
|
"has": "^1.0.3",
|
||||||
|
"has-symbols": "^1.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"google-auth-library": {
|
||||||
|
"version": "7.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.14.1.tgz",
|
||||||
|
"integrity": "sha512-5Rk7iLNDFhFeBYc3s8l1CqzbEBcdhwR193RlD4vSNFajIcINKI8W8P0JLmBpwymHqqWbX34pJDQu39cSy/6RsA==",
|
||||||
|
"requires": {
|
||||||
|
"arrify": "^2.0.0",
|
||||||
|
"base64-js": "^1.3.0",
|
||||||
|
"ecdsa-sig-formatter": "^1.0.11",
|
||||||
|
"fast-text-encoding": "^1.0.0",
|
||||||
|
"gaxios": "^4.0.0",
|
||||||
|
"gcp-metadata": "^4.2.0",
|
||||||
|
"gtoken": "^5.0.4",
|
||||||
|
"jws": "^4.0.0",
|
||||||
|
"lru-cache": "^6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"google-p12-pem": {
|
||||||
|
"version": "3.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.4.tgz",
|
||||||
|
"integrity": "sha512-HHuHmkLgwjdmVRngf5+gSmpkyaRI6QmOg77J8tkNBHhNEI62sGHyw4/+UkgyZEI7h84NbWprXDJ+sa3xOYFvTg==",
|
||||||
|
"requires": {
|
||||||
|
"node-forge": "^1.3.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"googleapis-common": {
|
||||||
|
"version": "5.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-5.1.0.tgz",
|
||||||
|
"integrity": "sha512-RXrif+Gzhq1QAzfjxulbGvAY3FPj8zq/CYcvgjzDbaBNCD6bUl+86I7mUs4DKWHGruuK26ijjR/eDpWIDgNROA==",
|
||||||
|
"requires": {
|
||||||
|
"extend": "^3.0.2",
|
||||||
|
"gaxios": "^4.0.0",
|
||||||
|
"google-auth-library": "^7.14.0",
|
||||||
|
"qs": "^6.7.0",
|
||||||
|
"url-template": "^2.0.8",
|
||||||
|
"uuid": "^8.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gtoken": {
|
||||||
|
"version": "5.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.3.2.tgz",
|
||||||
|
"integrity": "sha512-gkvEKREW7dXWF8NV8pVrKfW7WqReAmjjkMBh6lNCCGOM4ucS0r0YyXXl0r/9Yj8wcW/32ISkfc8h5mPTDbtifQ==",
|
||||||
|
"requires": {
|
||||||
|
"gaxios": "^4.0.0",
|
||||||
|
"google-p12-pem": "^3.1.3",
|
||||||
|
"jws": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||||
|
"requires": {
|
||||||
|
"function-bind": "^1.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has-symbols": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
|
||||||
|
},
|
||||||
|
"https-proxy-agent": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
|
||||||
|
"requires": {
|
||||||
|
"agent-base": "6",
|
||||||
|
"debug": "4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"is-stream": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="
|
||||||
|
},
|
||||||
|
"json-bigint": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
|
||||||
|
"requires": {
|
||||||
|
"bignumber.js": "^9.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"jwa": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==",
|
||||||
|
"requires": {
|
||||||
|
"buffer-equal-constant-time": "1.0.1",
|
||||||
|
"ecdsa-sig-formatter": "1.0.11",
|
||||||
|
"safe-buffer": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"jws": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
|
||||||
|
"requires": {
|
||||||
|
"jwa": "^2.0.0",
|
||||||
|
"safe-buffer": "^5.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lru-cache": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||||
|
"requires": {
|
||||||
|
"yallist": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||||
|
},
|
||||||
|
"node-fetch": {
|
||||||
|
"version": "2.6.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
|
||||||
|
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
|
||||||
|
"requires": {
|
||||||
|
"whatwg-url": "^5.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node-forge": {
|
||||||
|
"version": "1.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
|
||||||
|
"integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA=="
|
||||||
|
},
|
||||||
|
"object-inspect": {
|
||||||
|
"version": "1.12.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
|
||||||
|
"integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ=="
|
||||||
|
},
|
||||||
|
"qs": {
|
||||||
|
"version": "6.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
|
||||||
|
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
|
||||||
|
"requires": {
|
||||||
|
"side-channel": "^1.0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
|
||||||
|
},
|
||||||
|
"side-channel": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
|
||||||
|
"requires": {
|
||||||
|
"call-bind": "^1.0.0",
|
||||||
|
"get-intrinsic": "^1.0.2",
|
||||||
|
"object-inspect": "^1.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tr46": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||||
|
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||||
|
},
|
||||||
|
"url-template": {
|
||||||
|
"version": "2.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz",
|
||||||
|
"integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw=="
|
||||||
|
},
|
||||||
|
"uuid": {
|
||||||
|
"version": "8.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
|
||||||
|
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
|
||||||
|
},
|
||||||
|
"webidl-conversions": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||||
|
},
|
||||||
|
"whatwg-url": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||||
|
"requires": {
|
||||||
|
"tr46": "~0.0.3",
|
||||||
|
"webidl-conversions": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"yallist": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"name": "beta-release",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "app.js",
|
||||||
|
"license": "MIT",
|
||||||
|
"type": "module",
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@googleapis/androidpublisher": "^3.0.0"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,201 @@
|
||||||
|
import * as google from '@googleapis/androidpublisher';
|
||||||
|
import * as fs from "fs";
|
||||||
|
import * as http from 'https';
|
||||||
|
import * as url from 'url';
|
||||||
|
|
||||||
|
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
|
||||||
|
|
||||||
|
const auth = new google.auth.GoogleAuth({
|
||||||
|
keyFile: '.secrets/service-account.json',
|
||||||
|
scopes: ['https://www.googleapis.com/auth/androidpublisher'],
|
||||||
|
})
|
||||||
|
|
||||||
|
const androidPublisher = google.androidpublisher({
|
||||||
|
version: 'v3',
|
||||||
|
auth: auth,
|
||||||
|
})
|
||||||
|
|
||||||
|
const universalApkPath = `${__dirname}/universal.apk`
|
||||||
|
|
||||||
|
export const release = async (github, version, applicationId, artifacts, config) => {
|
||||||
|
const appEditId = await startPlayRelease(applicationId)
|
||||||
|
|
||||||
|
console.log("Uploading bundle...")
|
||||||
|
await uploadBundle(appEditId, applicationId, artifacts.bundle)
|
||||||
|
|
||||||
|
console.log("Uploading mapping...")
|
||||||
|
await uploadMappingFile(appEditId, version.code, applicationId, artifacts.mapping)
|
||||||
|
|
||||||
|
console.log("Assign artifacts to beta release...")
|
||||||
|
await addReleaseToTrack(appEditId, version, applicationId)
|
||||||
|
|
||||||
|
console.log("Commiting draft release...")
|
||||||
|
await androidPublisher.edits.commit({
|
||||||
|
editId: appEditId,
|
||||||
|
packageName: applicationId,
|
||||||
|
}).catch((error) => Promise.reject(error.response.data))
|
||||||
|
|
||||||
|
console.log("Downloading generated universal apk...")
|
||||||
|
await dowloadSignedUniversalApk(
|
||||||
|
version,
|
||||||
|
applicationId,
|
||||||
|
await auth.getAccessToken(),
|
||||||
|
universalApkPath
|
||||||
|
)
|
||||||
|
|
||||||
|
const releaseResult = await github.rest.repos.createRelease({
|
||||||
|
owner: config.owner,
|
||||||
|
repo: config.repo,
|
||||||
|
tag_name: version.name,
|
||||||
|
prerelease: true,
|
||||||
|
generate_release_notes: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log(releaseResult.data.id)
|
||||||
|
|
||||||
|
await github.rest.repos.uploadReleaseAsset({
|
||||||
|
owner: config.owner,
|
||||||
|
repo: config.repo,
|
||||||
|
release_id: releaseResult.data.id,
|
||||||
|
name: `universal-${version.name}.apk`,
|
||||||
|
data: fs.readFileSync(universalApkPath)
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log("Promoting beta draft release to live...")
|
||||||
|
await promoteDraftToLive(applicationId)
|
||||||
|
}
|
||||||
|
|
||||||
|
const startPlayRelease = async (applicationId) => {
|
||||||
|
const result = await androidPublisher.edits.insert({
|
||||||
|
packageName: applicationId
|
||||||
|
}).catch((error) => Promise.reject(error.response.data))
|
||||||
|
return result.data.id
|
||||||
|
}
|
||||||
|
|
||||||
|
const uploadBundle = async (appEditId, applicationId, bundleReleaseFile) => {
|
||||||
|
const res = await androidPublisher.edits.bundles.upload({
|
||||||
|
packageName: applicationId,
|
||||||
|
editId: appEditId,
|
||||||
|
media: {
|
||||||
|
mimeType: 'application/octet-stream',
|
||||||
|
body: fs.createReadStream(bundleReleaseFile)
|
||||||
|
}
|
||||||
|
}).catch((error) => Promise.reject(error.response.data))
|
||||||
|
|
||||||
|
return res.data
|
||||||
|
}
|
||||||
|
|
||||||
|
const uploadMappingFile = async (appEditId, versionCode, applicationId, mappingFilePath) => {
|
||||||
|
await androidPublisher.edits.deobfuscationfiles.upload({
|
||||||
|
packageName: applicationId,
|
||||||
|
editId: appEditId,
|
||||||
|
apkVersionCode: versionCode,
|
||||||
|
deobfuscationFileType: 'proguard',
|
||||||
|
media: {
|
||||||
|
mimeType: 'application/octet-stream',
|
||||||
|
body: fs.createReadStream(mappingFilePath)
|
||||||
|
}
|
||||||
|
}).catch((error) => Promise.reject(error.response.data))
|
||||||
|
}
|
||||||
|
|
||||||
|
const addReleaseToTrack = async (appEditId, version, applicationId) => {
|
||||||
|
const result = await androidPublisher.edits.tracks
|
||||||
|
.update({
|
||||||
|
editId: appEditId,
|
||||||
|
packageName: applicationId,
|
||||||
|
track: "beta",
|
||||||
|
requestBody: {
|
||||||
|
track: "beta",
|
||||||
|
releases: [
|
||||||
|
{
|
||||||
|
name: version.name,
|
||||||
|
status: "draft",
|
||||||
|
releaseNotes: {
|
||||||
|
language: "en-GB",
|
||||||
|
text: "Bug fixes and improvments - See https://github.com/ouchadam/small-talk/releases for more details",
|
||||||
|
},
|
||||||
|
versionCodes: [version.code]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => Promise.reject(error.response.data))
|
||||||
|
return result.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const dowloadSignedUniversalApk = async (version, applicationId, authToken, outputFile) => {
|
||||||
|
console.log("fetching universal apk")
|
||||||
|
|
||||||
|
const apkRes = await androidPublisher.generatedapks.list({
|
||||||
|
packageName: applicationId,
|
||||||
|
versionCode: version.code,
|
||||||
|
})
|
||||||
|
|
||||||
|
const apks = apkRes.data.generatedApks
|
||||||
|
|
||||||
|
console.log(`found ${apks.length} apks`)
|
||||||
|
apks.forEach((apk) => {
|
||||||
|
console.log(apk)
|
||||||
|
})
|
||||||
|
|
||||||
|
const id = apks[0].generatedUniversalApk.downloadId
|
||||||
|
|
||||||
|
console.log(`downloading: ${id}`)
|
||||||
|
|
||||||
|
const downloadUrl = `https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${applicationId}/generatedApks/${version.code}/downloads/${id}:download?alt=media`
|
||||||
|
const options = {
|
||||||
|
headers: {
|
||||||
|
"Authorization": `Bearer ${authToken}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await downloadToFile(downloadUrl, options, outputFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
const downloadToFile = async (url, options, outputFile) => {
|
||||||
|
return new Promise((resolve, error) => {
|
||||||
|
http.get(url, options, (response) => {
|
||||||
|
const file = fs.createWriteStream(outputFile)
|
||||||
|
response.pipe(file)
|
||||||
|
|
||||||
|
file.on("finish", () => {
|
||||||
|
file.close()
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
|
||||||
|
file.on("error", (cause) => {
|
||||||
|
error(cause)
|
||||||
|
})
|
||||||
|
}).on("error", (cause) => {
|
||||||
|
error(cause)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const promoteDraftToLive = async () => {
|
||||||
|
const fappEditId = await startPlayRelease(applicationId)
|
||||||
|
|
||||||
|
await androidPublisher.edits.tracks
|
||||||
|
.update({
|
||||||
|
editId: fappEditId,
|
||||||
|
packageName: applicationId,
|
||||||
|
track: "beta",
|
||||||
|
requestBody: {
|
||||||
|
track: "beta",
|
||||||
|
releases: [
|
||||||
|
{
|
||||||
|
status: "completed",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => Promise.reject(error.response.data))
|
||||||
|
|
||||||
|
|
||||||
|
await androidPublisher.edits.commit({
|
||||||
|
editId: fappEditId,
|
||||||
|
packageName: applicationId,
|
||||||
|
}).catch((error) => Promise.reject(error.response.data))
|
||||||
|
}
|
||||||
|
|
|
@ -67,30 +67,10 @@ def collectProjects(predicate) {
|
||||||
return subprojects.findAll { it.buildFile.isFile() && predicate(it) }
|
return subprojects.findAll { it.buildFile.isFile() && predicate(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
//task unitCodeCoverageReport(type: JacocoReport) {
|
|
||||||
// outputs.upToDateWhen { false }
|
|
||||||
// rootProject.apply plugin: 'jacoco'
|
|
||||||
// def excludedProjects = [
|
|
||||||
// 'olm-stub',
|
|
||||||
// 'test-harness'
|
|
||||||
// ]
|
|
||||||
// def projects = collectProjects { !excludedProjects.contains(it.name) }
|
|
||||||
// dependsOn { ["app:assembleDebug"] + projects*.test }
|
|
||||||
// initializeReport(it, projects, excludes)
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//task harnessCodeCoverageReport(type: JacocoReport) {
|
|
||||||
// outputs.upToDateWhen { false }
|
|
||||||
// rootProject.apply plugin: 'jacoco'
|
|
||||||
// def projects = collectProjects { true }
|
|
||||||
// dependsOn { ["app:assembleDebug", project(":test-harness").test] }
|
|
||||||
// initializeReport(it, projects, excludes)
|
|
||||||
//}
|
|
||||||
|
|
||||||
task allCodeCoverageReport(type: JacocoReport) {
|
task allCodeCoverageReport(type: JacocoReport) {
|
||||||
outputs.upToDateWhen { false }
|
outputs.upToDateWhen { false }
|
||||||
rootProject.apply plugin: 'jacoco'
|
rootProject.apply plugin: 'jacoco'
|
||||||
def projects = collectProjects { !it.name.contains("stub") }
|
def projects = collectProjects { !it.name.contains("stub") && !it.name.contains("-noop") }
|
||||||
dependsOn { ["app:assembleDebug"] + projects*.test }
|
dependsOn { ["app:assembleDebug"] + projects*.test }
|
||||||
initializeReport(it, projects, excludes)
|
initializeReport(it, projects, excludes)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
./gradlew clean bundleRelease -Punsigned --no-daemon --no-configuration-cache --no-build-cache
|
||||||
|
|
||||||
|
WORKING_DIR=app/build/outputs/bundle/release
|
||||||
|
RELEASE_AAB=$WORKING_DIR/app-release.aab
|
||||||
|
|
||||||
|
cp $RELEASE_AAB $WORKING_DIR/app-release-unsigned.aab
|
||||||
|
|
||||||
|
echo "signing $RELEASE_AAB"
|
||||||
|
jarsigner -verbose -sigalg SHA256withRSA -digestalg SHA-256 \
|
||||||
|
-keystore .secrets/upload-key.jks \
|
||||||
|
-storepass $1 \
|
||||||
|
$RELEASE_AAB \
|
||||||
|
key0
|
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"name": "0.0.1-alpha03",
|
"name": "0.0.1-alpha04",
|
||||||
"code": 5
|
"code": 7
|
||||||
}
|
}
|
Loading…
Reference in New Issue