Mehrzeiliger YAML-String für GitLab CI (.gitlab-ci.yml)

83

Ich versuche, eine gitlab-ci.ymlDatei zu schreiben , die eine mehrzeilige Zeichenfolge für den Befehl verwendet. Es scheint jedoch, dass es nicht analysiert wird. Ich habe sowohl das - |als auch - >mit identischen Ergebnissen ausprobiert .

stages:
  - mystage

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

Wenn versucht wird, ausgeführt zu werden, wird nur echo -e 'das auszuführende Skript und nicht die gesamte mehrzeilige Zeichenfolge angezeigt. Dies verursacht Probleme für mich.

Was wäre die richtige Syntax, um so etwas zu schreiben?

Samanime
quelle
Es gibt ein Problem für diese: gitlab.com/gitlab-org/gitlab-ci-multi-runner/issues/166 nicht für mich ist es klar , was das Problem ist, da der Code sollte äquivalent sein (genug) YAML zu den Lösungen vorgeschlagen , dort . Sie könnten versuchen, \an Ihre Zeilen anzuhängen , aber ich kann nicht sagen, ob das funktioniert oder nicht.
Jordan läuft

Antworten:

35

TL; DR; Sie möchten einen mehrzeiligen YAML-Skalar (zur besseren Lesbarkeit) verwenden, der als einzeilige Zeichenfolge geladen wird, die von Gitlab-CI als Befehl ausgegeben werden kann. Verwenden Sie dazu in YAML einen einfachen Skalar (ohne Anführungszeichen), der über mehrere Zeilen verteilt ist:

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

Bitte beachten Sie, dass YAML solchen Skalaren einige Einschränkungen auferlegt. Was Sie sicherlich wissen müssen, ist, dass jede folgende Zeile mindestens eine Position mehr echo -eeingerückt ist als (die zwei Positionen relativ zu ihrem Sammlungsknoten eingerückt ist, der überhaupt nicht eingerückt ist) und dass jede neue Zeile durch ein Leerzeichen ersetzt wird wenn geladen (also müssen Sie ein wenig darauf achten, wo Sie Zeilenumbrüche platzieren).


Es gibt mehrere Missverständnisse in Ihrem Beitrag, die dazu führen, dass Sie die falsche Frage stellen.

Es gibt keine mehrzeilige YAML-Zeichenfolge . YAML verfügt über Skalare, und einige dieser Skalare können von einem Programm als Zeichenfolgen geladen werden, während andere als Ganzzahlen, Gleitkommazahlen usw. geladen werden.

Sie sind offensichtlich an Skalarknoten interessiert, die als Zeichenfolge geladen werden, da diese Zeichenfolge dann als Befehlszeile interpretiert werden kann. Sie möchten jedoch keine mehrzeilige Befehlszeile (dh mit eingebetteten Zeilenumbrüchen) haben, da mehrzeilige Skripte in Gitlab CI nicht unterstützt werden (wie von @Jordan angegeben).

Zur besseren Lesbarkeit möchten Sie die Standardfunktion von YAML verwenden, um mehrzeilige Skalare als einzeilige Zeichenfolge zu laden.

Wenn Sie sich nicht für die Lesbarkeit interessieren, können Sie Folgendes verwenden:

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

und da Ihr Skalar nicht in Anführungszeichen steht (dh mit beginnt echo), müssen Sie in YAML nichts Besonderes für die Backslashes oder Anführungszeichen tun.

Das Ergebnis des Skripts ist dasselbe (leere Zeile drucken, echo 'hi';in einer Zeile mit vier Leerzeichen einrücken , in einer Zeile mit vier Leerzeichen drucken echo 'bye';).

Wenn Sie den mehrzeiligen Eingang zur besseren Lesbarkeit verwenden möchten, der als einzelne Zeile geladen wird, gibt es im Wesentlichen zwei Optionen: Verwenden Sie einen mehrzeiligen Ebenenskalar oder einen gefalteten Skalar in Ihrer YAML.

mehrzeiliger einfacher Skalar

Einfach bedeutet, dass der Skalar nicht in Anführungszeichen steht, und wie bei allen mehrzeiligen Elementen in YAML bedeutet mehrzeilig, dass folgende Zeilen entsprechend eingerückt werden müssen, in diesem Fall weiter als die ursprüngliche Zeile

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

Zeilenumbrüche werden durch Leerzeichen ersetzt. Tun Sie also nichts:

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

wie Sie einen sichtbaren Raum vor bekommen bye.

Es gibt einige Einschränkungen, dass Sie keinen Doppelpunkt gefolgt von einem Leerzeichen innerhalb eines solchen Skalars haben können (wodurch es wie ein Schlüssel-Wert-Paar aussehen würde).

Es besteht keine Notwendigkeit Schrägstriche im Klar Skalare zu entkommen, da Sie keine Zeichen in einem einfachen skalaren entweichen können, aber natürlich können Sie einen umgekehrten Schrägstrich enthalten, die in der Zeichenfolge aus dem YAML geladen werden am Ende und kann haben für den Befehl Bedeutung ausgeführt von dieser Zeichenfolge.

gefalteter Skalar

Ein gefalteter Skalar ähnelt einem einfachen Skalar dahingehend, dass alle (einzelnen) Zeilenumbrüche beim Laden durch ein Leerzeichen ersetzt werden:

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

Sie müssen die tatsächlichen Befehlsinformationen mindestens so stark einrücken wie die gefaltete Skalaranzeige ( >).

Im Gegensatz zu einfachen Skalaren haben Dinge wie :keine besondere Bedeutung. Wenn also einfache Skalare durch Auslösen eines YAML-Fehlers fehlschlagen, werden ähnliche gefaltete Skalare dies höchstwahrscheinlich nicht tun.

Anthon
quelle
Ich möchte es aus Gründen der Klarheit und Wartbarkeit mehrzeilig schreiben. Während mein Beispiel trivial ist, sind die echten Skripte entschieden nicht.
Samanime
Ich kann das verstehen. Wäre es akzeptabel, Ihre lesbare YAML-Datei vorzuverarbeiten, bevor sie von GitLab CI verarbeitet wird?
Anthon
Ich habe darüber nachgedacht. Es ist ein zusätzlicher Schritt und ein bisschen mehr Komplexität, aber es kann sich lohnen.
Samanime
Ich habe eine mögliche Lösung hinzugefügt.
Anthon
3
Oh Junge. Diese Antwort ist zwar technisch korrekt, aber lächerlich ausführlich bis zur Unlesbarkeit. Jeder, der keinen YAML-Parser schreibt , möchte wahrscheinlich stattdessen nur die hoch bewertete und viel knappere Antwort von PotatoFarmer .
Cecil Curry
111

Ich bin hierher gekommen, um zu erwarten, dass dies ein Problem sein würde, aber der folgende "mehrzeilige" Befehl zur besseren Lesbarkeit funktioniert für mich:

Gitlab Runner: Shell Runner Version 1.11.0 / Gitlab Version: 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}
Kartoffelbauer
quelle
2
Was ist der Trick hier? Haben Sie die zweite Zeile auf die gleiche Ebene wie die erste Zeile eingerückt?
Victor Grazi
6
@ victor-grazi So wie ich es verstehe: In normalem YAML (normalem Flussskalar \n) tun Escapezeichen (wie z. B. Newline ) nichts, und führende Leerzeichen werden ignoriert - es scheint, dass Gitlab YAML Skriptblöcke auf diese Weise analysiert. Zum Einrücken: YAML-Spezifikation sagt In YAML block styles, structure is determined by indentationund so wird die zweite Zeile so oft eingerückt, wie es für die YAML-Spezifikation erforderlich ist (ein Leerzeichen relativ zum übergeordneten Einzug) und ein weiteres für die Lesbarkeit (was technisch überflüssig, aber hübscher ist).
PotatoFarmer
Klappt wunderbar. Funktioniert auch mit allen Parametern in der neuen Zeile
Bodolsog
25

Sie können beliebige mehrzeilige Skripte / Befehle über die Funktion yaml literal_block und anchor verwenden. Beispiel:

.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
[...]
Benny K.
quelle
Vielen Dank für das Teilen - diese erweiterte Funktionalität ist besonders nützlich für die Lesbarkeit des Jobs / für die Wiederverwendung von Codeblöcken im gesamten Rezept.
PotatoFarmer
5
Dies ist ein großartiges Beispiel, aber es wäre klarer, wenn Sie .rsync
Victor Grazi
13

Der Befehl wp config create war ziemlich pingelig ... von der .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
mal
quelle
4

Das funktioniert für mich in 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

Hier werden auch zwei env-Variablen ( ${GITHUB_USERNAME}und ${GITHUB_PASSWORD}) interpoliert

Maksim Kostromin
quelle
0

Dieses Format wird funktionieren. Verwenden Sie in YAML einen einfachen Skalar (ohne Anführungszeichen). Beispiel: Skript zum Initialisieren des Terraform-Backends

  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"
Job in
quelle