对于gitlab CI,我正在定义一些变量,如下所示:
variables:
PROD: project_package
STAGE: project_package_stage
PACKAGE_PATH: /opt/project/build/package
BUILD_PATH: /opt/project/build/package/bundle
CONTAINER_IMAGE: registry.example.com/project/package:e2e
Run Code Online (Sandbox Code Playgroud)
我想更动态地设置这些变量,因为主要只有两部分:project和package。其他所有内容都取决于这些值,这意味着我只需更改两个值即可获取所有其他变量。
所以我期望像
variables:
PROJECT: project
PACKAGE: package
PROD: $PROJECT_$PACKAGE
STAGE: $PROD_stage
PACKAGE_PATH: /opt/$PROJECT/build/$PACKAGE
BUILD_PATH: /opt/$PROJECT/build/$PACKAGE/bundle
CONTAINER_IMAGE: registry.example.com/$PROJECT/$PACKAGE:e2e
Run Code Online (Sandbox Code Playgroud)
但是看起来这样做的方式是错误的...
我不知道您的期望来自哪里,但检查, , '/' 是否没有特殊含义以及 YAML 中是否后跟空格是否没有$_:特殊含义很简单。gitlab 中可能有,但我强烈怀疑是否按照您期望的方式存在。
为了形式化您的期望,您假设任何以 a 开头$并以标量末尾 by_或 by结尾的键(来自同一映射)/都将“扩展”为该键的值。必须_是这样的终止符,否则$PROJECT_$PACKAGE将无法正确扩展。
现在考虑添加一个键值对:
BREAKING_TEST: $PACKAGE_PATH
Run Code Online (Sandbox Code Playgroud)
这应该扩展到:
BREAKING_TEST: /opt/project/build/package/bundle
Run Code Online (Sandbox Code Playgroud)
或者遵循您暗示的终止符规则_并扩展到:
BREAKING_TEST: project_PATH
Run Code Online (Sandbox Code Playgroud)
为了防止这种歧义程序,例如bash在要扩展的变量名称周围使用引号("$PROJECT"_PATHvs. $PROJECT_PATH),但更明智、更现代的解决方案是使用钳位开始和结束字符(例如{and }、$%and %、 )以及一些特殊规则来将夹紧字符用作普通文本。
所以这不会像你所说的那样起作用,因为你确实做错了。
预处理 YAML 文件并不难,可以使用 Python 等来完成(但要注意它{在 YAML 中具有特殊含义),可以在 jinja2 的帮助下完成:加载变量,然后展开原始文本使用变量直到无法再进行替换为止。
但这一切都始于明智地选择分隔符。另请记住,虽然您的“变量”似乎在 YAML 文本中排序,但当它们在程序中构造为 dict/hash/mapping 时,没有这样的保证。
例如,您可以使用<<和>>:
variables:
PROJECT: project
PACKAGE: package
PROD: <<PROJECT>>_<<PACKAGE>>
STAGE: <<PROD>>_stage
PACKAGE_PATH: /opt/<<PROJECT>>/build/<<PACKAGE>>
BUILD_PATH: /opt/<<PROJECT>>/build/<<PACKAGE>>/bundle
CONTAINER_IMAGE: registry.example.com/<<PROJECT>>/<<PACKAGE>>:e2
Run Code Online (Sandbox Code Playgroud)
通过以下程序(不处理转义<<以保持其正常含义),它会准确生成原始的扩展 YAML。
import sys
from ruamel import yaml
def expand(s, d):
max_recursion = 100
while '<<' in s:
res = ''
max_recursion -= 1
if max_recursion < 0:
raise NotImplementedError('max recursion exceeded')
for idx, chunk in enumerate(s.split('<<')):
if idx == 0:
res += chunk # first chunk is before <<, just append
continue
try:
var, rest = chunk.split('>>', 1)
except ValueError:
raise NotImplementedError('delimiters have to balance "{}"'.format(chunk))
if var not in d:
res += '<<' + chunk
else:
res += d[var] + rest
s = res
return s
with open('template.yaml') as fp:
yaml_str = fp.read()
variables = yaml.safe_load(yaml_str)['variables']
data = yaml.round_trip_load(expand(yaml_str, variables))
yaml.round_trip_dump(data, sys.stdout, indent=2)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5229 次 |
| 最近记录: |