Giter Club home page Giter Club logo

secrets-gradle-plugin's Introduction

Secrets Gradle Plugin for Android

Tests Apache-2.0

A Gradle plugin for providing your secrets securely to your Android project.

This Gradle plugin reads secrets from a properties file not checked into version control, such as local.properties, and expose those properties as variables in the Gradle-generated BuildConfig class and in the Android manifest file.

DISCLAIMER: This plugin is primarily for hiding your keys from version control. Since your key is part of the static binary, your API keys are still recoverable by decompiling an APK. So, securing your key using other measures like adding restrictions (if possible) are recommended.

Requirements

  • Gradle-based Android project
  • Android Gradle plugin 7.0.2

Installation

NOTE: Starting from v1.1.0, the plugin ID was changed to "com.google.android.libraries.mapsplatform.secrets-gradle-plugin" and the plugin is now being distributed via Google Maven (gMaven). You can still download previous versions of the plugin from Gradle's plugin portal, but new versions will now only be distributed through gMaven.

  1. In your project's root build.gradle file:

Groovy:

buildscript {
    dependencies {
        classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1"
    }
}

Kotlin:

buildscript {
    dependencies {
        classpath("com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:2.0.1")
    }
}
  1. In your app-level build.gradle file:

Groovy:

plugins {
    id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'
}

Kotlin:

plugins {
    id("com.google.android.libraries.mapsplatform.secrets-gradle-plugin")
}

This plugin also supports library module type (com.android.library). Just install the plugin in your library-level build.gradle file and keys will be visible inside that module as well.

Snapshot Releases

Snapshot releases, which are distributed via GitHub Packages, are also available for latest fixes. To use a snapshot release, add the following repository to your project-level build.gradle file:

Groovy:

buildscript {
    repositories {
        maven {
            url = uri("https://maven.pkg.github.com/google/secrets-gradle-plugin")
            credentials {
                username = project.findProperty("GITHUB_USER") ?: System.getenv("GITHUB_USER")
                password = project.findProperty("GITHUB_TOKEN") ?: System.getenv("GITHUB_TOKEN")
            }
        }
    }
    dependencies {
        classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:<version>-SNAPSHOT"
    }
}

Also, see Authenticating to GitHub Packages.

Example Usage

Example contents of local.properties under your root project:

apiKey=YOUR_API_KEY

After applying the plugin and building your project, the API key then becomes accessible in two ways.

  1. As a BuildConfig value:
val apiKey = BuildConfig.apiKey
  1. As a variable accessible in your AndroidManifest.xml file:
<meta-data android:value="${apiKey}" />

CI/CD Systems

For CI/CD systems, consider creating and checking in version control a default properties file with all the same keys required by your app but with safe default values. To do this, create a properties file and set the defaultPropertiesFileName value to that file name. For example:

secrets {
    defaultPropertiesFileName = 'local.defaults.properties'
}

Configuration Options

The plugin can optionally be configured:

secrets {
    // Change the properties file from the default "local.properties" in your root project
    // to another properties file in your root project.
    propertiesFileName 'secrets.properties'

    // A properties file containing default secret values. This file can be checked in version
    // control.
    defaultPropertiesFileName = 'secrets.defaults.properties'

    // Configure which keys should be ignored by the plugin by providing regular expressions.
    // "sdk.dir" is ignored by default.
    ignoreList.add("keyToIgnore") // Ignore the key "keyToIgnore"
    ignoreList.add("sdk.*")       // Ignore all keys matching the regexp "sdk.*"
}

Build-Variant Specific Properties

To set build-variant specific properties (build type or flavor), create a properties file at the root directory of the project with the same name as the variant. For example, to set keys specific for the release build type, create a new file called release.properties containing release-specific keys.

Contributing

Contributions to this library are always welcome and highly encouraged!

See CONTRIBUTING.md and CODE_OF_CONDUCT.md for more information on how to get started.

License

Apache 2.0. See LICENSE for more information.

secrets-gradle-plugin's People

Contributors

aminsepahan avatar arriolac avatar ericksumargo avatar pelusodan avatar semantic-release-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

secrets-gradle-plugin's Issues

Installation instructions throwing UnknownPluginException

Installation calls for adding com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:1.3.0as a dependency classpath and com.google.android.libraries.mapsplatform.secrets-gradle-plugin to plugins block, this results in

Exception is:
org.gradle.api.plugins.UnknownPluginException: Plugin [id: 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'] was not found in any of the following sources:

- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Plugin Repositories (plugin dependency must include a version number for this source)

What has worked for me and is documented here and here is to add id "com.google.secrets_gradle_plugin" version "0.6.1" to the plugins dsl and not adding the dependency classpath.

The installation instructions are included in Maps SDK Quickstart and don't seem to be working as expected.

To reproduce:

How I can get the value inside an xml file ?

I'm trying with google maps API key as following

in AndroidManifest.xml
<meta-data android:name="com.google.android.geo.API_KEY" android:value="@string/google_maps_key" />

and in google_maps_api.xml

<resources> <string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">"${*.*.*BuildConfig.GoogleMapsAPIKey}"</string> </resources>

I tried to like this and as well like ${GoogleMapsAPIKey} and GoogleMapsAPIKey but always have the same error
Ensure that the following Android Key exists:
API Key: ${*.*.*.BuildConfig.GoogleMapsAPIKey}
and it works fine if I put it in the value in AndroidManifest how to solve this?

NoClassDefFoundError while using AGP 7.0.0-beta04

The plugin fails to build while using it with com.android.tools.build:gradle:7.0.0-beta04. Using 4.2.x works on version 1.3.0 of the plugin and 4.1.x and earlier on version 1.2.0 and earlier of the plugin.

Stracktrace:

com/android/build/api/extension/AndroidComponentsExtension$DefaultImpls
> com.android.build.api.extension.AndroidComponentsExtension$DefaultImpls

* Try:
Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Exception is:
java.lang.NoClassDefFoundError: com/android/build/api/extension/AndroidComponentsExtension$DefaultImpls
	at com.google.android.libraries.mapsplatform.secrets_gradle_plugin.SecretsPlugin.apply(SecretsPlugin.kt:45)
	at com.google.android.libraries.mapsplatform.secrets_gradle_plugin.SecretsPlugin.apply(SecretsPlugin.kt:33)
	at org.gradle.api.internal.plugins.ImperativeOnlyPluginTarget.applyImperative(ImperativeOnlyPluginTarget.java:43)
	at org.gradle.api.internal.plugins.RuleBasedPluginTarget.applyImperative(RuleBasedPluginTarget.java:51)
	at org.gradle.api.internal.plugins.DefaultPluginManager.addPlugin(DefaultPluginManager.java:177)
	at org.gradle.api.internal.plugins.DefaultPluginManager.access$100(DefaultPluginManager.java:51)
	at org.gradle.api.internal.plugins.DefaultPluginManager$AddPluginBuildOperation.run(DefaultPluginManager.java:272)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:56)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$run$1(DefaultBuildOperationExecutor.java:71)
	at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.runWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:45)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:71)
	at org.gradle.api.internal.plugins.DefaultPluginManager.lambda$doApply$0(DefaultPluginManager.java:157)
	at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.apply(DefaultUserCodeApplicationContext.java:43)
	at org.gradle.api.internal.plugins.DefaultPluginManager.doApply(DefaultPluginManager.java:156)
	at org.gradle.api.internal.plugins.DefaultPluginManager.apply(DefaultPluginManager.java:127)
	at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.lambda$applyPlugins$0(DefaultPluginRequestApplicator.java:129)
	at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.applyPlugin(DefaultPluginRequestApplicator.java:185)
	at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.lambda$applyPlugins$1(DefaultPluginRequestApplicator.java:127)
	at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.applyPlugins(DefaultPluginRequestApplicator.java:127)
	at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.applyPlugins(DefaultPluginRequestApplicator.java:123)
	at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:117)
	at org.gradle.configuration.BuildOperationScriptPlugin$1.run(BuildOperationScriptPlugin.java:65)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:56)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$run$1(DefaultBuildOperationExecutor.java:71)
	at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.runWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:45)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:71)
	at org.gradle.configuration.BuildOperationScriptPlugin.lambda$apply$0(BuildOperationScriptPlugin.java:62)
	at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.apply(DefaultUserCodeApplicationContext.java:43)
	at org.gradle.configuration.BuildOperationScriptPlugin.apply(BuildOperationScriptPlugin.java:62)
	at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.lambda$applyToMutableState$0(DefaultProjectStateRegistry.java:250)
	at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.fromMutableState(DefaultProjectStateRegistry.java:277)
	at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.applyToMutableState(DefaultProjectStateRegistry.java:249)
	at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:42)
	at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:26)
	at org.gradle.configuration.project.ConfigureActionsProjectEvaluator.evaluate(ConfigureActionsProjectEvaluator.java:35)
	at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.lambda$run$0(LifecycleProjectEvaluator.java:100)
	at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.lambda$applyToMutableState$0(DefaultProjectStateRegistry.java:250)
	at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.lambda$withProjectLock$3(DefaultProjectStateRegistry.java:310)
	at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:213)
	at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.withProjectLock(DefaultProjectStateRegistry.java:310)
	at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.fromMutableState(DefaultProjectStateRegistry.java:291)
	at org.gradle.api.internal.project.DefaultProjectStateRegistry$ProjectStateImpl.applyToMutableState(DefaultProjectStateRegistry.java:249)
	at org.gradle.configuration.project.LifecycleProjectEvaluator$EvaluateProject.run(LifecycleProjectEvaluator.java:91)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:56)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$run$1(DefaultBuildOperationExecutor.java:71)
	at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.runWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:45)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:71)
	at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:63)
	at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:723)
	at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:150)
	at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:41)
	at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:69)
	at org.gradle.configuration.DefaultProjectsPreparer.prepareProjects(DefaultProjectsPreparer.java:46)
	at org.gradle.configuration.BuildTreePreparingProjectsPreparer.prepareProjects(BuildTreePreparingProjectsPreparer.java:64)
	at org.gradle.configuration.BuildOperationFiringProjectsPreparer$ConfigureBuild.run(BuildOperationFiringProjectsPreparer.java:52)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:56)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$run$1(DefaultBuildOperationExecutor.java:71)
	at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.runWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:45)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:71)
	at org.gradle.configuration.BuildOperationFiringProjectsPreparer.prepareProjects(BuildOperationFiringProjectsPreparer.java:40)
	at org.gradle.initialization.DefaultGradleLauncher.prepareProjects(DefaultGradleLauncher.java:226)
	at org.gradle.initialization.DefaultGradleLauncher.doClassicBuildStages(DefaultGradleLauncher.java:164)
	at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:149)
	at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:125)
	at org.gradle.internal.invocation.GradleBuildController$1.create(GradleBuildController.java:71)
	at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:213)
	at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:67)
	at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:56)
	at org.gradle.tooling.internal.provider.runner.AbstractClientProvidedBuildActionRunner.runClientAction(AbstractClientProvidedBuildActionRunner.java:53)
	at org.gradle.tooling.internal.provider.runner.ClientProvidedPhasedActionRunner.run(ClientProvidedPhasedActionRunner.java:47)
	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
	at org.gradle.launcher.exec.BuildOutcomeReportingBuildActionRunner.run(BuildOutcomeReportingBuildActionRunner.java:66)
	at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
	at org.gradle.tooling.internal.provider.FileSystemWatchingBuildActionRunner.run(FileSystemWatchingBuildActionRunner.java:90)
	at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:41)
	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:49)
	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$3.call(RunAsBuildOperationBuildActionRunner.java:44)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:75)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$3.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:153)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:68)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:62)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.lambda$call$2(DefaultBuildOperationExecutor.java:76)
	at org.gradle.internal.operations.UnmanagedBuildOperationWrapper.callWithUnmanagedSupport(UnmanagedBuildOperationWrapper.java:54)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:76)
	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:44)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter.lambda$execute$0(InProcessBuildActionExecuter.java:59)
	at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:86)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:58)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:30)
	at org.gradle.launcher.exec.BuildTreeScopeLifecycleBuildActionExecuter.lambda$execute$0(BuildTreeScopeLifecycleBuildActionExecuter.java:34)
	at org.gradle.internal.buildtree.BuildTreeState.run(BuildTreeState.java:53)
	at org.gradle.launcher.exec.BuildTreeScopeLifecycleBuildActionExecuter.execute(BuildTreeScopeLifecycleBuildActionExecuter.java:33)
	at org.gradle.launcher.exec.BuildTreeScopeLifecycleBuildActionExecuter.execute(BuildTreeScopeLifecycleBuildActionExecuter.java:28)
	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:104)
	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:55)
	at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:64)
	at org.gradle.tooling.internal.provider.SubscribableBuildActionExecuter.execute(SubscribableBuildActionExecuter.java:37)
	at org.gradle.tooling.internal.provider.SessionScopeLifecycleBuildActionExecuter.lambda$execute$0(SessionScopeLifecycleBuildActionExecuter.java:54)
	at org.gradle.internal.session.BuildSessionState.run(BuildSessionState.java:67)
	at org.gradle.tooling.internal.provider.SessionScopeLifecycleBuildActionExecuter.execute(SessionScopeLifecycleBuildActionExecuter.java:50)
	at org.gradle.tooling.internal.provider.SessionScopeLifecycleBuildActionExecuter.execute(SessionScopeLifecycleBuildActionExecuter.java:36)
	at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:36)
	at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:25)
	at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:59)
	at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:31)
	at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:58)
	at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:42)
	at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:47)
	at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:31)
	at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:65)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:39)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:29)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:35)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:78)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:75)
	at org.gradle.util.Swapper.swap(Swapper.java:38)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:75)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:63)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:84)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:52)
	at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
Caused by: java.lang.ClassNotFoundException: com.android.build.api.extension.AndroidComponentsExtension$DefaultImpls
	... 164 more

Not compatible with `android.enableBuildConfigAsBytecode` Gradle Property

Problem:
If the android.enableBuildConfigAsBytecode=true flag is set in the gradle.properties file, no secrets or extensions will be added to the BuildConfig.

The flag being enabled or disabled does not affect the ability of anything to compile or affect the standard BuildConfig flags. This package will only work if that feature is disabled.

This incompatibility is problematic because

  1. it significantly affects compile-time
  2. the advice given here would cause this to fail and there aren't any logs or other indicators that this is the issue.

Updating .properties file in run time

Hi,
I am trying to use the plugin but an error is blocking me from moving forward. Before I go further, I would like to understand if it is possible to achieve this:

  1. Follow the steps in "Example Usage" to use the plugin.
  2. Create a temp.properties file in the project level folder and enter MAP_KEY=this_is_map_key in the file.
  3. In the manifest file, add
<meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="${MAP_KEY}" />
  1. In runtime, trigger a network call and the response has the real map API key.
  2. Update the entry created in step 2 with the real map API key.
    The activities that need the map API key will use the real map API key provided via the meta-data added in step 3.

I am not sure if updating the value in temp.properties (step 5) in runtime will change the value in the meta-data.
Please advise.

Plugin ignores custom file found in root directory

I created a custom file named service.properties at the root of my project and I stored my google api key in it as such: key_name="value"
In my module's build.gradle file I have this configuration:
secrets { propertiesFileName 'service.properties' }
When I run the project I get the error message saying telling me to check if the api key exist. It does already exists as I originally set my key in the strings.xml file and I read directly from there, before attempting this plugin
I am using v1.3.0 of the plugin

React Native Support

Can I use this in a react native project to store keys for the android folder? If so how do I do it, when I do it how it's done in the android way, I get * What went wrong: A problem occurred evaluating project ':app'.

Error while updating dependency to 2.0.0

After I update the dependency version from 1.3.0 to 2.0.0, I am getting following error after Gradle sync

Unable to load class 'com.android.build.api.variant.AndroidComponentsExtension'.

This is an unexpected error. Please file a bug containing the idea.log file.

Additional information:

  • Gradle build tool version: 4.2.2
  • Gradle wrapper: 7.0.2

Leaked GCP API Keys

I still get Leaked GCP API Keys, any idea how to solve this?

It works when displaying maps, but when it comes to Google Places I need to initialize it on the application class

image

image

More details about the security model and use cases?

Hi ๐Ÿ‘‹ ! Thanks for the plugin! I am not 100% sure when it should be used though.

Secrets like apiKeys are typically super hard (if not impossible) to secure in an app that is shipped to thousands of people. Someone could disassemble the apk and get the apiKeys from the bytecode.

Not having the secrets in source control is nice but ultimately, devs will need an apiKey to work, which means the secrets will be stored on their machine. And the CI would need it as well, which means most of the places where the repository will be cloned will most likely contain the secret.

The use cases I can think of are:

  • open source projects where users will need to create other resources/apiKeys if they clone.
  • not trusting Github (or any other host) with secrets (but that seems overkill given the secrets will be in the wild anyways).

Are there other use cases?

In all cases, I think a disclaimer about the apiKeys being easily extractable from the final app would be nice.

Build-Variant Specific Properties not working when file name as more then one dot.

Config

build.gradle.kts

secrets {
    propertiesFileName = "secrets.properties"
}

files names on root project :

  • debug.secrets.properties
  • secrets.properties

Result Error

Always show the secrets.properties content, even when set as

Solution

There is no bug, I finaly realise my mistake. But in case of someone did the same I have to say you you have to replace the first world by the build variant insted of add it.
So, for propertiesFileName = "secrets.properties" and a debug variant, use file named debug.properties.

CI Configuration for Build-Variant Specific Properties

Followed the notes in the docs and created three files: test.properties, staging.properties, production.properties. They work properly locally.

Now, on the CI (Bitbucket, yml), I have a first step on pipelines that dumps the keys into each build variant file, like this:

- step: &Create-Test-properties
    name: Create-Test-properties
    script:
       - echo API_KEY=$MY_SECRET_VAR > test.properties
    artifacts:
       - test.properties

...

Problem is, the error seem to imply that the plugin will go to local.properties and ignore the build-variant files:

Failed to query the value of property 'buildFlowServiceProperty'.

> Could not isolate value () of type BuildFlowService.Parameters

   > A problem occurred configuring project ''.

      > Failed to notify project evaluation listener.

         > The file '.../local.properties' could not be found

Is there a step I'm missing? Configuration options only mentions defaultPropertiesFileName for CI but then it'll use the default file, not the specific ones.

Leaked GCP API Keys

I still get Leaked GCP API Keys, any idea how to solve this?

It works when displaying maps, but when it comes to Google Places I need to initialize it on the application class

image

image

Remove misleading double quotes in local.defaults.properties file

The local.defaults.properties file contains the following:

MAPS_API_KEY=""

I copied that line and added the following line in my local.properties:

MAPS_API_KEY="AIzaalskro0jlskdj2kr5jlksbjlksdjflkse0p"

where the AIza... is a valid API key.

With this configuration, when you run your app you will get an authentication error, because the whole string including the double quotes is $MAPS_API_KEY.

Please consider to remove the double quotes in local.defaults.properties because it may mislead people.

Creating problems with Github Actions

When I use this plugin in my app and if I have Github Action setup, it ends up with following error:

* What went wrong:
A problem occurred configuring project ':app'.
> java.io.FileNotFoundException: The file '/home/runner/work/AppName/AppName/local.properties' could not be found

Incorrect plugin module name in the documentation on Maps Platform site

While following the documentation to use Secrets Gradle Plugin for Android in Maps platform site.
https://developers.google.com/maps/documentation/android-sdk/config#step_3_add_your_api_key_to_the_project

I found this to be the plugin module name (project-level build.gradle file variant)

plugins {
    // ...
    id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' version '2.0.1' apply false
}

However this is only the Gradle plugin group name, It's missing the library name
Here is the correct variant

plugins {
    // ...
    id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin' version '2.0.1' apply false
}

Variant specific properties file

Add support for variant specific properties. Right now, the plugin supports buildType OR flavor specific properties.

For example, let's say we have build types release and debug and we have flavors paid and free. Accept paidRelease.properties, paidDebug.properties , freeRelease.properties and freeDebugProperties instead of only release.properties, debug.properties, free.properties and paid.properties.

How to get the values in gradle?

Hi. great plugin here! I saw you added examples on how to retrieve the value in manifest value or in Java/Kotln codes.
But how bout in gradle files? Below is to how to get it from properties files

buildscript {
    ...
    repositories {
        jcenter()
        google()
        maven {
            def credentialPropertiesFile = rootProject.file("credential.properties")
            def credentialProperties = new Properties()
            credentialProperties.load(new FileInputStream(credentialPropertiesFile))
            credentials {
                username credentialProperties['user']
                password credentialProperties['password']
            }
            url 'http:url'
        }
    }
}

Merged Manifest error

So I followed this guide from the Maps SDK to add the API key to the app.
Now in Android Studio the Merged Manifest view no longer works which in turn also breaks the MissingPermission lint.

Android Studio shows this error when viewing the Merged Manifest:

Merging Errors: Error: Attribute meta-data#com.google.android.geo.API_KEY@value at AndroidManifest.xml:57:13-44 requires a placeholder substitution but no value for <MAPS_API_KEY> is provided. redacted.app main manifest (this file), line 56 Error: Validation failed, exiting redacted.app main manifest (this file)

MissingPermission lint warning, despite the permissions being in AndroidManifest.xml:

Missing permissions required by FusedLocationProviderClient.requestLocationUpdates: android.permission.ACCESS_COARSE_LOCATION or android.permission.ACCESS_FINE_LOCATION

A workaround would be to manually add manifestPlaceholders = [MAPS_API_KEY: ""] to the app build.gradle, but this feels wrong.
Is there a better way to avoid this, or is this more an error by Android Studio or the Android Gradle plugin?

BuildConfig not accessible in kotlin files

Hi, I have my gradle and local.properties files like this:

image
image
image

When I try to access BuildConfig.apiKey in my kotlin files, I get an Unresolved reference, but in the Android Manifest it works:

image

Please, what am I doing wrong?

How do I access secrets in build.gradle?

I need to access secrets in my app build.gradle, but I'm not seeing any documentation on how to do it. Specifically, I want to default my signing keystore to use an environment variable if present for github actions, but then fallback to using a local secrets file. It seems like this would probably be supported, is there a way to do this?

I'm trying this, but this doesn't work:

    signingConfigs {
        release {
            storePassword System.getenv("MY_RELEASE_KEYSTORE_PASSWORD") ?: project.findProperty('MyReleaseKeystorePassword')
        }
    }

Merging in environment variables over top of properties

New feature request I've noticed. Instead of a defaults file with safe values for CI/CD systems, I would much more often like to be able to inject secrets such as API Keys through environment variables.

Parsing the environment for prefixed environment variables (something like SECRETS_NAME_OF_SECRET) to merge over top of the defaults and merging all of the mappings sensibly before injecting would be insanely helpful for CI/CD systems that also handle deployment to beta testing and the like.

Add support for a default properties file

Problem

If the properties file containing secrets is missing a key, building the Android project could result in build failures due to code referring to necessary keys. So if the manifest file expects the key "API_KEY" but the secrets file does not contain that value, then the build will fail resulting in a "...requires a placeholder substitution but no value for <API_KEY> is provided." A similar error would be encountered for BuildConfig key references.

While this behavior can be acceptable (i.e. it's left up to consumers to handle this failure), there are use cases, such as with CI, where the build should not fail from this requirement and instead pass but perhaps with placeholder values for the keys.

Solution

Provide an optional configuration wherein a default properties file can be set. This default properties file could serve as a template of all the keys needed for the app to function correctly.

API:

secrets {
    // A properties file checked in version control that contains key/value defaults
    defaultPropertiesFile 'secrets.defaults.properties'
}

Example contents of secrets.defaults.properties:

apiKey=""

"defaultPropertiesFileName" should be mentioned in examle usage or installation

Hello,

I've been struggling to use this plugin in my GitHub actions workflow. Locally everything worked fine. On GitHub action I've got known error:

Attribute meta-data#com.google.android.geo.API_KEY@value at AndroidManifest.xml:32:13-44 requires a placeholder substitution but no value for <GOOGLE_MAPS_KEY> is provided.

To mention in my workflow I've just passed local.properties content from GitHub action secret storage in my workflow.yml like that:

- name: Provide Local properties
  env:
    LOCAL_PROP: ${{ secrets.LOCAL_PROP }}
  run: echo $LOCAL_PROP > ./android/local.properties

When I explicitly added the default option in my app/build.gradle:

secrets {
    defaultPropertiesFileName = 'local.properties'
}

It finally started working! ๐Ÿ˜Ž
To conclude I think it should be mentioned somewhere in the documentation that the defaultPropertiesFileName param might be required in some applications.

Unable to read values

During build this error is thrown:
Attribute meta-data#com.google.android.geo.API_KEY@value at AndroidManifest.xml:17:9-35 requires a placeholder substitution but no value for <GMP_KEY> is provided.

If I add a sample placeholder in my default config the app seems to build fine but the keys are not read in manifest:

Build.gradle(app):

defaultConfig {
    applicationId "com.projID"
    minSdkVersion rootProject.ext.minSdkVersion
    targetSdkVersion rootProject.ext.targetSdkVersion
    versionCode 3
    versionName "0.1"
    multiDexEnabled true
    manifestPlaceholders=[GMP_KEY: "Google Maps", googleMapApiKey: ""]
}

Build.gradle(root):

ext {
    buildToolsVersion = "29.0.2"
    minSdkVersion = 16
    compileSdkVersion = 29
    targetSdkVersion = 29

    googlePlayServicesVersion = "17.0.0"
    androidMapsUtilsVersion="2.2.5"
}

I have tried manually adding the keys in manifest and that works fine.
I am running this with React-Native

The plugin is ignoring my custom file when specific the file with path.

As the document said we have to create a custom file at the root of the folder and it's working fine on my project,
Is it possible to move my custom file into another folder?

staging {
    secrets {
        propertiesFileName 'properties/staging.properties'
    }
}

The plugin is ignoring my custom file with the path and then somehow read from my release.properties instead.

Does anyone know how to read the configuration file from another folder?

Properties are not injected if the plugin is applied before the Android plugin

If the plugin is added before com.android.application it silently skips properties injection.
I believe it should fail the build in this case. Or, at least, docs should mention that the order is important.
It took me several hours to understand why the properties are not injected when after some refactoring I accidentally changed the order of plugins.

CI/CD system doesn't resolve environment variables

Using this plugin, I am able to easily keep my API keys locally and not upload them via git.

However, when using the Gitlab CI system to deliver application via runners, this plugin doesn't resolve the keys in environment variables defined in Gitlab (ORG_GRADLE_PROJECT_) and defaults to using the default variables in the specified file (local.defaults.properties for example).

The expected behaviour is:

  • Check for the given properties file (local.properties)
  • Check environment variables
  • Use the default properties file (local.defaults.properties)

Merging error + problem in adding API key to the project

I followed this guide still facing problem in adding API key to the project. I have successfully installed the secrects gradle plugin. But when i open this local.properties file it does not allow to make any changes. The contents of the file are not as mentioned in the guide.
local properties

Merging error in AndroidManifest.xml
manifest erroe

I'm stuck in step 4 of the process mentioned below.
add api key steps

Help please

Add strict mode feature

Add a configuration option for turning on/off strict mode which will error/warn if the provided properties file is not ignored by version control.

Multi-Module Gradle Support

Hi @arriolac,
First of all, great plugin! It helps me reduce some boilerplate I used to write for extracting keys stored in e.g., gradle.properties file.

But I have a use case where I want the generated keys are visible not limited to com.android.application module only, but com.android.library modules as well. Even better, I want my keys are generated in a certain module only, but I don't find such abilities in the current plugin version.

Btw, I've made a local workaround for this case. I'd be ready to submit my PR if my requirement is eligible enough treated as a "feature request". Thank you.

Getting error while Gradle Sync

I am using the latest version of plugin v1.2.0 and when I do Gradle sync I am getting the following error:

The value for property 'buildConfigFields' cannot be changed any further.

Key is visible in AndroidManifest after performing profiling on APK

Hi,

We are having below configuration in our project.
gradle = 4.2.1
Kotlin version = 1.5.0

We tried to use this plugin to hide the google map key. We followed below mentioned steps but still when we perform profile on APK, we can see key stored in the local properties as it is inside Manifest metadata. Kindly let us know if we are missing any step.

1. Added to root-level build.gradle
buildscript {
dependencies {
// ...
classpath "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin:1.3.0"
}
}

2. Added to app-level build.gradle to the plugin element
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin'

3. Sync gradle

4. Added to local.properties
MAPS_API_KEY=Az....

5. In Android Manifest.xml added

6. Created build in Release Mode

We we open the build in profile, we can see "${MAPS_API_KEY}" in AndroidManifest is replaced with the actual key. Kindly let us know if anything missing to hide the map key.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.