从Azure管道Maven构建上的单元测试访问Secure变量

时间:2019-10-23 07:55:54

标签: maven unit-testing azure-devops environment-variables azure-pipelines

我正在尝试使用maven为其中一个Java应用程序创建一个Azure DevOps管道,在单元测试中,我有2个秘密,需要从环境变量访问值。

String key = System.getenv().get("MY_KEY");
String secret = System.getenv().get("MY_SECRET");

我在浏览器的管道变量下添加了2个值,并将它们标记为“保持此值保密”,以便将值保密。

enter image description here

在管道中,我添加了必需的变量,并将值替换为配置的变量。

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) ./

运行构建过程,该过程将在执行单元测试时读取机密。

2 个答案:

答案 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代理的说明。

希望以上内容对您有所帮助!