2017-05-22 11 views
3

Gitlab CI:設定して動的変数私はこのようないくつかの変数を定義しています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 

は、私は主に2つの部分のみが存在するとして、動的にもう少し、これらの変数を設定したいと思います:projectおよびpackage。他のすべてはそれらの値に依存します。つまり、他のすべての変数を取得するために2つの値だけを変更する必要があります。

だから私は

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 

のようなものを期待する。しかし、それはこれを行う方法が間違っている、ように見える...

答えて

1

あなたの期待がどこから来るか、私は知りませんが、それはありますYAMLのtrivial to check there is no special meaning for $, _, '/' nor : if not followed by a space。 gitlabにはあるかもしれないが、あなたが期待している方法があることを強く疑う。あなたの期待を形式化するために

、あなたは(同じマッピングから)任意のキー$が先行し、_または/により、スカラーの終わりで終了し、そのキーの値を「拡大」されようとしていることを前提としています。 _はそのようなターミネータでなければならず、そうでなければ$PROJECT_$PACKAGEは正しく拡張されません。

は今、キーと値のペアを追加することを検討:

BREAKING_TEST: /opt/project/build/package/bundle 

か、_はターミネータであるだけに展開することを暗示ルールに従ってください:

BREAKING_TEST: $PACKAGE_PATH 

これはに拡大することになっています。

BREAKING_TEST: project_PATH 

bashのようなこのようなあいまい性プログラムを防止するには("$PROJECT"_PATH$PROJECT_PATH)の変数名を引用符で囲みますが、より初期のやり方では、締め付けの開始と終了の文字を使用することです。 {および},$%および%)、クランプ文字を通常のテキストとして使用する特別な規則があります。

本当に間違ったことを言ったように、これはうまくいかないでしょう。

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 

、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) 
関連する問題