Многострочная строка YAML для GitLab CI (.gitlab-ci.yml)

86

Я пытаюсь написать gitlab-ci.ymlфайл, в котором для команды используется многострочная строка. Однако похоже, что он не анализируется. Я пробовал и - |и - >с одинаковыми результатами.

stages:
  - mystage

Build:
  stage: mystage
  script:
    - |
        echo -e "
            echo 'hi';
            echo 'bye';
        "

Когда он пытается запустить, он показывает только echo -e 'запускаемый скрипт, а не всю многострочную строку. Это вызывает у меня проблемы.

Каков правильный синтаксис, чтобы написать что-то подобное?

саманиме
источник
Для этого есть проблема: gitlab.com/gitlab-org/gitlab-ci-multi-runner/issues/166 Мне не ясно, в чем проблема, поскольку ваш код должен быть эквивалентен (достаточно) YAML предлагаемым там решениям. . Вы можете попробовать добавить \к своим строкам, но я не могу сказать, сработает это или нет.
Jordan Running

Ответы:

37

TL; DR; Вы хотите использовать многострочный скаляр YAML (для удобства чтения), который загружается как однострочная строка, которую Gitlab-CI может выдать как команду. Для этого используйте простой (без кавычек) скаляр в YAML, который распределен по нескольким строкам:

script:
- echo -e 
   "echo 'hi';
    echo 'bye';"

Имейте в виду, что YAML налагает некоторые ограничения на такие скаляры. Что вам определенно нужно знать, так это то, что каждая следующая строка имеет отступ, по крайней мере, на одну позицию больше, чем echo -e(который имеет отступ на две позиции относительно своего узла коллекции, который вообще не имеет отступа), и что каждая новая строка заменяется пробелом при загрузке (поэтому вам нужно немного позаботиться о том, где разместить новые строки).


В вашем сообщении есть несколько заблуждений, из-за которых вы задаете неправильный вопрос.

Многострочной строки YAML не существует. . В YAML есть скаляры, и некоторые из этих скаляров могут быть загружены программой как строки, а некоторые другие будут загружены как целые числа, числа с плавающей запятой и т. Д.

Вы, очевидно, заинтересованы в скалярных узлах, которые загружаются в виде строки, поскольку эту строку можно затем интерпретировать как командную строку. Но вы не хотите иметь многострочную командную строку (т.е. со встроенными символами новой строки), поскольку многострочные сценарии не поддерживаются в Gitlab CI (как указано в @Jordan).

Для удобства чтения вы хотите использовать стандартную возможность YAML для загрузки многострочных скаляров в виде однострочной строки.

Если вас не волнует удобочитаемость, вы можете использовать:

- echo -e "\n    echo 'hi';\n    echo 'bye';\n"

и поскольку ваш скаляр не цитируется (т.е. начинается с echo ), вам не нужно делать ничего особенного в YAML для обратной косой черты или кавычек.

Результат скрипта тот же (вывести пустую строку, вывести echo 'hi'; строку с отступом в четыре пробела, напечатать echo 'bye';строку с отступом в четыре пробела).

Если вы хотите использовать многострочный ввод для удобочитаемости, который загружается как одна строка, по существу есть два варианта: использовать многострочный скаляр плоскости или использовать скаляр со складками в вашем YAML.

многострочный простой скаляр

Обычный означает, что скаляр не заключен в кавычки, и, как и в случае любой многострочной вещи в YAML, многострочный означает, что следующие строки должны иметь соответствующий отступ, в данном случае дальше, чем исходная строка.

script:
- echo -e 
   "echo 'hi';
    echo 'bye';"

новые строки заменяются пробелами, поэтому не делайте этого:

script:
- echo -e 
   "echo 'hi';
    echo '
   bye';"

так как вы получите видимое пространство перед bye .

Существуют некоторые ограничения, например, вы не можете иметь двоеточие, за которым следует пробел внутри такого скаляра (что сделает его похожим на пару ключ-значение).

Нет необходимости экранировать обратную косую черту в простых скалярах, так как вы не можете экранировать символы в простом скаляре, но, конечно, вы можете включить обратную косую черту, которая окажется в строке, загруженной из YAML, и может иметь значение для выполняемой команды из этой строки.

свернутый скаляр

Свернутый скаляр похож на простой скаляр в том, что все (отдельные) символы новой строки заменяются пробелом во время загрузки:

script:
- >
  echo -e 
  "echo 'hi';
  echo 'bye';"

Вам необходимо отступить от фактической информации о команде не меньше, чем на свернутом скалярном индикаторе (> ).

В отличие от простых скаляров, такие вещи как не :имеют особого значения. Поэтому, если простые скаляры терпят неудачу из-за ошибки YAML, подобные скаляры со свернутой структурой, скорее всего, этого не сделают.

Антон
источник
Я хочу написать его многострочным для наглядности и ремонтопригодности. Хотя мой пример тривиален, настоящие сценарии явно не так.
samanime 08
Я могу понять, что. Можно ли предварительно обработать ваш читаемый файл YAML до того, как он будет обработан GitLab CI?
Anthon
Я думал об этом. Это дополнительный шаг и немного усложнение, но оно того стоит.
samanime 08
Я добавил возможное решение.
Anthon
3
О, парень. Хотя этот ответ технически верен, он смехотворно многословен до нечитаемости. Каждый , кто не писать парсер YAML , вероятно , просто хочет PotatoFarmer «ы высоко upvoted и много terser ответа , вместо этого.
Сесил Карри
115

Я пришел сюда заранее, ожидая, что это будет проблемой, но следующая "многострочная" команда для удобства чтения у меня работает:

Gitlab Runner: Shell Runner версия 1.11.0 / версия Gitlab : 8.17.2

myjob:
stage: deploy
script:
  # Single line command
  - az component update --add sql

  # Multi-line command
  - az sql server create -n ${variable} -g ${variable} -l ${variable}
    --administrator-login ${variable} --administrator-login-password ${variable}
КартофельФермер
источник
2
В чем тут фокус? Вы сделали отступ для второй строки на том же уровне, что и для первой?
Виктор Граци
6
@ victor-grazi Насколько я понимаю: в обычном YAML (простой скаляр потока) \nescape-символы (например, новая строка) ничего не делают, а начальные пробелы игнорируются - похоже, Gitlab YAML анализирует блоки скрипта таким образом. Об отступе: в спецификации YAML сказано, In YAML block styles, structure is determined by indentationи поэтому вторая строка имеет отступ столько, сколько требуется для спецификации YAML (один пробел относительно родительского отступа), и еще один для удобочитаемости (что технически излишне, но красивее).
PotatoFarmer
Работает как шарм. Также работает со всеми параметрами в новой строке
bodolsog
26

Вы можете использовать любые многострочные скрипты / команды через yaml literal_block и функцию привязки. Пример:

.build: &build |
    echo -e "\n$hl🛠 Building $green$build_path/$build_assets_dir/*.js $nl\n"
    echo -e "javascript-obfuscator $build_path/$build_assets_dir/*.js"
[...]

build:master: 
  stage: build
  script:
    - *rsync
    - *build
[...]
Бенни К.
источник
Спасибо за то, что поделились - эта более продвинутая функция будет особенно полезна для удобства чтения задания / возможности повторно использовать фрагменты кода в рецепте.
PotatoFarmer
5
Это отличный пример, но он будет более ясным, если вы определите .rsync
Виктор Граци
13

Команда создания конфигурации wp была довольно привередливой ... из .gitlab-ci ...

build:
  stage: build
  script:
    - echo "Building the app"
    - |
        wp config create --dbname=$vardb --dbhost=$varhost --dbuser=$varusr --dbpass=$varpas --extra-php <<PHP
            define( 'WP_DEBUG', false );
            define( 'FS_METHOD', 'direct' );
            define( 'WP_POST_REVISIONS', 5 );
            define( 'AUTOSAVE_INTERVAL', 600 );
        PHP
    - scp ./wp-config.php continued...
  allow_failure: true
мал
источник
4

Это работает для меня в Travis CI

before_install:
  - set -e
  - |
    echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
    <settings xmlns=\"http://maven.apache.org/SETTINGS/1.0.0\"
              xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
              xsi:schemaLocation=\"http://maven.apache.org/SETTINGS/1.0.0
                                   http://maven.apache.org/xsd/settings-1.0.0.xsd\">
      <servers>
        <server>
          <id>github</id>
          <username>${GITHUB_USERNAME}</username>
          <password>${GITHUB_PASSWORD}</password>
        </server>
      </servers>
    </settings>
    " >  ${HOME}/.m2/settings.xml

Здесь также будут интерполированы две переменные env ( ${GITHUB_USERNAME}и ${GITHUB_PASSWORD})

Максим Костромин
источник
0

Этот формат будет работать. используйте простой (без кавычек) скаляр в YAML. Например, скрипт, используемый для инициализации бэкэнда terraform.

  before_script:
    - cd ${TF_ROOT}
    - terraform init -backend-config="address=${GITLAB_TF_ADDRESS}"
      -backend-config="lock_address=${GITLAB_TF_ADDRESS}/lock"
      -backend-config="unlock_address=${GITLAB_TF_ADDRESS}/lock"
      -backend-config="username=${GITLAB_USER_LOGIN}" -backend-config="password=${GITLAB_ACCESS_TOKEN}"
      -backend-config="lock_method=POST" -backend-config="unlock_method=DELETE"
      -backend-config="retry_wait_min=5"
Джобин Джеймс
источник