如何用Awk在GitLab自动生成的YAML中为指定触发器添加规则行?
需求与问题背景
我有一个GitLab自动生成的YAML文件,包含多个触发器和任务,示例内容如下:
name-1-${VAR1}-${VAR2}: stage: trigger-1 trigger: project: test/test1 branch: master strategy: depend rules: - if: '$CI_PIPELINE_SOURCE == "pipeline"' release-build-name_1: extends: - .build-name_1 - .test-name_1 image: name variables: NAME_1: "build-name_1" ... # 表示更多键值对或其他结构 artifacts: expire_in: 1 week paths: - ${CI_PROJECT_DIR}/file_1.log ... rules: - if: $STAGE == "TEST1" - if: $STAGE == "TEST2" when: manual name-2-${VAR1}-${VAR2}: stage: trigger-2 rules: - if: '$CI_PIPELINE_SOURCE == "pipeline"' - if: $STAGE == "TEST1" trigger: project: test/test2 branch: dev strategy: depend name-1-${VAR3}-${VAR4}: ...
我的需求是:
- 匹配所有名称以
name-1-开头的触发器块 - 在该块的
rules:部分添加一行- if: $VALUE - 不清楚如何处理块之间的空行,之前设想的伪代码如下:
n=0 if /^name-1-*/ { ++n } elif /^\s*$/ { n=0 } elif n== 1 and / rules:/ { print " - if: $VALUE" }
可行的Awk实现方案
下面是能满足需求的Awk脚本,它会正确识别目标触发器块、处理空行,并在对应rules:下添加规则:
BEGIN { in_target_block = 0 in_rules_section = 0 indent = "" } # 匹配以name-1-开头的触发器块起始行 /^name-1-/ { in_target_block = 1 print $0 next } # 空行:退出当前目标块和rules段 /^\s*$/ { in_target_block = 0 in_rules_section = 0 print $0 next } # 在目标块内,匹配rules:行 in_target_block && /^\s*rules:/ { print $0 # 提取当前行的缩进,保持YAML格式一致 indent = substr($0, 1, length($0) - length("rules:")) # 插入新规则,缩进对齐原有格式 print indent " - if: $VALUE" in_rules_section = 1 next } # 在rules段内,遇到下一个同级键时退出rules段 in_target_block && in_rules_section && /^\s*[^ ]/ { in_rules_section = 0 print $0 next } # 其他情况直接输出 { print $0 }
脚本说明
- 状态标记:用
in_target_block标记是否处于name-1-开头的块内,in_rules_section标记是否处于该块的rules段中 - 空行处理:遇到空行直接重置所有状态,避免跨块误操作
- 缩进对齐:自动提取
rules:行的缩进,保证新增规则的格式和原有YAML一致,防止格式错误 - 规则段结束判断:当rules段内出现同级别的YAML键(缩进和rules行相同)时,自动退出rules段,避免在非rules区域插入内容
使用方式:将脚本保存为add-rule.awk,执行命令:
awk -f add-rule.awk your-gitlab-ci.yml > modified-ci.yml
内容的提问来源于stack exchange,提问作者Red Black
相关产品推荐
相关产品推荐

