Skip to content

Commit

Permalink
Configure release signing for conference app (#1124)
Browse files Browse the repository at this point in the history
  • Loading branch information
ashdavies authored Aug 28, 2024
1 parent 673b18a commit 437d32d
Show file tree
Hide file tree
Showing 11 changed files with 183 additions and 35 deletions.
86 changes: 86 additions & 0 deletions .github/workflows/android-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Android Release

on:
push:
branches:
- main

workflow_dispatch:
inputs:
log_level:
type: choice
description: Log Level
required: false
default: info
options:
- error
- quiet
- warning
- lifecycle
- info
- debug

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number }}
cancel-in-progress: true

jobs:
build:
name: Assemble Release
runs-on: ubuntu-latest

permissions:
pull-requests: 'write'
id-token: 'write'

steps:
- uses: actions/checkout@v3

- uses: ./.github/actions/setup-cloud
with:
workload_identity_provider: ${{ secrets.GOOGLE_WORKLOAD_IDENTITY }}
service_account: ${{ secrets.GOOGLE_SERVICE_ACCOUNT_ID }}
setup_gcloud: false

- uses: ./.github/actions/setup-gradle

- uses: 1password/load-secrets-action/configure@v2
with:
service-account-token: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}

- id: op-secrets
uses: 1password/load-secrets-action@v2
with:
export-env: false
env:
GOOGLE_SERVICES: op://development/google services/playground release/base64
KEYSTORE_BASE64: op://development/playground keystore/keystore base64
KEYSTORE_PASSWORD: op://development/playground keystore/keystore password
KEY_ALIAS: op://development/playground keystore/key alias
KEY_PASSWORD: op://development/playground keystore/key password

- env:
GOOGLE_SERVICES: ${{ steps.op-secrets.outputs.GOOGLE_SERVICES }}
KEYSTORE_BASE64: ${{ steps.op-secrets.outputs.KEYSTORE_BASE64 }}
run: |
echo $GOOGLE_SERVICES | base64 --decode > app-launcher/android/google-services.json
echo $GOOGLE_SERVICES | base64 --decode > conferences-app/google-services.json
echo $KEYSTORE_BASE64 | base64 --decode > keystore.jks
- id: gradle
env:
ANDROID_API_KEY: ${{ secrets.ANDROID_API_KEY }}
BROWSER_API_KEY: ${{ secrets.BROWSER_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
KEY_STORE_FILE: keystore.jks
KEY_STORE_PASSWORD: ${{ steps.op-secrets.outputs.KEYSTORE_PASSWORD }}
RELEASE_KEY_ALIAS: ${{ steps.op-secrets.outputs.KEY_ALIAS }}
RELEASE_KEY_PASSWORD: ${{ steps.op-secrets.outputs.KEY_PASSWORD }}
SERVER_CLIENT_ID: ${{ secrets.SERVER_CLIENT_ID }}
run: ./gradlew assembleRelease --console=plain

- uses: actions/upload-artifact@v2
with:
if-no-files-found: error
name: apk-release
path: "**/*-release.apk"
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Pre Merge Checks
name: Pull Request
on: [ pull_request ]

concurrency:
Expand All @@ -7,7 +7,7 @@ concurrency:

jobs:
build:
name: Pre Merge Checks
name: Build
runs-on: ubuntu-latest

permissions:
Expand All @@ -17,8 +17,7 @@ jobs:
steps:
- uses: actions/checkout@v3

- id: setup-cloud
uses: ./.github/actions/setup-cloud
- uses: ./.github/actions/setup-cloud
with:
workload_identity_provider: ${{ secrets.GOOGLE_WORKLOAD_IDENTITY }}
service_account: ${{ secrets.GOOGLE_SERVICE_ACCOUNT_ID }}
Expand Down
11 changes: 8 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
/.idea

# Android
/gradle.properties
**/local.properties
/captures
*.hprof
*.apk
*.ap_

# Database
*.db
Expand All @@ -22,9 +22,14 @@
**/*.log

# Gradle
/gradle.properties
**/local.properties
.gradle
build
/reports

# Keystore Files
*.jks
*.keystore

# Kotlin
.kotlin/sessions
Expand Down
Binary file removed app-launcher/android/google-services.aes
Binary file not shown.
1 change: 0 additions & 1 deletion asg-service/src/.gitignore

This file was deleted.

51 changes: 44 additions & 7 deletions conferences-app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,48 @@ android {
res.srcDirs("src/androidMain/res")
}

val release by signingConfigs.creating {
val debug by signingConfigs.getting
initWith(debug)

enableV3Signing = true
enableV4Signing = true

val keyStoreFile by stringPropertyOrNull {
if (it != null) storeFile = rootProject.file(it)
}

val keyStorePassword by stringPropertyOrNull {
if (it != null) storePassword = it
}

val releaseKeyAlias by stringPropertyOrNull {
if (it != null) keyAlias = it
}

val releaseKeyPassword by stringPropertyOrNull {
if (it != null) keyPassword = it
}
}

buildTypes {
debug {
applicationIdSuffix = ".debug"
}

release {
isMinifyEnabled = true
isShrinkResources = true

signingConfig = release

proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro",
)
}
}

defaultConfig {
versionName = "1.0"
versionCode = 1
Expand All @@ -26,13 +68,8 @@ android {
}

buildConfig {
val androidApiKey by stringProperty { value ->
buildConfigField("ANDROID_API_KEY", value)
}

val androidStrictMode by booleanProperty { value ->
buildConfigField("ANDROID_STRICT_MODE", value)
}
val androidApiKey by stringPropertyWithTag(::buildConfigField)
val androidStrictMode by booleanPropertyWithTag(::buildConfigField)

packageName.set(android.namespace)
}
Expand Down
Binary file removed conferences-app/google-services.aes
Binary file not shown.
1 change: 1 addition & 0 deletions conferences-app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-dontwarn org.slf4j.impl.StaticLoggerBinder
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ internal class MainActivity : ComponentActivity() {
}

setContent {
LauncherApp { intent.getStringExtra(it) }
LauncherApp()
}
}
}

@Composable
private fun LauncherApp(context: Context = LocalContext.current, extra: (String) -> String?) {
private fun LauncherApp(context: Context = LocalContext.current) {
ProvideHttpClient(
config = {
install(DefaultRequest) {
Expand Down
57 changes: 39 additions & 18 deletions fused-properties/src/main/kotlin/StringProperty.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,60 @@ import kotlin.properties.ReadOnlyProperty

public fun interface ReadOnlyDelegateProvider<T> : PropertyDelegateProvider<Any?, ReadOnlyProperty<Any?, T>>

private fun Project.stringPropertyProvider(propertyName: String): Provider<String> {
private interface PropertyDefinition {
val gradlePropertyName: String
val envPropertyName: String
}

private fun PropertyDefinition(propertyName: String) = object : PropertyDefinition {
private val propertyNameParts = propertyName.split(Regex("(?=[A-Z])"))
override val gradlePropertyName = propertyNameParts.joinToString(".") { it.lowercase() }
override val envPropertyName = propertyNameParts.joinToString("_") { it.uppercase() }
}

private fun Project.stringPropertyProvider(definition: PropertyDefinition): Provider<String> {
val rootPropertiesProvider = rootProject.cachedLocalPropertiesProvider()
val localPropertiesProvider = cachedLocalPropertiesProvider()
val startPropertiesProvider = startParameterProvider()

val propertyNameParts = propertyName.split(Regex("(?=[A-Z])"))
val gradlePropertyName = propertyNameParts.joinToString(".") { it.lowercase() }
val envPropertyName = propertyNameParts.joinToString("_") { it.uppercase() }

return startPropertiesProvider.mapOrNull { it[gradlePropertyName] }
.orElse(localPropertiesProvider.map { it.getProperty(gradlePropertyName) })
.orElse(rootPropertiesProvider.map { it.getProperty(gradlePropertyName) })
.orElse(providers.gradleProperty(gradlePropertyName))
.orElse(providers.environmentVariable(envPropertyName))
return startPropertiesProvider.mapOrNull { it[definition.gradlePropertyName] }
.orElse(localPropertiesProvider.map { it.getProperty(definition.gradlePropertyName) })
.orElse(rootPropertiesProvider.map { it.getProperty(definition.gradlePropertyName) })
.orElse(providers.gradleProperty(definition.gradlePropertyName))
.orElse(providers.environmentVariable(definition.envPropertyName))
}

public fun Project.booleanProperty(block: (Boolean) -> Unit = { }): ReadOnlyDelegateProvider<Boolean> {
return readOnlyDelegateProvider { it.get().toBoolean().also(block) }
return readOnlyDelegateProvider { provider, _ -> provider.get().toBoolean().also(block) }
}

public fun Project.booleanPropertyWithTag(action: (String, Boolean) -> Unit): ReadOnlyDelegateProvider<Boolean> {
return readOnlyDelegateProvider { provider, tag -> provider.get().toBoolean().also { action(tag, it) } }
}

public fun Project.stringProperty(block: (String) -> Unit = { }): ReadOnlyDelegateProvider<String> {
return readOnlyDelegateProvider { it.get().also(block) }
return readOnlyDelegateProvider { provider, _ -> provider.get().also(block) }
}

public fun Project.stringPropertyWithTag(action: (String, String) -> Unit): ReadOnlyDelegateProvider<String> {
return readOnlyDelegateProvider { provider, tag -> provider.get().also { action(tag, it) } }
}

public fun Project.stringPropertyOrNull(block: (String?) -> Unit = { }): ReadOnlyDelegateProvider<String?> {
return readOnlyDelegateProvider { it.orNull.also(block) }
return readOnlyDelegateProvider { provider, _ -> provider.orNull.also(block) }
}

private fun <T> Project.readOnlyDelegateProvider(transform: (Provider<String>) -> T): ReadOnlyDelegateProvider<T> {
return ReadOnlyDelegateProvider { _, property ->
val value = transform(stringPropertyProvider(property.name))
ReadOnlyProperty { _, _ -> value }
}
private fun <T> Project.readOnlyDelegateProvider(
transform: (provider: Provider<String>, tag: String) -> T,
): ReadOnlyDelegateProvider<T> = ReadOnlyDelegateProvider { _, property ->
val definition = PropertyDefinition(property.name)

val value = transform(
stringPropertyProvider(definition),
definition.envPropertyName,
)

ReadOnlyProperty { _, _ -> value }
}

private fun <S : Any, T> Provider<S>.mapOrNull(block: (S) -> T?): Provider<T> {
Expand Down
Empty file added keystore.properties
Empty file.

0 comments on commit 437d32d

Please sign in to comment.