97 votes

Chaîne YAML multiligne pour GitLab CI (.gitlab-ci.yml)

J'essaie d'écrire un gitlab-ci.yml qui utilise une chaîne de plusieurs lignes pour la commande. Cependant, il semble qu'elle ne soit pas analysée. J'ai essayé à la fois le - | et - > avec des résultats identiques.

stages:
  - mystage

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

Quand il essaie de s'exécuter, il affiche seulement echo -e ' comme le script à exécuter, et non la chaîne multiligne entière. Cela pose des problèmes pour moi.

Quelle serait la syntaxe correcte pour écrire quelque chose comme ça ?

0 votes

Il y a un problème pour ça : gitlab.com/gitlab-org/gitlab-ci-multi-runner/issues/166 Je ne vois pas bien où est le problème, puisque votre code devrait être équivalent (suffisamment) YAML aux solutions proposées ici. Vous pouvez essayer d'ajouter \ à vos lignes, mais je ne peux pas dire si ça va marcher ou pas.

123voto

PotatoFarmer Points 764

Je suis venu ici en m'attendant à ce que ce soit un problème, mais la commande "multi-ligne" suivante pour la lisibilité fonctionne pour moi :

Gitlab Runner : Shell Runner version 1.11.0 / Version 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}

4 votes

Quelle est l'astuce ici ? Avez-vous mis en retrait la deuxième ligne au même niveau que la première ?

6 votes

@victor-grazi Tel que je le comprends : Dans YAML brut (scalaire de flux brut), les échappements (tels que newline \n ) ne font rien, et les espaces blancs de tête sont ignorés - il semble que Gitlab YAML analyse les blocs script de cette manière. Sur l'indentation : La spécification YAML dit In YAML block styles, structure is determined by indentation et donc la deuxième ligne est indentée autant que l'exige la spécification YAML (un espace par rapport à l'indentation parentale), et un de plus pour la lisibilité (ce qui est techniquement superflu mais plus joli).

0 votes

Fonctionne comme un charme. Fonctionne également avec tous les paramètres dans une nouvelle ligne

49voto

Anthon Points 4119

TL;DR ; Vous voulez utiliser un scalaire YAML à plusieurs lignes (pour plus de lisibilité) qui est chargé comme une chaîne à une seule ligne qui peut être émise comme une commande par Gitlab-CI. Pour ce faire, utilisez un scalaire simple (sans guillemets) dans YAML qui est réparti sur plusieurs lignes :

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

Sachez qu'il existe certaines restrictions imposées par YAML sur ces scalaires. Ce que vous devez certainement savoir, c'est que chaque ligne suivante est indentée d'au moins une position supplémentaire que echo -e (qui est indenté de deux positions par rapport à son nœud de collection, qui n'est pas indenté du tout), et que chaque nouvelle ligne est remplacée par un espace lors du chargement (il faut donc faire un peu attention à l'endroit où placer les nouvelles lignes).


Il y a plusieurs idées fausses dans votre message, qui vous amènent à poser la mauvaise question.

Il n'existe pas de chaîne YAML à plusieurs lignes. . YAML comporte des scalaires et certains de ces scalaires peuvent être chargés par un programme sous forme de chaînes de caractères, tandis que d'autres seront chargés sous forme d'entiers, de flottants, etc.

Vous êtes évidemment intéressé par les nœuds scalaires qui sont chargés sous forme de chaîne, puisque cette chaîne peut ensuite être interprétée comme une ligne de commande. Mais vous ne voulez pas avoir une ligne de commande multi-lignes (i.e. avec des nouvelles lignes intégrées), puisque scripts multi-lignes ne sont pas pris en charge dans Gitlab CI (comme l'a indiqué @Jordan).

Pour plus de lisibilité, vous voulez utiliser la capacité standard de YAML pour charger des scalaires multi-lignes comme des chaînes de caractères d'une seule ligne.

Si vous ne vous souciez pas de la lisibilité, vous pouvez utiliser :

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

et puisque votre scalaire n'est pas cité (c'est-à-dire qu'il commence par echo ) vous n'avez pas besoin de faire quoi que ce soit de spécial dans YAML pour les backslashes ou les guillemets.

Le résultat du script est le même (imprimer une ligne vide, imprimer echo 'hi'; sur une ligne en retrait de quatre espaces, imprimez echo 'bye'; sur une ligne en retrait de quatre espaces).

Si vous voulez utiliser l'entrée multi-lignes pour la lisibilité, qui sont chargées comme une seule ligne, il y a essentiellement deux options : utiliser un scalaire plan multi-lignes ou utiliser un scalaire plié dans votre YAML.

scalaire uni multi-ligne

Plain signifie que le scalaire n'est pas cité, et comme pour toute chose à plusieurs lignes dans YAML, cela signifie que les lignes suivantes doivent être indentées de manière appropriée, dans ce cas plus loin que la ligne initiale.

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

les nouvelles lignes sont remplacées par des espaces, donc ne le font pas :

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

car vous obtiendrez un espace visible avant bye .

Il existe certaines restrictions, comme le fait que vous ne pouvez pas avoir de deux-points suivis d'un espace dans un tel scalaire (ce qui le ferait ressembler à une paire clé-valeur).

Il n'est pas nécessaire d'échapper les barres obliques inverses dans les scalaires simples, car vous ne pouvez pas échapper de caractères dans un scalaire simple, mais vous pouvez bien sûr inclure une barre oblique inversée, qui se retrouvera dans la chaîne chargée à partir du fichier YAML et du fichier peut ont une signification pour la commande exécutée à partir de cette chaîne.

scalaire plié

Un scalaire plié est similaire à un scalaire simple, mais tous les retours à la ligne (simples) sont remplacés par un espace pendant le chargement :

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

Vous devez indenter les informations de la commande réelle au moins autant que l'indicateur scalaire plié ( > ).

Contrairement aux scalaires ordinaires, les choses comme : n'ont pas de signification particulière. Ainsi, si les scalaires simples échouent en lançant une erreur YAML, les scalaires pliés similaires ne le feront probablement pas.

0 votes

Je veux l'écrire en plusieurs lignes pour plus de clarté et de facilité de maintenance. Si mon exemple est trivial, les vrais scripts ne le sont décidément pas.

0 votes

Je peux comprendre cela. Serait-il acceptable de prétraiter votre fichier YAML lisible avant qu'il ne soit traité par GitLab CI ?

0 votes

J'y ai pensé. C'est une étape supplémentaire et un peu plus complexe, mais ça peut en valoir la peine.

27voto

Benny K Points 549

Vous pouvez utiliser n'importe quel script/commande multiligne via la fonctionnalité yaml literal_block et anchors. Exemple :

.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
[...]

0 votes

Merci de partager cette information. Cette fonctionnalité plus avancée sera particulièrement utile pour la lisibilité du travail et la possibilité de réutiliser des morceaux de code tout au long de la recette.

5 votes

C'est un excellent exemple, mais il serait plus clair si vous définissiez .rsync

13voto

mal Points 31

La commande wp config create était assez délicate... à partir du .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

4voto

Maksim Kostromin Points 961

Cela fonctionne pour moi dans 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

Ici, deux variables env ( ${GITHUB_USERNAME} et ${GITHUB_PASSWORD} ) seront également interpolés

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X