Injecting Jenkins Credentials into a Build Job

From NovaOrdis Knowledge Base
Jump to navigation Jump to search

External

Internal

Overview

This article describes the procedure to declare credentials, in this case an external repository username and password, in a Jenkins credential store and then expose them to a build job, in this case a Gradle-driven build.

Pre-Requisites

Procedure

Define the Credential

Credentials -> System -> Global credentials (unrestricted) -> Add Credential

Username with password

Scope: Global. The Global scope is required if the credential must be exposed to the build jobs.

Username:

Password:

ID: same as username.

OK.

Upon creation, the credential should be reported in "Global credentials (unrestricted)" section.

Inject the Credential in the Build Job

Jenkins -> the build job in question -> Configure -> Build Environment section -> Check "Use secret text(s) or file(s).

The "Bindings" section will appear.

Add -> Username and password (separated)

Username Variable. This is the name of the environment variable to be set to the username during the build. Example:

CI_USERNAME

Password Variable. This is the name of an environment variable to be set to the password during the build.

Credentials -> Specific credentials -> the credential set up at the previous step.

DO NOT click on the Add button at the right - this will add a new credential.

Save.

Use the Credential in the Build Script

Start the script with:

set +x

to prevent commands from being echoed in the logs, in case sensitive credentials are specified in commands.

The username and password will be available as the environment variables declared in the previous section.

Inject Credentials into a Gradle Build

Use the following bash function or similar logic:

#
# Reads credentials exposed by Jenkins Credentials Binding plugin in the build environment and writes them into
# a Gradle properties file, translating names as appropriate. Arguments, and behavior on missing or invalid
# arguments are documented below.
#
# Usage example:
#
# inject-jenkins-credentials ~/.gradle/gradle.properties "CI_USERNAME" "ciUsername" "CI_PASSWORD" "ciPassword"
#
function inject-jenkins-credentials-binding-plugin() {

    # The gradle.properties file to update. If it does not exist, it will be created. If it exists, it will be updated.
    # No assumptions are made on naming convention or location, any file passed here is assumed a Gradle properties
    # file. If not value is provided, the function will display an error message at stderr and return a non-zero value.

    local gradle_properties_file=$1

    #
    # The name of the username environment variable set by Jenkins Credentials Binding plugin. The value is configured
    # in Jenkins in Build Job -> Configure -> Build Environment -> (Use secret text(s) or file(s)) -> Bindings ->
    # Username Variable. If the argument is not provided, or if no such environment variable exists, the function
    # will display an error message at stderr and return a non-zero value.
    #
    local username_env_var_name=$2

    #
    # The name of the Gradle property expected to carry the username
    #
    local gradle_username_property_name=$3

    #
    # The name of the password environment variable set by Jenkins Credentials Binding plugin. The value is configured
    # in Jenkins in Build Job -> Configure -> Build Environment -> (Use secret text(s) or file(s)) -> Bindings ->
    # Password Variable.
    #
    local password_env_var_name=$4

    #
    # The name of the Gradle property expected to carry the password
    #
    local gradle_password_property_name=$5

    [ -z "${gradle_properties_file}" ] && { echo "no Gradle properties file provided" 1>&2; return 1; }
    [ -z "${username_env_var_name}" ] && { echo "no username environment variable name provided" 1>&2; return 1; }
    [ -z "${gradle_username_property_name}" ] && { echo "no Gradle username property name provided" 1>&2; return 1; }
    [ -z "${password_env_var_name}" ] && { echo "no password environment variable name provided" 1>&2; return 1; }
    [ -z "${gradle_password_property_name}" ] && { echo "no Gradle password property name provided" 1>&2; return 1; }

    [ -z "${!username_env_var_name}" ] && { echo "environment variable '${username_env_var_name}' not set in environment" 1>&2; return 1; }
    [ -z "${!password_env_var_name}" ] && { echo "environment variable '${password_env_var_name}' not set in environment" 1>&2; return 1; }

    [ -f ${gradle_properties_file} ] || touch ${gradle_properties_file}

    local username=${!username_env_var_name}
    local password=${!password_env_var_name}

    if grep -q "^${gradle_username_property_name} *=" ${gradle_properties_file} >/dev/null; then
        # replace
        sed -i '' -e "s/^${gradle_username_property_name} *=.*$/${gradle_username_property_name}=${username}/" ${gradle_properties_file}
    else
        # append
        echo "${gradle_username_property_name}=${username}" >> ${gradle_properties_file}
    fi

    if grep -q "^${gradle_password_property_name} *=" ${gradle_properties_file} >/dev/null; then
        # replace
        sed -i '' -e "s/^${gradle_password_property_name} *=.*$/${gradle_password_property_name}=${password}/" ${gradle_properties_file}
    else
        # append
        echo "${gradle_password_property_name}=${password}" >> ${gradle_properties_file}
    fi
}