我正在尝试使用maven为其中一个Java应用程序创建一个Azure DevOps管道,在单元测试中,我有2个秘密,需要从环境变量访问值。
String key = System.getenv().get("MY_KEY");
String secret = System.getenv().get("MY_SECRET");
我在浏览器的管道变量下添加了2个值,并将它们标记为“保持此值保密”,以便将值保密。
在管道中,我添加了必需的变量,并将值替换为配置的变量。
variables:
MY_KEY: $(MY_KEY_VAL)
MY_SECRET: $(MY_SECRET_VAL)
但是,当我运行构建管道时,由于'key'和'secret'值都为空,因此单元测试失败。
我该如何解决?我在配置上做错了吗?
更新
如下面的Ben所述,无法在托管代理上设置环境变量。为了在构建管道中运行所有单元测试并仍然保持密钥和机密的安全,我修改了单元测试以从项目根目录中的文件读取密钥和机密。与其将包含密钥和机密的文件添加到git repo中,而是将其作为安全文件添加到管道库中,并被授予通过管道访问的权限。
在管道上,我可以使用“ DownloadSecureFile”任务下载安全文件。
- task: DownloadSecureFile@1
displayName: Download API secrets
name: configfile
inputs:
secureFile: 'service_api_keys'
使用bash将文件移动到项目根目录。
- bash: mv $(configfile.secureFilePath) ./
运行构建过程,该过程将在执行单元测试时读取机密。
答案 0 :(得分:1)
您需要替换Java文件中的值。您已经在上面详细介绍了变量替换,即
variables:
MY_KEY: $(MY_KEY_VAL)
MY_SECRET: $(MY_SECRET_VAL)
将仅替换管道YAML文件中的值。
例如,您可以使用“ Replace Tokens”任务将变量替换为Java文件中的变量
- task: replacetokens@3
inputs:
targetFiles: "yourJavaFile.java"
encoding: "auto"
writeBOM: true
verbosity: "detailed"
actionOnMissing: "warn"
keepToken: false
tokenPrefix: "#{"
tokenSuffix: "}#"
displayName: Perform variable substitution in java file
在您的Java文件中,您将要替换的变量写为例如
String key = System.getenv().get("#{MY_KEY}#");
String secret = System.getenv().get("#{MY_SECRET}#");
答案 1 :(得分:1)
System.getenv()读取运行Java代码的计算机的系统环境变量。而且在管道中定义的变量不在代理范围内,而在机器范围内。也许这就是为什么单元测试无法获取变量的原因。
可能没有直接的方法可以实现这一目标。正如本·史密斯(Ben Smith)所述,您可以重构代码以从json文件中获取密钥/秘密,并添加一个Set Json Property
任务,以使用maven任务运行单元测试之前在管道中定义的变量更新json文件。检查here以获得此任务的详细用法。
作为另一种解决方法,您可以在自托管的Linux代理上运行管道,并尝试添加bash脚本任务来设置linux代理的环境变量(我测试并发现设置的环境变量不适用于共享托管代理)。检查here,了解如何为Linux设置环境变量。
查看here中有关创建自托管linux代理的说明。
希望以上内容对您有所帮助!