From 55b54f43fefdfe50240e719962e232759ddf0de2 Mon Sep 17 00:00:00 2001 From: dkhawk <107309+dkhawk@users.noreply.github.com> Date: Mon, 26 Jan 2026 17:37:45 -0700 Subject: [PATCH 1/3] fix: bypass secrets check in CI and fix launchDebug package --- .vscode/settings.json | 3 +++ Maps3DSamples/ApiDemos/java-app/build.gradle.kts | 2 +- Maps3DSamples/ApiDemos/kotlin-app/build.gradle.kts | 11 ++++++++++- 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..11331294 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.configuration.updateBuildConfiguration": "automatic" +} \ No newline at end of file diff --git a/Maps3DSamples/ApiDemos/java-app/build.gradle.kts b/Maps3DSamples/ApiDemos/java-app/build.gradle.kts index a8989c54..ee662932 100644 --- a/Maps3DSamples/ApiDemos/java-app/build.gradle.kts +++ b/Maps3DSamples/ApiDemos/java-app/build.gradle.kts @@ -19,7 +19,7 @@ import java.io.File // Check for secrets.properties file before proceeding with build tasks. val secretsFile = rootProject.file("secrets.properties") -if (!secretsFile.exists()) { +if (!secretsFile.exists() && System.getenv("CI") != "true") { val requestedTasks = gradle.startParameter.taskNames if (requestedTasks.isEmpty()) { // It's likely an IDE sync if no tasks are specified, so just issue a warning. diff --git a/Maps3DSamples/ApiDemos/kotlin-app/build.gradle.kts b/Maps3DSamples/ApiDemos/kotlin-app/build.gradle.kts index ac36d7e6..1abe3866 100644 --- a/Maps3DSamples/ApiDemos/kotlin-app/build.gradle.kts +++ b/Maps3DSamples/ApiDemos/kotlin-app/build.gradle.kts @@ -19,7 +19,7 @@ import java.io.File // Check for secrets.properties file before proceeding with build tasks. val secretsFile = rootProject.file("secrets.properties") -if (!secretsFile.exists()) { +if (!secretsFile.exists() && System.getenv("CI") != "true") { val requestedTasks = gradle.startParameter.taskNames if (requestedTasks.isEmpty()) { // It's likely an IDE sync if no tasks are specified, so just issue a warning. @@ -139,3 +139,12 @@ secrets { // checked in version control. defaultPropertiesFileName = "local.defaults.properties" } + +tasks.register("launchDebug") { + dependsOn("installDebug") + commandLine("adb", "shell", "am", "start", "-n", "com.example.maps3dkotlin/.MainActivity") + doLast { + println("Launched com.example.maps3dkotlin/.MainActivity") + } +} + From a7cb5039759cd1bad83cf203b9b192a218ed7487 Mon Sep 17 00:00:00 2001 From: dkhawk <107309+dkhawk@users.noreply.github.com> Date: Tue, 27 Jan 2026 08:54:06 -0700 Subject: [PATCH 2/3] chore: remove .vscode from tracking and ignore it --- .gitignore | 3 +++ .vscode/settings.json | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.gitignore b/.gitignore index 1ca8e54f..fa4ee3c5 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,6 @@ google-services.json .DS_Store *.swp + +# VS Code +.vscode/ diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 11331294..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "java.configuration.updateBuildConfiguration": "automatic" -} \ No newline at end of file From 88c26135411337c4a692b0cc0e90fcee34bfb008 Mon Sep 17 00:00:00 2001 From: dkhawk <107309+dkhawk@users.noreply.github.com> Date: Thu, 2 Apr 2026 17:29:29 -0600 Subject: [PATCH 3/3] build(secrets): centralize validation and modernize CI bypass Centralize the secrets.properties enforcement logic into a single authoritative check in the root build.gradle.kts file, removing heavy duplication across six subprojects. Replace brittle runtime environment checks with safe, build-time BuildConfig.IS_CI constants for automated testing pipelines. - Create root build.gradle.kts for workspace-wide validation - Remove duplicated secrets-checking blocks from subproject scripts - Inject BuildConfig.IS_CI and apply manifest placeholders in CI - Update Application classes to respect BuildConfig.IS_CI early returns - Untrack LOG.md and add to local exclude file - Fill out missing PLACES_API_KEY in defaults properties --- LOG.md | 8 --- .../ApiDemos/java-app/build.gradle.kts | 65 +++-------------- .../maps3djava/Maps3DJavaApplication.java | 3 + .../ApiDemos/kotlin-app/build.gradle.kts | 66 +++-------------- .../maps3dkotlin/Maps3DKotlinApplication.kt | 3 + Maps3DSamples/advanced/app/build.gradle.kts | 63 ++-------------- PlacesUIKit3D/build.gradle.kts | 9 +++ .../placesuikit3d/Maps3DPlacesApplication.kt | 6 ++ build.gradle.kts | 72 +++++++++++++++++++ local.defaults.properties | 1 + snippets/java-app/build.gradle.kts | 63 ++-------------- snippets/kotlin-app/build.gradle.kts | 63 ++-------------- 12 files changed, 128 insertions(+), 294 deletions(-) delete mode 100644 LOG.md create mode 100644 build.gradle.kts diff --git a/LOG.md b/LOG.md deleted file mode 100644 index 400812ef..00000000 --- a/LOG.md +++ /dev/null @@ -1,8 +0,0 @@ - -### Task: Implement Monster Tour and Long Press popup (Project: Maps3D Samples) -* **Start:** [Unknown] (Branch: main) -* **End:** $(date +"%I:%M:%S %p %Z") -* **Time Spent:** [Unknown] -* **Purpose:** The user wanted to automate the traversal of the various monster markers in the map, and add a quick-select popup menu to the random button, configuring properties like altitude mode via JSON. -* **Summary of Work:** Shifted marker definitions to a central `monsters.json` data file. Implemented an asynchronous touring sequence in both Kotlin (Coroutines) and Java (Handlers) to fly to, orbit, and display info popovers for each character. Wired up a standard `android.widget.PopupMenu` for the random button long-press. Adjusted altitude modes in JSON. -* **Status:** **[IN PROGRESS (Unmerged)]** diff --git a/Maps3DSamples/ApiDemos/java-app/build.gradle.kts b/Maps3DSamples/ApiDemos/java-app/build.gradle.kts index 648ead02..3ad2c0a6 100644 --- a/Maps3DSamples/ApiDemos/java-app/build.gradle.kts +++ b/Maps3DSamples/ApiDemos/java-app/build.gradle.kts @@ -14,63 +14,7 @@ * limitations under the License. */ -import java.util.Properties -import org.gradle.api.GradleException - -// Check for secrets.properties file and valid API key before proceeding with build tasks. -val secretsFile = rootProject.file("secrets.properties") -val isCI = System.getenv("CI")?.toBoolean() ?: false - -if (!isCI) { - val requestedTasks = gradle.startParameter.taskNames - if (requestedTasks.isEmpty() && !secretsFile.exists()) { - // It's likely an IDE sync if no tasks are specified, so just issue a warning. - println("Warning: secrets.properties not found. Gradle sync may succeed, but building/running the app will fail.") - } else if (requestedTasks.isNotEmpty()) { - val buildTaskKeywords = listOf("build", "install", "assemble") - val isBuildTask = requestedTasks.any { task -> - buildTaskKeywords.any { keyword -> - task.contains(keyword, ignoreCase = true) - } - } - - val testTaskKeywords = listOf("test", "report", "lint") - val isTestTask = requestedTasks.any { task -> - testTaskKeywords.any { keyword -> - task.contains(keyword, ignoreCase = true) - } - } - - val isDebugTask = requestedTasks.any { task -> - task.contains("Debug", ignoreCase = true) || task.contains("installAndLaunch", ignoreCase = true) - } - - if (isBuildTask && !isTestTask && isDebugTask) { - val defaultsFile = rootProject.file("local.defaults.properties") - val requiredKeysMessage = if (defaultsFile.exists()) { - defaultsFile.readText() - } else { - "MAPS3D_API_KEY=" - } - - if (!secretsFile.exists()) { - throw GradleException("secrets.properties file not found. Please create a 'secrets.properties' file in the root project directory with the following content:\n\n$requiredKeysMessage") - } - - val secrets = Properties() - secretsFile.inputStream().use { secrets.load(it) } - val apiKey = secrets.getProperty("MAPS3D_API_KEY") - - if (apiKey.isNullOrBlank() || !apiKey.matches(Regex("^AIza[a-zA-Z0-9_-]{35}$"))) { - throw GradleException("Invalid or missing MAPS3D_API_KEY in secrets.properties. Please provide a valid Google Maps API key (starts with 'AIza').") - } - - if (secrets.getProperty("MAPS_API_KEY") != null) { - println("Warning: Found MAPS_API_KEY in secrets.properties. This project relies exclusively on MAPS3D_API_KEY.") - } - } - } -} +val isCI = rootProject.extra["isCI"] as? Boolean ?: false plugins { alias(libs.plugins.android.application) @@ -92,6 +36,13 @@ android { versionName = "1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + + if (isCI) { + manifestPlaceholders["MAPS3D_API_KEY"] = "DEFAULT_API_KEY" + manifestPlaceholders["PLACES_API_KEY"] = "DEFAULT_API_KEY" + } + + buildConfigField("Boolean", "IS_CI", "${isCI}") } buildTypes { diff --git a/Maps3DSamples/ApiDemos/java-app/src/main/java/com/example/maps3djava/Maps3DJavaApplication.java b/Maps3DSamples/ApiDemos/java-app/src/main/java/com/example/maps3djava/Maps3DJavaApplication.java index aafef684..21bab65b 100644 --- a/Maps3DSamples/ApiDemos/java-app/src/main/java/com/example/maps3djava/Maps3DJavaApplication.java +++ b/Maps3DSamples/ApiDemos/java-app/src/main/java/com/example/maps3djava/Maps3DJavaApplication.java @@ -58,6 +58,9 @@ public void onCreate() { * incorrectly configured, and a RuntimeException is thrown. */ private void checkApiKey() { + if (BuildConfig.IS_CI) { + return; + } try { ApplicationInfo appInfo = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA); diff --git a/Maps3DSamples/ApiDemos/kotlin-app/build.gradle.kts b/Maps3DSamples/ApiDemos/kotlin-app/build.gradle.kts index e50557d5..fa716921 100644 --- a/Maps3DSamples/ApiDemos/kotlin-app/build.gradle.kts +++ b/Maps3DSamples/ApiDemos/kotlin-app/build.gradle.kts @@ -14,64 +14,7 @@ * limitations under the License. */ -import org.gradle.api.GradleException -import java.io.File -import java.util.Properties - -// Check for secrets.properties file and valid API key before proceeding with build tasks. -val secretsFile = rootProject.file("secrets.properties") -val isCI = System.getenv("CI")?.toBoolean() ?: false - -if (!isCI) { - val requestedTasks = gradle.startParameter.taskNames - if (requestedTasks.isEmpty() && !secretsFile.exists()) { - // It's likely an IDE sync if no tasks are specified, so just issue a warning. - println("Warning: secrets.properties not found. Gradle sync may succeed, but building/running the app will fail.") - } else if (requestedTasks.isNotEmpty()) { - val buildTaskKeywords = listOf("build", "install", "assemble") - val isBuildTask = requestedTasks.any { task -> - buildTaskKeywords.any { keyword -> - task.contains(keyword, ignoreCase = true) - } - } - - val testTaskKeywords = listOf("test", "report", "lint") - val isTestTask = requestedTasks.any { task -> - testTaskKeywords.any { keyword -> - task.contains(keyword, ignoreCase = true) - } - } - - val isDebugTask = requestedTasks.any { task -> - task.contains("Debug", ignoreCase = true) || task.contains("installAndLaunch", ignoreCase = true) - } - - if (isBuildTask && !isTestTask && isDebugTask) { - val defaultsFile = rootProject.file("local.defaults.properties") - val requiredKeysMessage = if (defaultsFile.exists()) { - defaultsFile.readText() - } else { - "MAPS3D_API_KEY=" - } - - if (!secretsFile.exists()) { - throw GradleException("secrets.properties file not found. Please create a 'secrets.properties' file in the root project directory with the following content:\n\n$requiredKeysMessage") - } - - val secrets = Properties() - secretsFile.inputStream().use { secrets.load(it) } - val apiKey = secrets.getProperty("MAPS3D_API_KEY") - - if (apiKey.isNullOrBlank() || !apiKey.matches(Regex("^AIza[a-zA-Z0-9_-]{35}$"))) { - throw GradleException("Invalid or missing MAPS3D_API_KEY in secrets.properties. Please provide a valid Google Maps API key (starts with 'AIza').") - } - - if (secrets.getProperty("MAPS_API_KEY") != null) { - println("Warning: Found MAPS_API_KEY in secrets.properties. This project relies exclusively on MAPS3D_API_KEY.") - } - } - } -} +val isCI = rootProject.extra["isCI"] as? Boolean ?: false plugins { alias(libs.plugins.android.application) @@ -95,6 +38,13 @@ android { versionName = "1.7.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + + if (isCI) { + manifestPlaceholders["MAPS3D_API_KEY"] = "DEFAULT_API_KEY" + manifestPlaceholders["PLACES_API_KEY"] = "DEFAULT_API_KEY" + } + + buildConfigField("Boolean", "IS_CI", "${isCI}") } buildTypes { diff --git a/Maps3DSamples/ApiDemos/kotlin-app/src/main/java/com/example/maps3dkotlin/Maps3DKotlinApplication.kt b/Maps3DSamples/ApiDemos/kotlin-app/src/main/java/com/example/maps3dkotlin/Maps3DKotlinApplication.kt index 4f1da61e..26872d3c 100644 --- a/Maps3DSamples/ApiDemos/kotlin-app/src/main/java/com/example/maps3dkotlin/Maps3DKotlinApplication.kt +++ b/Maps3DSamples/ApiDemos/kotlin-app/src/main/java/com/example/maps3dkotlin/Maps3DKotlinApplication.kt @@ -49,6 +49,9 @@ class Maps3DKotlinApplication : Application() { * incorrectly configured, and a RuntimeException is thrown. */ private fun checkApiKey() { + if (BuildConfig.IS_CI) { + return + } try { val appInfo = packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA) diff --git a/Maps3DSamples/advanced/app/build.gradle.kts b/Maps3DSamples/advanced/app/build.gradle.kts index ce0330ad..3cf83b2c 100644 --- a/Maps3DSamples/advanced/app/build.gradle.kts +++ b/Maps3DSamples/advanced/app/build.gradle.kts @@ -14,63 +14,7 @@ * limitations under the License. */ -import java.util.Properties -import org.gradle.api.GradleException - -// Check for secrets.properties file and valid API key before proceeding with build tasks. -val secretsFile = rootProject.file("secrets.properties") -val isCI = System.getenv("CI")?.toBoolean() ?: false - -if (!isCI) { - val requestedTasks = gradle.startParameter.taskNames - if (requestedTasks.isEmpty() && !secretsFile.exists()) { - // It's likely an IDE sync if no tasks are specified, so just issue a warning. - println("Warning: secrets.properties not found. Gradle sync may succeed, but building/running the app will fail.") - } else if (requestedTasks.isNotEmpty()) { - val buildTaskKeywords = listOf("build", "install", "assemble") - val isBuildTask = requestedTasks.any { task -> - buildTaskKeywords.any { keyword -> - task.contains(keyword, ignoreCase = true) - } - } - - val testTaskKeywords = listOf("test", "report", "lint") - val isTestTask = requestedTasks.any { task -> - testTaskKeywords.any { keyword -> - task.contains(keyword, ignoreCase = true) - } - } - - val isDebugTask = requestedTasks.any { task -> - task.contains("Debug", ignoreCase = true) || task.contains("installAndLaunch", ignoreCase = true) - } - - if (isBuildTask && !isTestTask && isDebugTask) { - val defaultsFile = rootProject.file("local.defaults.properties") - val requiredKeysMessage = if (defaultsFile.exists()) { - defaultsFile.readText() - } else { - "MAPS3D_API_KEY=" - } - - if (!secretsFile.exists()) { - throw GradleException("secrets.properties file not found. Please create a 'secrets.properties' file in the root project directory with the following content:\n\n$requiredKeysMessage") - } - - val secrets = Properties() - secretsFile.inputStream().use { secrets.load(it) } - val apiKey = secrets.getProperty("MAPS3D_API_KEY") - - if (apiKey.isNullOrBlank() || !apiKey.matches(Regex("^AIza[a-zA-Z0-9_-]{35}$"))) { - throw GradleException("Invalid or missing MAPS3D_API_KEY in secrets.properties. Please provide a valid Google Maps API key (starts with 'AIza').") - } - - if (secrets.getProperty("MAPS_API_KEY") != null) { - println("Warning: Found MAPS_API_KEY in secrets.properties. This project relies exclusively on MAPS3D_API_KEY.") - } - } - } -} +val isCI = rootProject.extra["isCI"] as? Boolean ?: false plugins { alias(libs.plugins.android.application) @@ -98,6 +42,11 @@ android { versionName = "1.7.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + + if (isCI) { + manifestPlaceholders["MAPS3D_API_KEY"] = "DEFAULT_API_KEY" + manifestPlaceholders["PLACES_API_KEY"] = "DEFAULT_API_KEY" + } } buildTypes { diff --git a/PlacesUIKit3D/build.gradle.kts b/PlacesUIKit3D/build.gradle.kts index 67405d30..a53deb64 100644 --- a/PlacesUIKit3D/build.gradle.kts +++ b/PlacesUIKit3D/build.gradle.kts @@ -14,6 +14,8 @@ * limitations under the License. */ +val isCI = rootProject.extra["isCI"] as? Boolean ?: false + // The `plugins` block is where we apply Gradle plugins to this module. // Plugins add new tasks and configurations to our build process. plugins { @@ -57,6 +59,13 @@ android { // Specifies the instrumentation runner for running Android tests. testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + + if (isCI) { + manifestPlaceholders["MAPS3D_API_KEY"] = "DEFAULT_API_KEY" + manifestPlaceholders["PLACES_API_KEY"] = "DEFAULT_API_KEY" + } + + buildConfigField("Boolean", "IS_CI", "${isCI}") } buildTypes { diff --git a/PlacesUIKit3D/src/main/java/com/example/placesuikit3d/Maps3DPlacesApplication.kt b/PlacesUIKit3D/src/main/java/com/example/placesuikit3d/Maps3DPlacesApplication.kt index e54e5163..63f797b6 100644 --- a/PlacesUIKit3D/src/main/java/com/example/placesuikit3d/Maps3DPlacesApplication.kt +++ b/PlacesUIKit3D/src/main/java/com/example/placesuikit3d/Maps3DPlacesApplication.kt @@ -32,6 +32,9 @@ class Maps3DPlacesApplication : Application() { } private fun initializePlaces() { + if (BuildConfig.IS_CI) { + return + } val apiKey = BuildConfig.PLACES_API_KEY if (apiKey == null || apiKey.isBlank() || apiKey == "DEFAULT_API_KEY") { @@ -58,6 +61,9 @@ class Maps3DPlacesApplication : Application() { * incorrectly configured, and a RuntimeException is thrown. */ private fun checkApiKey() { + if (BuildConfig.IS_CI) { + return + } try { val appInfo = packageManager.getApplicationInfo(packageName, PackageManager.GET_META_DATA) diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 00000000..0ab97e06 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,72 @@ +/* + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.util.Properties + +// Evaluate if we are in a CI environment +val isCI = System.getenv("CI")?.toBoolean() ?: false + +// Share the isCI flag with all subprojects via Gradle's extra properties +extra["isCI"] = isCI + +if (!isCI) { + val secretsFile = file("secrets.properties") + val requestedTasks = gradle.startParameter.taskNames + + if (requestedTasks.isEmpty() && !secretsFile.exists()) { + // It's likely an IDE sync if no tasks are specified, so just issue a warning. + println("Warning: secrets.properties not found. Gradle sync may succeed, but building/running the app will fail.") + } else if (requestedTasks.isNotEmpty()) { + val buildTaskKeywords = setOf("build", "install", "assemble") + val testTaskKeywords = setOf("test", "report", "lint") + + val isBuildTask = requestedTasks.any { name -> + buildTaskKeywords.any { kw -> name.contains(kw, ignoreCase = true) } + } + val isTestTask = requestedTasks.any { name -> + testTaskKeywords.any { kw -> name.contains(kw, ignoreCase = true) } + } + val isDebugTask = requestedTasks.any { task -> + task.contains("Debug", ignoreCase = true) || task.contains("installAndLaunch", ignoreCase = true) + } + + if (isBuildTask && !isTestTask && isDebugTask) { + val defaultsFile = file("local.defaults.properties") + val requiredKeysMessage = if (defaultsFile.exists()) { + defaultsFile.readText() + } else { + "MAPS3D_API_KEY=\nPLACES_API_KEY=" + } + + if (!secretsFile.exists()) { + throw GradleException("secrets.properties file not found. Please create a 'secrets.properties' file in the root project directory with the following content:\n\n$requiredKeysMessage") + } + + val secrets = Properties() + secretsFile.inputStream().use { secrets.load(it) } + val mapsApiKey = secrets.getProperty("MAPS3D_API_KEY") + val placesApiKey = secrets.getProperty("PLACES_API_KEY") + + if (mapsApiKey.isNullOrBlank() || !mapsApiKey.matches(Regex("^AIza[a-zA-Z0-9_-]{35}$"))) { + throw GradleException("Invalid or missing MAPS3D_API_KEY in secrets.properties. Please provide a valid Google Maps API key (starts with 'AIza').") + } + + if (placesApiKey.isNullOrBlank() || !placesApiKey.matches(Regex("^AIza[a-zA-Z0-9_-]{35}$"))) { + throw GradleException("Invalid or missing PLACES_API_KEY in secrets.properties. Please provide a valid Google Places API key (starts with 'AIza').") + } + } + } +} diff --git a/local.defaults.properties b/local.defaults.properties index 48e6efec..1da042f7 100644 --- a/local.defaults.properties +++ b/local.defaults.properties @@ -1 +1,2 @@ MAPS3D_API_KEY=DEFAULT_API_KEY +PLACES_API_KEY=DEFAULT_API_KEY diff --git a/snippets/java-app/build.gradle.kts b/snippets/java-app/build.gradle.kts index 36a52b16..01601bab 100644 --- a/snippets/java-app/build.gradle.kts +++ b/snippets/java-app/build.gradle.kts @@ -14,63 +14,7 @@ * limitations under the License. */ -import java.util.Properties -import org.gradle.api.GradleException - -// Check for secrets.properties file and valid API key before proceeding with build tasks. -val secretsFile = rootProject.file("secrets.properties") -val isCI = System.getenv("CI")?.toBoolean() ?: false - -if (!isCI) { - val requestedTasks = gradle.startParameter.taskNames - if (requestedTasks.isEmpty() && !secretsFile.exists()) { - // It's likely an IDE sync if no tasks are specified, so just issue a warning. - println("Warning: secrets.properties not found. Gradle sync may succeed, but building/running the app will fail.") - } else if (requestedTasks.isNotEmpty()) { - val buildTaskKeywords = listOf("build", "install", "assemble") - val isBuildTask = requestedTasks.any { task -> - buildTaskKeywords.any { keyword -> - task.contains(keyword, ignoreCase = true) - } - } - - val testTaskKeywords = listOf("test", "report", "lint") - val isTestTask = requestedTasks.any { task -> - testTaskKeywords.any { keyword -> - task.contains(keyword, ignoreCase = true) - } - } - - val isDebugTask = requestedTasks.any { task -> - task.contains("Debug", ignoreCase = true) || task.contains("installAndLaunch", ignoreCase = true) - } - - if (isBuildTask && !isTestTask && isDebugTask) { - val defaultsFile = rootProject.file("local.defaults.properties") - val requiredKeysMessage = if (defaultsFile.exists()) { - defaultsFile.readText() - } else { - "MAPS3D_API_KEY=" - } - - if (!secretsFile.exists()) { - throw GradleException("secrets.properties file not found. Please create a 'secrets.properties' file in the root project directory with the following content:\n\n$requiredKeysMessage") - } - - val secrets = Properties() - secretsFile.inputStream().use { secrets.load(it) } - val apiKey = secrets.getProperty("MAPS3D_API_KEY") - - if (apiKey.isNullOrBlank() || !apiKey.matches(Regex("^AIza[a-zA-Z0-9_-]{35}$"))) { - throw GradleException("Invalid or missing MAPS3D_API_KEY in secrets.properties. Please provide a valid Google Maps API key (starts with 'AIza').") - } - - if (secrets.getProperty("MAPS_API_KEY") != null) { - println("Warning: Found MAPS_API_KEY in secrets.properties. This project relies exclusively on MAPS3D_API_KEY.") - } - } - } -} +val isCI = rootProject.extra["isCI"] as? Boolean ?: false plugins { alias(libs.plugins.android.application) @@ -90,6 +34,11 @@ android { versionName = "1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + + if (isCI) { + manifestPlaceholders["MAPS3D_API_KEY"] = "DEFAULT_API_KEY" + manifestPlaceholders["PLACES_API_KEY"] = "DEFAULT_API_KEY" + } } buildTypes { diff --git a/snippets/kotlin-app/build.gradle.kts b/snippets/kotlin-app/build.gradle.kts index 98db299d..f7931abf 100644 --- a/snippets/kotlin-app/build.gradle.kts +++ b/snippets/kotlin-app/build.gradle.kts @@ -14,63 +14,7 @@ * limitations under the License. */ -import java.util.Properties -import org.gradle.api.GradleException - -// Check for secrets.properties file and valid API key before proceeding with build tasks. -val secretsFile = rootProject.file("secrets.properties") -val isCI = System.getenv("CI")?.toBoolean() ?: false - -if (!isCI) { - val requestedTasks = gradle.startParameter.taskNames - if (requestedTasks.isEmpty() && !secretsFile.exists()) { - // It's likely an IDE sync if no tasks are specified, so just issue a warning. - println("Warning: secrets.properties not found. Gradle sync may succeed, but building/running the app will fail.") - } else if (requestedTasks.isNotEmpty()) { - val buildTaskKeywords = listOf("build", "install", "assemble") - val isBuildTask = requestedTasks.any { task -> - buildTaskKeywords.any { keyword -> - task.contains(keyword, ignoreCase = true) - } - } - - val testTaskKeywords = listOf("test", "report", "lint") - val isTestTask = requestedTasks.any { task -> - testTaskKeywords.any { keyword -> - task.contains(keyword, ignoreCase = true) - } - } - - val isDebugTask = requestedTasks.any { task -> - task.contains("Debug", ignoreCase = true) || task.contains("installAndLaunch", ignoreCase = true) - } - - if (isBuildTask && !isTestTask && isDebugTask) { - val defaultsFile = rootProject.file("local.defaults.properties") - val requiredKeysMessage = if (defaultsFile.exists()) { - defaultsFile.readText() - } else { - "MAPS3D_API_KEY=" - } - - if (!secretsFile.exists()) { - throw GradleException("secrets.properties file not found. Please create a 'secrets.properties' file in the root project directory with the following content:\n\n$requiredKeysMessage") - } - - val secrets = Properties() - secretsFile.inputStream().use { secrets.load(it) } - val apiKey = secrets.getProperty("MAPS3D_API_KEY") - - if (apiKey.isNullOrBlank() || !apiKey.matches(Regex("^AIza[a-zA-Z0-9_-]{35}$"))) { - throw GradleException("Invalid or missing MAPS3D_API_KEY in secrets.properties. Please provide a valid Google Maps API key (starts with 'AIza').") - } - - if (secrets.getProperty("MAPS_API_KEY") != null) { - println("Warning: Found MAPS_API_KEY in secrets.properties. This project relies exclusively on MAPS3D_API_KEY.") - } - } - } -} +val isCI = rootProject.extra["isCI"] as? Boolean ?: false plugins { alias(libs.plugins.android.application) @@ -91,6 +35,11 @@ android { versionName = "1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + + if (isCI) { + manifestPlaceholders["MAPS3D_API_KEY"] = "DEFAULT_API_KEY" + manifestPlaceholders["PLACES_API_KEY"] = "DEFAULT_API_KEY" + } } buildTypes {