[Gradle] Secure way of storing passwords
Problem
Using passwords in build.gradle file can be cumbersome. The question is, where to store passwords? Typing it directly in build.gralde, or gradle.properties is bad idea (especially when working with git - accidental commit of properties etc.). Fortunatelly, there is good OOTB (Out-of-the-box) solution in gradle, which helps us to solve that problem.
Gradle init script
Gradle offers initialization script mechanism. It is executed before build starts. There are few ways of include init script into our build:
- Specify init.gradle file anywhere in file system. Then, type in console:
gradle --init-script=/path/to/your/script/init.gradle -q someTask
- Specify init.gradle file in YOUR_HOME_DIR/.gradle. Init script will be loaded automatically when executing gradle tasks.
- Specify file ended with .gradle in GRADLE_HOME/.gradle. Init script will be loaded automatically when executing gradle tasks.
You are free to load any dependencies you need in your init sript. A typical way to do that is the following snippet:
import com.btcgroup.gradleplugin.utils.*
initscript {
repositories {
mavenCentral()
}
dependencies {
classpath group: 'com.btcgroup', name: 'gralde-plugin-utils', version: '1.1.+'
}
}
def list = Util.getProjects()
Example
As an example, we will create external properties loader. Properties contain passwords, so the best idea is to store it in secure place. For the purpose of this example, I will store my properties file in the same place, as init.gradle script, that’s: YOUR_HOME_DIR/.gradle.
init-settings.properties
archiva.url=http://localhost:8080/repository/myproject/
archiva.username=xxxxx
archiva.password=xxxxx
init.gradle
import java.util.Properties
import java.io.*
allprojects {
println "[INIT SCRIPT] Initializing script START..."
Properties props = loadExternalProps()
beforeEvaluate { project ->
if(props!=null) {
println "[INIT SCRIPT] Loading properties for project " + project.name
project.ext.externalProps = props
}
}
}
def loadExternalProps() {
String userGradleDir = System.getProperty("user.home") + "/.gradle/"
File file = new File(userGradleDir + "init-settings.properties")
if(!file.exists())
return null
Properties props = new Properties()
props.load(new FileInputStream(file))
return props
}
What’s happening there?
- First of all, we want to evaluate our logic to all projects builded at the time. That’s why we use
allprojects
clause. - Right after that, we use
beforeEvaluate
callback for specific project. Another option is to useafterEvaluate
callback, but in case of properties loading,beforeEvaluate
is the best choice. - Including our properties. We do it by adding
externalProperties
object toext
object ofproject
:project.ext.externalProps = props
How to use it in our build.gradle scripts?
It’s really simple, and refers to use externalProperies object inside build.gradle. Take a look at this example:
repositories {
mavenCentral()
}
dependencies {
}
...
task someSampleTask << {
println externalProps["archiva.username"] //Example of use
}