97 votes

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

Je cherche à écrire un fichier gitlab-ci.yml qui utilise une chaîne multi-lignes pour la commande. Cependant, il semble que cela ne soit pas analysé. J'ai essayé à la fois - | et - > avec des résultats identiques.

stages:
  - mystage

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

Lorsqu'il essaie de s'exécuter, il affiche seulement echo -e ' comme script à exécuter, et non toute la chaîne multi-lignes. Cela me pose des problèmes.

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

0 votes

Il y a un problème à ce sujet : gitlab.com/gitlab-org/gitlab-ci-multi-runner/issues/166 Il n'est pas clair pour moi quel est le problème, puisque votre code devrait être équivalent (suffisamment) en YAML par rapport aux solutions proposées là-bas. Vous pouvez essayer d'ajouter \ à la fin de vos lignes, mais je ne peux pas garantir si cela fonctionnera ou non.

123voto

PotatoFarmer Points 764

Je suis venu ici de manière préventive en m'attendant à ce que cela pose problème, mais la commande "multi-ligne" suivante pour la lisibilité fonctionne pour moi :

Gitlab Runner : Version Shell Runner 1.11.0 / Version Gitlab : 8.17.2

myjob:
stage: deploy
script:
  # Commande sur une seule ligne
  - az component update --add sql

  # Commande sur plusieurs lignes
  - az sql server create -n ${variable} -g ${variable} -l ${variable}
    --administrator-login ${variable} --administrator-login-password ${variable}

4 votes

Quel est le truc ici? Avez-vous indenté la deuxième ligne au même niveau que la première ligne?

6 votes

@victor-grazi Tel que je le comprends : En YAML brut (scalaire d'écoulement brut), les échappements (comme le saut de ligne \n) ne servent à rien, et les espaces blancs initiaux sont ignorés - il semble que le YAML de Gitlab analyse les blocs de script de cette manière. Sur l'indentation : La spécification YAML dit que Dans les styles de bloc YAML, la structure est déterminée par l'indentation et donc la deuxième ligne est indentée autant que nécessaire pour la spécification YAML (un espace par rapport à l'indentation parent), et un de plus pour la lisibilité (techniquement superflue mais plus jolie).

0 votes

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

49voto

Anthon Points 4119

TL;DR; Vous voulez utiliser un scalaire YAML multi-ligne (pour la lisibilité) qui est chargé comme une chaîne d'une seule ligne pouvant être exécutée comme une commande par Gitlab-CI. Pour ce faire, utilisez un scalaire simple (sans guillemets) en YAML qui est réparti sur plusieurs lignes :

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

Veuillez noter qu'il existe certaines restrictions imposées par YAML sur de tels scalaires. Ce que vous devez absolument savoir, c'est que chaque ligne suivante est indentée d'au moins une position de plus que echo -e (qui est indenté de deux positions par rapport à son noeud de collection, qui n'est pas du tout indenté), et que chaque nouvelle ligne est remplacée par un espace lors du chargement (vous devez donc faire attention à l'emplacement des nouvelles lignes).


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

Il n'existe pas de tel chose comme une chaîne YAML multi-ligne. YAML a des scalaires et certains de ces scalaires peuvent être chargés par un programme en tant que chaînes, tandis que d'autres seront chargés en tant qu'entiers, flottants, etc.

Vous êtes évidemment intéressé par les noeuds scalaires qui sont chargés en tant que chaîne, puisque cette chaîne peut ensuite être interprétée comme une commande ligne de commande. Mais vous ne voulez pas avoir une ligne de commande multi-ligne (c'est-à-dire avec des sauts de ligne intégrés), car les scripts multi-lignes ne sont pas pris en charge dans Gitlab CI (comme l'a indiqué @Jordan).

Pour la lisibilité, vous voulez utiliser la capacité standard de YAML à charger des scalaires multi-lignes en tant que chaîne d'une seule ligne.

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

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

et puisque votre scalaire n'est pas entre guillemets (c'est-à-dire qu'il commence par echo), vous n'avez pas besoin de faire quelque chose de spécial en YAML pour les antislashs ou les guillemets.

Le résultat du script est le même (afficher une ligne vide, afficher echo 'hi'; sur une ligne indentée de quatre espaces, afficher echo 'bye'; sur une ligne indentée de quatre espaces).

Si vous souhaitez utiliser une entrée multi-ligne pour la lisibilité, qui est chargée comme une seule ligne, il existe essentiellement deux options : utiliser un scalaire plain multi-ligne ou utiliser un scalaire plié dans votre YAML.

scalaire plain multi-ligne

Plain signifie que le scalaire n'est pas entre guillemets, et comme pour toute chose multi-ligne en YAML, cela signifie que les lignes suivantes doivent être indentées de manière appropriée, dans ce cas plus que la ligne initiale

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

les sauts de ligne sont remplacés par des espaces donc ne faites pas :

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

car vous obtiendrez un espace visible avant bye.

Il y a quelques restrictions comme le fait que vous ne pouvez pas avoir un deux-points suivi d'un espace à l'intérieur d'un tel scalaire (ce qui le ferait ressembler à une paire clé-valeur).

Il n'est pas nécessaire d'échapper les antislashs dans les scalaires plain, car vous ne pouvez pas échapper de caractères dans un scalaire plain, mais bien sûr vous pouvez inclure un antislash, qui se retrouvera dans la chaîne chargée depuis le YAML et peut avoir une signification pour la commande exécutée à partir de cette chaîne.

scalaire plié

Un scalaire plié est similaire à un scalaire plain en ce sens que toutes les (uniques) nouvelles lignes sont substituées par un espace lors du chargement :

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

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

Contrairement aux scalaires plain, des choses comme : n'ont pas de signification spéciale. Donc si les scalaires plain échouent en lançant une erreur YAML, des scalaires pliés similaires ne le feront probablement pas.

0 votes

Je veux l'écrire sur plusieurs lignes pour plus de clarté et de maintenabilité. Bien que mon exemple soit trivial, les vrais scripts ne le sont certainement 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'ai bien pris cela en compte. C'est une étape supplémentaire et une complexité supplémentaire, mais cela peut en valoir la peine.

27voto

Benny K Points 549

Vous pouvez utiliser n'importe quel script/commande multiligne via le bloc littéral yaml et la fonction d'ancrage. Exemple :

.build: &build |
    echo -e "\n$hl Construction $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 pour le partage - cette fonctionnalité plus avancée sera particulièrement utile pour la lisibilité du travail / la possibilité de réutiliser des morceaux de code tout au long de la recette.

5 votes

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

13voto

mal Points 31

La commande de création de configuration wp config était assez capricieuse... du fichier .gitlab-ci...

build:
  stage: build
  script:
    - echo "Construction de l'application"
    - |
        wp config create --dbname=$vardb --dbhost=$varhost --dbuser=$varusr --dbpass=$varpas --extra-php <

4voto

Maksim Kostromin Points 961

Cela fonctionne pour moi dans Travis CI

before_install:
  - set -e
  - |
    echo "

          github
          ${GITHUB_USERNAME}
          ${GITHUB_PASSWORD}

    " >  ${HOME}/.m2/settings.xml

Ici, deux variables d'environnement (${GITHUB_USERNAME} et ${GITHUB_PASSWORD}) seront également interpolées

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