Build Settings - kgleong/software-engineering GitHub Wiki

app/build.gradle

A typical gradle build file:

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"

    defaultConfig {
        applicationId "com.example.sampleapp"
        minSdkVersion 16
        targetSdkVersion 22

        // See sections below for method definitions.
        versionCode generateVersionCode()
        versionName generateVersionName()
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
  • A few attributes worth mentioning:
    • versionCode - internal version number used by the system to determine recency of an application. Type: int. See versionCode description for full details.
    • versionName - version number displayed to users. Type: String. See versionName description for full details.

Generating Version Code

def generateVersionCode() {
    try {
        def output = new ByteArrayOutputStream()

        exec {
            // Count commits in current branch.
            commandLine "git", "rev-list", "HEAD", "--count"
            standardOutput = output
        }

        return output.toString().trim() as int
    }
    catch(exception) {
        return -1
    }
}

Generating Version Name

One approach to version naming is to use the latest tag from the repository.

The git command to retrieve the nearest tag: git describe --tags --abbrev=0.

def generateVersionName() {
    try {
        def output = new ByteArrayOutputStream()

        exec {
            // Get latest tag name.
            commandLine "git", "describe", "--tags", "--abbrev=0"
            standardOutput = output
        }

        return output.toString().trim()
    }
    catch(exception) {
        return null
    }
}
  • Creating a tag:
    • git tag -a 1.0 -m 1.0: creates a tag with name (-a) and message (-m).
    • git push --tags: pushes all local tags to remote repository.

Build a signed release version using Gradle

// Project properties
def projectProperties = new Properties()
projectProperties.load(new FileInputStream("gradle.properties"))

// App credential properties
ext.credentialProperties = new Properties()
credentialProperties.load(
        new FileInputStream(projectProperties['appCredentialsFilePath']))

// Release credentials properties.  E.g., keystore credentials.
def releaseCredentialsFilePath = projectProperties['releaseCredentialsFilePath']

if(file(releaseCredentialsFilePath).exists()) {
    // Load keystore credentials.
    def keystoreProperties = new Properties()
    keystoreProperties.load(new FileInputStream(releaseCredentialsFilePath))

    android {
        signingConfigs {
            release {
                storeFile file(keystoreProperties['keystoreFile'])
                storePassword keystoreProperties['keystorePassword']
                keyAlias keystoreProperties['keyAlias']
                keyPassword keystoreProperties['keyPassword']
            }
        }

        buildTypes {
            release {
                signingConfig signingConfigs.release
            }
        }
    }
}

Sample gradle.properties file

# Credentials Property File Path
# ==============================
# Credentials for this app are stored locally to prevent accidental commit of credentials to the repository.
#
# The credential property file should contain the following key-value pairs:
# parseAppId=aU1233455d3898UUdweibe39
# parseClientKey=23kd3i3323353312k89
appCredentialsFilePath=/Users/leong/Credentials/makorati_credentials.properties

# Release Credentials Property File Path
# ======================================
# Credentials for the keystore used to sign the release version of the app.
#
# The release credentials file should contain the following key-value pairs:
# keystoreFile=/Users/johndoe/credentials/sampleapp-release.keystore
# keystorePassword=abc123
# keyAlias=myKeyAlias
# keyPassword=abc123
releaseCredentialsFilePath=/Users/leong/Credentials/makorati_release_credentials.properties

Build release version via command line

  1. Navigate to project root.
  2. Run ./gradlew assembleRelease.
  3. Verify apk if necessary:
    • Verify version code and name:
      • aapt dump badging <release apk file>
    • Verify the app has been signed:
      • jarsigner -verify -verbose my_application.apk
    • Verify alignment:
      • zipalign -c -v 4 <relase apk file>

Importing credentials from an external file

It's preferred to store sensitive credential information outside of the project root, since the project root is usually commited to a source control repository.

// Project properties
def projectProperties = new Properties()
projectProperties.load(new FileInputStream("gradle.properties"))

// App credential properties
ext.credentialProperties = new Properties()
credentialProperties.load(
        new FileInputStream(projectProperties['appCredentialsFilePath']))

android {
    buildTypes {
        release {
            // Strings must included escaped double quotes.
            def parseClientKey ="\"${credentialProperties['someClientKey']}\""

            buildConfigField 'String', 'SOME_CLIENT_KEY', someClientKey
        }
    }
}