您可以使用 IntelliJ 原生导入器Eclipse Buildship 在 IDE 中打开示例。

此示例展示了如何将凭据传递给通常通过标准输入接受凭据的外部工具。

假设我们需要在执行某些操作之前登录到某个系统。这可能是某个外部系统,它要求身份验证才能允许我们上传一些工件。

此示例假设需要交互式登录的外部工具不支持任何形式的非交互式登录。实际上,许多工具提供了无需提示用户输入即可进行身份验证的选项。可以使用 args 属性将命令行参数传递给 Exec 任务。

为了演示这个概念,我们将使用一个提示用户输入用户名和密码的 bash 脚本模拟身份验证

login.sh
#!/bin/bash

echo Enter username:
read username
echo Enter password:
if [ -t 0 ] ; then # if connected to a terminal, do not echo the password input
    stty -echo
    read password
    stty echo
    echo
else
    read password
fi

if [ "$username" = "secret-user" ] && [ "$password" = "secret-password" ] ; then
    echo "Welcome, $username!"
else
    echo "Bad credentials!"
    exit 1
fi

它包含一个硬编码的用户名/密码对,可以成功登录。该脚本可以在没有 Gradle 的情况下执行 - 它将模拟一个需要交互式登录的工具。

Gradle 构建文件注册了两个任务 - 一个执行登录,另一个依赖于登录成功。

build.gradle.kts
val login = tasks.register<Exec>("login") {
    val loginProvider = providers.credentials(PasswordCredentials::class.java, "login")
    inputs.property("credentials", loginProvider)

    commandLine = listOf("sh", "login.sh")
    doFirst {
        val loginCredentials = loginProvider.get()
        standardInput = java.io.ByteArrayInputStream("${loginCredentials.username}\n${loginCredentials.password}".toByteArray())
    }
}

tasks.register("doAuthenticated") {
    dependsOn(login)
    doLast {
        println("Doing authenticated task")
    }
}
build.gradle
def login = tasks.register('login', Exec) {
    def loginProvider = providers.credentials(PasswordCredentials, 'login')
    inputs.property('credentials', loginProvider)

    commandLine = ['sh', 'login.sh']
    doFirst {
        def loginCredentials = loginProvider.get()
        standardInput = new ByteArrayInputStream("$loginCredentials.username\n$loginCredentials.password".getBytes())
    }
}

tasks.register('doAuthenticated') {
    dependsOn(login)
    doLast {
        println 'Doing authenticated task'
    }
}

login 任务声明了一个输入属性,并将其与凭据提供程序连接。凭据提供程序将从 项目属性 中获取凭据片段。

凭据可以通过多种方式传递给任务

  • 通过命令行属性

$ ./gradlew doAuthenticated -PloginUsername=secret-user -PloginPassword=secret-password
  • 通过环境变量

$ ORG_GRADLE_PROJECT_loginUsername=secret-user ORG_GRADLE_PROJECT_loginPassword=secret-password ./gradlew doAuthenticated
  • 通过在 gradle.properties 文件中设置属性

loginUsername=secret-user
loginPassword=secret-password

并运行

$ ./gradlew doAuthenticated

这样,敏感数据就可以保存在项目源代码之外 - gradle.properties 可以位于用户的 ~/.gradle 目录中。这样,这些值也不会在任何地方被回显。有关使用 Gradle 属性的更多信息,请参阅 Gradle 属性用户手册章节

使用正确凭据的输出将是

> Task :login
Enter userame:
Enter password:
Welcome, secret-user!

> Task :doAuthenticated
doAuthenticated

BUILD SUCCESSFUL in 496ms
2 actionable tasks: 2 executed