我可以在 Azure Pipelines 中对变量进行子串吗?

nik*_*itz 9 azure-devops azure-pipelines azure-pipelines-yaml

我正在寻找一种在我的azure-pipelines.yml文件中定义变量的方法,我可以在其中对'Build.SourceVersion'-> 仅使用前 7 个字符进行子串。

文档中似乎没有可以执行此类字符串操作的内置函数。有什么我想念的吗?

我的另一种方法是使用 bash 任务并覆盖那里的变量,但找到可以做到这一点的内置方法将是更好的解决方案。

Leo*_*SFT 7

我的另一种方法是使用 bash 任务并覆盖那里的变量,但找到可以做到这一点的内置方法将是更好的解决方案。

我同意卢卡斯的观点。在 Azure DevOps 中没有这样的内置任务来获取 $(Build.SourceVersion) 的前 7 个字符。

我们可以使用命令行/powershell 任务将长 sha 拆分为短 sha:

echo $(Build.SourceVersion)

set TestVar=$(Build.SourceVersion)

set MyCustomVar=%TestVar:~0,7%

echo %MyCustomVar%

echo ##vso[task.setvariable variable=ShortSourceVersion]%MyCustomVar%
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我们可以获得 的简短版本Build.SourceVersion并将其设置为环境变量。

然后我们可以将这个命令行任务设置为一个任务组:

在此处输入图片说明

所以,我们可以使用这个任务来ShortSourceVersion直接设置。

希望这可以帮助。


Mar*_*ský 5

我知道我参加这个聚会有点晚了,但对于任何来到这里并希望避免使用 Bash、PowerShell 和类似内容的人来说,我已经设法只使用 Azure Pipelines 表达式来创建一个子字符串。

(我肯定会因为写这段代码而直接下地狱)

不幸的是,由于某种原因我们无法对字符串进行索引,因此@dsschneidermann 的答案不起作用。但我们可以使用该split函数来解决这个问题。

这肯定比使用脚本更复杂,但另一方面,它在编译时完全运行

  1. 使用 ,在原始字符串中的每个字符后面附加一些已知字符replace。即,附加_,这样就abc变成了a_b_c_
  2. 使用附加字符 - 分割字符串split('a_b_c_', '_')。该split函数返回一个可索引数组。
  3. 使用数组索引来组成结果

除了不可读之外,这样做的缺点是您必须指定可能属于输入值一部分的所有字符。如果不这样做可能会导致意外行为。但对于 git hash,指定整个字母表和数字就足够了。

结果是这样的:

- name: Build.SourceVersion.PreparedForSplit
  value: ${{ replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(variables['Build.SourceVersion'], 'a', 'a_'), 'b', 'b_'), 'c', 'c_'), 'd', 'd_'), 'e', 'e_'), 'f', 'f_'), 'g', 'g_'), 'h', 'h_'), 'i', 'i_'), 'j', 'j_'), 'k', 'k_'), 'l', 'l_'), 'm', 'm_'), 'n', 'n_'), 'o', 'o_'), 'p', 'p_'), 'q', 'q_'), 'r', 'r_'), 's', 's_'), 't', 't_'), 'u', 'u_'), 'v', 'v_'), 'w', 'w_'), 'x', 'x_'), 'y', 'y_'), 'z', 'z_'), '0', '0_'), '1', '1_'), '2', '2_'), '3', '3_'), '4', '4_'), '5', '5_'), '6', '6_'), '7', '7_'), '8', '8_'), '9', '9_') }}
  readonly: true
- name: Build.SourceVersion.Short
  value: ${{ split(variables['Build.SourceVersion.PreparedForSplit'], '_')[0] }}${{ split(variables['Build.SourceVersion.PreparedForSplit'], '_')[1] }}${{ split(variables['Build.SourceVersion.PreparedForSplit'], '_')[2] }}${{ split(variables['Build.SourceVersion.PreparedForSplit'], '_')[3] }}${{ split(variables['Build.SourceVersion.PreparedForSplit'], '_')[4] }}${{ split(variables['Build.SourceVersion.PreparedForSplit'], '_')[5] }}${{ split(variables['Build.SourceVersion.PreparedForSplit'], '_')[6] }}
  readonly: true
Run Code Online (Sandbox Code Playgroud)

您可以将它们放入变量模板中,然后,在您需要使用它们的任何地方,只需包含此模板即可,这就是一行代码。因此,您最终会得到一个难以阅读的代码文件,但还有其他简单的代码文件,并且所有内容都在模板的编译时进行处理。


我还创建了一个 PowerShell 脚本来生成中间变量:
# Input variable name
$VariableName = 'Build.SourceVersion'
# Known characters - should be every character that could appear in the input
$Chars = 'abcdefghijklmnopqrstuvwxyz0123456789'
# Character to be appended after every character in the input string
$IntermediateChar = '_'

$output = "variables['$VariableName']"

foreach ($Char in [char[]]$Chars) {
    $output = "replace($output, '$Char', '$Char$IntermediateChar')"
}

Write-Host $output
Run Code Online (Sandbox Code Playgroud)