Partie 2: Pipeline de CI
Bonjour à toutes et à tous 😀
Dans l'article précédent nous avons poussé à la main des crates en utilisant curl en local.
Ce n'est pas du tout satisfaisant.
Nous allons automatiser tout ça via la CI. Et comme nous avons commencé avec la package registry de Gitlab, on va également utilisé la Gitlab CI.
J'ai un certain nombre d'exigences.
- une adresse unique pour toutes les crates, je ne veaux pas à avoir à me rappeler du chemin à chaque fois
- le versionnage est explicite et basé sur la version du package publié
- support des versions flottantes de dev
- ces versions de devs ont un versionnage implicite et automatique
- cela doit être le moins contraignant à utiliser, le moins de boilerplate possible
- il doit gérer les workspace Rust
Autant dire qu'il y a un peu de travail.
Pipeline de CI 1o1
Commençons par la base.
Si vous créez un fichier .gitlab-ci.yml
à la racine d'un projet git et que vous le poussez sur Gitlab, cela va indiquer à Gitlab qu'il faut lancer un pipeline de CI.
Son format est le suivant
stages:
- stage1
- stage2
job1:
stage: stage1
job2:
stage: stage1
job3:
stage: stage2
Cela créé un graphe d'exécution qui va ressembler à ceci
flowchart LR job1 -->job3 job2 --> job3
job1
et job2
doivent tous les deux réussir si l'on veut que job3
s'exécute. Ce système de strates se nomme des stages et permettent de réaliser des checkpoints bloquants entre les différentes étapes.
Par exemple ne packager que si le build est un succès est une bonne idée. 😎
Nous nous allons définir un stage qui s'appellera package
.
Bon et maintenant, qu'est ce que l'on fait de nos jobs ?.
La première chose est de définir une image qui sera notre environnement de packaging, nous faisons du rust, ça sera donc une image rust. Et de préférence versionnée.
package-crate:
image: rust:1.77
stage: packaging
Nous allons écrire du bash, ce qui reste la meilleure façon d'intéragir avec un environnement.
Et ce bash vient se mettre dans un array nommé scripts
.
package-crate:
image: rust:1.77
stage: packaging
script:
- echo "Hello World"
Packaging en CI
D'abord récapitulons ce que nous avons fait en local:
- nous avons défini un
.ssh/config
contenant le host de notre proxy - nous avons lancé les commandes de packaging
- nous avons fait du curl
Ok, mimons ce fonctionnement.
Tout d'abord occupons-nous du SSH.
La première chose que l'on va faire c'est définir des informations sous forme de variable d'environnement
variables:
CRATE_PACKAGE_ENDPOINT=$CRATES_ENDPOINT
CRATE_PACKAGE_USER=personal-token
Bien maintenant le packaging en lui-même.
Il nécessite plusieurs éléments:
- l'addresse de l'API gitlab trouvable dans la variable injectée
$CI_API_V4_URL
- la version du package
- le nom du package
- le chemin vers le fichier
.crate
à générer à partier des informations précédentes - le token que l'on possède déjà
Pour rappel, cela à cette tête-là:
Commençons par récupérer le nom et la version du package.
Pour cela nous pouvons utiliser un utiliser un utilitaire qui se nomme tomlq
, il vient avec yq
et permet de réaliser des requêtes jq sur un fichier toml.
Pour cela, on se rajoute la dépendance.
&&
Puis on génère nos variables.
On vient "trim" les guillemets qui vont nous ennuyer par la suite.
On peut alors constituer notre $CRATE_FILE
Il nous faut également un $CRATE_PACKAGE_PROJECT_ID
que l'on défini dans les variables d'environement
Nous avons tous les ingédients, nous pouvons créer notre job.
stages:
- packaging
variables:
# gitlab token
CRATE_PACKAGE_TOKEN: $CI_JOB_TOKEN
# l'ID du projet qui supportera les crates par défaut le project du job
CRATE_PACKAGE_PROJECT_ID: $CI_PROJECT_ID
# API user
CRATE_PACKAGE_USER_API: JOB-TOKEN
package-crate:
image: rust:1.77
stage: packaging
script:
# dépendences
- apt update && apt install -y yq
# récupération des informations du paquet
- export CRATE_NAME=$(tomlq '.package.name' Cargo.toml | tr -d '"')
- export CRATE_VERSION=$(tomlq '.package.version' Cargo.toml | tr -d '"')
- export CRATE_FILE=${CRATE_NAME}-${CRATE_VERSION}.crate
# packaging
- cargo package
- cargo metadata --format-version 1 > metadata.json
# upload
- 'curl --header "$CRATE_PACKAGE_USER_API: $CRATE_PACKAGE_TOKEN" --upload-file target/package/${CRATE_FILE} "${CI_API_V4_URL}/projects/${CRATE_PACKAGE_PROJECT_ID}/packages/generic/${CRATE_NAME}/${CRATE_VERSION}/$CRATE_FILE"'
- 'curl --header "$CRATE_PACKAGE_USER_API: $CRATE_PACKAGE_TOKEN" --upload-file metadata.json "${CI_API_V4_URL}/projects/${CRATE_PACKAGE_PROJECT_ID}/packages/generic/${CRATE_NAME}/${CRATE_VERSION}/metadata.json"'
Si tout se passe bien, vous devriez voir apparaître dans la package registry de votre projet Gitlab un paquet project v0.1.0
.
Maintenant intéressons nous au cas où le projet nécessite une dépendence qui elle même est privée.
On se créé un projet pour tester.
&&
&&
Comme vous pouvez le voir, nous allons devoir nous authentifier.
Pour cela nous définissons dans l'objet variables
les différentes informations nécessaire à la connexion SSH.
variables:
CRATE_PACKAGE_TOKEN: $CI_JOB_TOKEN
CRATE_PACKAGE_ENDPOINT: noa-crates.cleverapps.io
CRATE_PACKAGE_PORT: 22066
CRATE_PACKAGE_USER: personal-token
On créé le répertoire .ssh
avec les bons droits
&&
Via heredoc nous générons la configuration SSH:
Mais cela n'est pas suffisant, il faut également générer une clef privée pour que la connexion SSH se fasse.
Et finalement récupérer la clef publique de notre proxy SSH, sinon la connexion échouera en non-intéractif car le endpoint n'est pas "connu".
Ok, notre job de CI est maintenant capable de réaliser notre authentification au proxy.
Nous pouvons rassembler les pièces du puzzle
stages:
- packaging
variables:
# gitlab token
CRATE_PACKAGE_TOKEN: $CI_JOB_TOKEN
# l'ID du projet qui supportera les crates par défaut le project du job
CRATE_PACKAGE_PROJECT_ID: $CI_PROJECT_ID
# API user
CRATE_PACKAGE_USER_API: JOB-TOKEN
# Host du proxy SSH
CRATE_PACKAGE_ENDPOINT: noa-crates.cleverapps.io
# Port d'écoute du proxy SSH
CRATE_PACKAGE_PORT: 22066
# Utilisateur associé au token
CRATE_PACKAGE_USER: personal-token
package-crate:
image: rust:1.77
stage: packaging
script:
# dépendences
- apt update && apt install -y yq
# configuration SSH
- mkdir -p ~/.ssh && chmod -R 700 ~/.ssh
- |
cat << EOF > ~/.ssh/config
Host $CRATE_PACKAGE_ENDPOINT
User $CRATE_PACKAGE_USER:$CRATE_PACKAGE_TOKEN
Port $CRATE_PACKAGE_PORT
EOF
# création de la paire de clefs
- ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519
# ajout de la clef publique du proxy
- ssh-keyscan -p $CRATE_PACKAGE_PORT $CRATE_PACKAGE_ENDPOINT >> ~/.ssh/known_hosts
# récupération des informations du paquet
- export CRATE_NAME=$(tomlq '.package.name' Cargo.toml | tr -d '"')
- export CRATE_VERSION=$(tomlq '.package.version' Cargo.toml | tr -d '"')
- export CRATE_FILE=${CRATE_NAME}-${CRATE_VERSION}.crate
# packaging
- cargo package
- cargo metadata --format-version 1 > metadata.json
# upload
- 'curl --header "$CRATE_PACKAGE_USER_API: $CRATE_PACKAGE_TOKEN" --upload-file target/package/${CRATE_FILE} "${CI_API_V4_URL}/projects/${CRATE_PACKAGE_PROJECT_ID}/packages/generic/${CRATE_NAME}/${CRATE_VERSION}/$CRATE_FILE"'
- 'curl --header "$CRATE_PACKAGE_USER_API: $CRATE_PACKAGE_TOKEN" --upload-file metadata.json "${CI_API_V4_URL}/projects/${CRATE_PACKAGE_PROJECT_ID}/packages/generic/${CRATE_NAME}/${CRATE_VERSION}/metadata.json"'
Et là c'est le drame 😫
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
Oui, votre $CI_JOB_TOKEN
n'a de droit que sur le projet need_project
pas project
.
Mais heureusement, il est possible de régler le souci en passant en paramètre du job un token apte à intéragir avec les deux projets, pour Gitlab SaaS en gratuit nous n'avons pas le choix, ça sera forcément des token personnels, mais pour des version self-hosted, il est possible de créer des group token.
Bref, dans la configuration de la CI du projet need_project
rajouté une variable d'environnement CRATE_PACKAGE_TOKEN
avec votre token.
Il faut également redéfinir le CRATE_PACKAGE_USER_API
à PRIVATE-TOKEN
On relance
Si tout est correct,
Votre pipeline devrait afficher quelque part ceci:
$ cargo package
warning: manifest has no description, license, license-file, documentation, homepage or repository.
See https://doc.rust-lang.org/cargo/reference/manifest.html#package-metadata for more info.
Packaging need_project v0.1.0 (/builds/noa-crates/need_project2)
Verifying need_project v0.1.0 (/builds/noa-crates/need_project2)
Updating `private-crate` index
From ssh://noa-crates.cleverapps.io/noa-crates/project
* [new ref] -> origin/HEAD
Downloading crates ...
Downloaded project v0.1.0 (registry `private-crate`)
Compiling project v0.1.0 (registry `private-crate`)
Compiling need_project v0.1.0 (/builds/noa-crates/need_project2/target/package/need_project-0.1.0)
Finished dev [unoptimized + debuginfo] target(s) in 3.00s
Cela prouve que votre arbre de dépendences privée est bien reconstruite en CI. 🤩
Succès ⁉️
Oui et non, c'est très contraignant de connaître toute cette mécanique, on ne gère pas encore les workspace et les versions de pre-release sont impossible à réaliser en l'état.
Bref on repars en chasse !
Versions de pre-release
Qu'est ce qu'une version de pre-release pour moi ?
Une version de pre-release c'est une version pas fini mais qui est nécessaire de packager pour d'autres développements.
Si on se fie à la notation semver suivie par cargo.
Il est possible de créer des versions qui ne sont pas "finies" en les suffixant d'un attribut.
par exemple 1.0.0-alpha.0
, le suffixe de version alpha.0
indique la notion de pre-release de cette 1.0.0
.
Mais on peut y mettre ce que l'on désire comme le SHA1 réduit de 8 caratères du commit de version.
C'est ce que j'ai décidé de faire pour générer des versions comme 1.0.2-2e92f1ff
.
Pour cela nous allons concaténer la version récupérer du Cargo.toml et la joindre au contenu de la varaible $CI_COMMIT_SHORT_SHA
injecté par le job.
Ok easy non ?
Alors non, si vous tentez de faire ça comme cela, la commande cargo package
n'utilisera pas votre version modifiée et créera un target/package/project-0.1.0.crate
au lieu du target/package/project-0.1.0-2e92f1ff.crate
voulu.
Il va falloir trafiquer le Cargo.toml pour mettre à jour la version.
tomlq permet au moyen du paramètre --arg
d'injecter de l'environnement.
Et il faut également rajouter un paramètre --allow-dirty
pour packager sans avoir à commiter.
cargo package --allow-dirty
On est bon ?
Presque.
Il faut que l'on découple les run entre la branche main
et les autres: je veux que le package de release ne se déclenche que sur la branche main et pas ailleurs.
Et je veux également que le run du packaging de pre-release soit une tâche manuelle.
Heuresement Gitlab Ci permet de configurer tout ceci.
stages:
- packaging
release-dev:
stage: packaging
# nécessite une intervention humaine
when: manual
# si la branche n'est pas main
rules:
- if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
release-prod:
stage: packaging
# seulement si c'est main
only:
- $CI_DEFAULT_BRANCH
Et maintenant on rempli
stages:
- packaging
variables:
# gitlab token
CRATE_PACKAGE_TOKEN: $CI_JOB_TOKEN
# l'ID du projet qui supportera les crates par défaut le project du job
CRATE_PACKAGE_PROJECT_ID: $CI_PROJECT_ID
# API user
CRATE_PACKAGE_USER_API: JOB-TOKEN
# Host du proxy SSH
CRATE_PACKAGE_ENDPOINT: noa-crates.cleverapps.io
# Port d'écoute du proxy SSH
CRATE_PACKAGE_PORT: 22066
# Utilisateur associé au token
CRATE_PACKAGE_USER: personal-token
release-dev:
image: rust:1.77
stage: packaging
# nécessite une intervention humaine
when: manual
# si la branche n'est pas main
rules:
- if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
script:
# dépendences
- apt update && apt install -y yq
# configuration SSH
- mkdir -p ~/.ssh && chmod -R 700 ~/.ssh
- |
cat << EOF > ~/.ssh/config
Host $CRATE_PACKAGE_ENDPOINT
User $CRATE_PACKAGE_USER:$CRATE_PACKAGE_TOKEN
Port $CRATE_PACKAGE_PORT
EOF
# création de la paire de clefs
- ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519
# ajout de la clef publique du proxy
- ssh-keyscan -p $CRATE_PACKAGE_PORT $CRATE_PACKAGE_ENDPOINT >> ~/.ssh/known_hosts
# récupération des informations du paquet
- export CRATE_NAME=$(tomlq '.package.name' Cargo.toml | tr -d '"')
- export CRATE_VERSION=$(tomlq '.package.version' Cargo.toml | tr -d '"')
# on créé la version flottante
- export CRATE_VERSION=$CRATE_VERSION-$CI_COMMIT_SHORT_SHA
- export CRATE_FILE=${CRATE_NAME}-${CRATE_VERSION}.crate
# On remplace la version
- tomlq --arg VERSION $CRATE_VERSION -t '.package.version = $VERSION' Cargo.toml > Cargo.toml.modified
- mv Cargo.toml.modified Cargo.toml
# packaging
- cargo package --allow-dirty
- cargo metadata --format-version 1 > metadata.json
# upload
- 'curl --header "$CRATE_PACKAGE_USER_API: $CRATE_PACKAGE_TOKEN" --upload-file target/package/${CRATE_FILE} "${CI_API_V4_URL}/projects/${CRATE_PACKAGE_PROJECT_ID}/packages/generic/${CRATE_NAME}/${CRATE_VERSION}/$CRATE_FILE"'
- 'curl --header "$CRATE_PACKAGE_USER_API: $CRATE_PACKAGE_TOKEN" --upload-file metadata.json "${CI_API_V4_URL}/projects/${CRATE_PACKAGE_PROJECT_ID}/packages/generic/${CRATE_NAME}/${CRATE_VERSION}/metadata.json"'
release-prod:
image: rust:1.77
stage: packaging
# seulement si c'est main
only:
- $CI_DEFAULT_BRANCH
script:
# dépendences
- apt update && apt install -y yq
# configuration SSH
- mkdir -p ~/.ssh && chmod -R 700 ~/.ssh
- |
cat << EOF > ~/.ssh/config
Host $CRATE_PACKAGE_ENDPOINT
User $CRATE_PACKAGE_USER:$CRATE_PACKAGE_TOKEN
Port $CRATE_PACKAGE_PORT
EOF
# création de la paire de clefs
- ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519
# ajout de la clef publique du proxy
- ssh-keyscan -p $CRATE_PACKAGE_PORT $CRATE_PACKAGE_ENDPOINT >> ~/.ssh/known_hosts
# récupération des informations du paquet
- export CRATE_NAME=$(tomlq '.package.name' Cargo.toml | tr -d '"')
- export CRATE_VERSION=$(tomlq '.package.version' Cargo.toml | tr -d '"')
- export CRATE_FILE=${CRATE_NAME}-${CRATE_VERSION}.crate
# packaging
- cargo package
- cargo metadata --format-version 1 > metadata.json
# upload
- 'curl --header "$CRATE_PACKAGE_USER_API: $CRATE_PACKAGE_TOKEN" --upload-file target/package/${CRATE_FILE} "${CI_API_V4_URL}/projects/${CRATE_PACKAGE_PROJECT_ID}/packages/generic/${CRATE_NAME}/${CRATE_VERSION}/$CRATE_FILE"'
- 'curl --header "$CRATE_PACKAGE_USER_API: $CRATE_PACKAGE_TOKEN" --upload-file metadata.json "${CI_API_V4_URL}/projects/${CRATE_PACKAGE_PROJECT_ID}/packages/generic/${CRATE_NAME}/${CRATE_VERSION}/metadata.json"'
{%end%}
Si l'on
Un pipeline avec une tâche manuelle va apparaître
Et dedans normalement
$ cargo package --allow-dirty
Packaging need_project v0.1.0-0eb85488 (/builds/noa-crates/need_project2)
Verifying need_project v0.1.0-0eb85488 (/builds/noa-crates/need_project2)
Updating `private-crate` index
From ssh://noa-crates.cleverapps.io/noa-crates/project
* [new ref] -> origin/HEAD
Downloading crates ...
Downloaded project v0.1.0 (registry `private-crate`)
Compiling project v0.1.0 (registry `private-crate`)
Compiling need_project v0.1.0-0eb85488 (/builds/noa-crates/need_project2/target/package/need_project-0.1.0-0eb85488)
Finished dev [unoptimized + debuginfo] target(s) in 2.89s
Packaged 6 files, 4.7KiB (1.8KiB compressed)
Félicitation, vous avez packagé votre version 0.1.0-0eb85488
de need_project
et celle-ci peut alors se retrouver dans la package registry de need_project
.
Factorisation
Tout cela c'est très bien mais on voit bien que les étapes sont très semblables entre le job de release et de pre-release.
Il doit être possible de mettre en place un système qui permet de factoriser ces répétitions, et ce mécanisme ne provient pas de Gitlab mais du format YAML, lui-même.
Il s'agit des YAML anchors.
Qu'est ce que l'on peut factoriser ?
Tout d'abord les dépendences
.dependencies:
# dépendences
- apt update && apt install -y yq
Puis la définition de la configuration SSH
.ssh-connexion:
# configuration SSH
- mkdir -p ~/.ssh && chmod -R 700 ~/.ssh
- |
cat << EOF > ~/.ssh/config
Host $CRATE_PACKAGE_ENDPOINT
User $CRATE_PACKAGE_USER:$CRATE_PACKAGE_TOKEN
Port $CRATE_PACKAGE_PORT
EOF
# création de la paire de clefs
- ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519
# ajout de la clef publique du proxy
- ssh-keyscan -p $CRATE_PACKAGE_PORT $CRATE_PACKAGE_ENDPOINT >> ~/.ssh/known_hosts
Ensuite, la récupération des informations du package.
.version:
# récupération des informations du paquet
- export CRATE_NAME=$(tomlq '.package.name' Cargo.toml | tr -d '"')
- export CRATE_VERSION=$(tomlq '.package.version' Cargo.toml | tr -d '"')
- export CRATE_FILE=${CRATE_NAME}-${CRATE_VERSION}.crate
Et finalement, le packaging en lui-même
.packaging:
# packaging
- cargo package --allow-dirty
- cargo metadata --format-version 1 > metadata.json
- ls target/package/$CRATE_FILE
# upload
- 'curl -i --header "$CRATE_PACKAGE_USER_API: $CRATE_PACKAGE_TOKEN" --upload-file target/package/${CRATE_FILE} "${CI_API_V4_URL}/projects/${CRATE_PACKAGE_PROJECT_ID}/packages/generic/${CRATE_NAME}/${CRATE_VERSION}/$CRATE_FILE"'
- 'curl -i --header "$CRATE_PACKAGE_USER_API: $CRATE_PACKAGE_TOKEN" --upload-file metadata.json "${CI_API_V4_URL}/projects/${CRATE_PACKAGE_PROJECT_ID}/packages/generic/${CRATE_NAME}/${CRATE_VERSION}/metadata.json"'
On peut alors jouer aux légos 🧱
.prepare:
- *dependencies
- *ssh-connexion
- *version
release-dev:
image: rust:1.77
stage: packaging
# manuel
when: manual
# si la branche n'est pas main
rules:
- if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
script:
- *prepare
# on créé la version flottante
- export CRATE_VERSION=$CRATE_VERSION-$CI_COMMIT_SHORT_SHA
- export CRATE_FILE=${CRATE_NAME}-${CRATE_VERSION}.crate
# On remplace la version
- tomlq --arg VERSION $CRATE_VERSION -t '.package.version = $VERSION' Cargo.toml > Cargo.toml.modified
- mv Cargo.toml.modified Cargo.toml
- *packaging
release-prod:
image: rust:1.77
stage: packaging
# seulement si c'est main
only:
- main
script:
- *prepare
- *packaging
C'est quand même plus clean comme ça 😀.gitlab-ci.yml
stages:
- packaging
variables:
# gitlab token
CRATE_PACKAGE_TOKEN: $CI_JOB_TOKEN
# l'ID du projet qui supportera les crates par défaut le project du job
CRATE_PACKAGE_PROJECT_ID: $CI_PROJECT_ID
# API user
CRATE_PACKAGE_USER_API: JOB-TOKEN
# Host du proxy SSH
CRATE_PACKAGE_ENDPOINT: noa-crates.cleverapps.io
# Port d'écoute du proxy SSH
CRATE_PACKAGE_PORT: 22066
# Utilisateur associé au token
CRATE_PACKAGE_USER: personal-token
.dependencies:
# dépendences
- apt update && apt install -y yq
.ssh-connexion:
# configuration SSH
- mkdir -p ~/.ssh && chmod -R 700 ~/.ssh
- |
cat << EOF > ~/.ssh/config
Host $CRATE_PACKAGE_ENDPOINT
User $CRATE_PACKAGE_USER:$CRATE_PACKAGE_TOKEN
Port $CRATE_PACKAGE_PORT
EOF
# création de la paire de clefs
- ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519
# ajout de la clef publique du proxy
- ssh-keyscan -p $CRATE_PACKAGE_PORT $CRATE_PACKAGE_ENDPOINT >> ~/.ssh/known_hosts
.packaging:
# packaging
- cargo package --allow-dirty
- cargo metadata --format-version 1 > metadata.json
- ls target/package/$CRATE_FILE
# upload
- 'curl -i --header "$CRATE_PACKAGE_USER_API: $CRATE_PACKAGE_TOKEN" --upload-file target/package/${CRATE_FILE} "${CI_API_V4_URL}/projects/${CRATE_PACKAGE_PROJECT_ID}/packages/generic/${CRATE_NAME}/${CRATE_VERSION}/$CRATE_FILE"'
- 'curl -i --header "$CRATE_PACKAGE_USER_API: $CRATE_PACKAGE_TOKEN" --upload-file metadata.json "${CI_API_V4_URL}/projects/${CRATE_PACKAGE_PROJECT_ID}/packages/generic/${CRATE_NAME}/${CRATE_VERSION}/metadata.json"'
.version:
# récupération des informations du paquet
- export CRATE_NAME=$(tomlq '.package.name' Cargo.toml | tr -d '"')
- export CRATE_VERSION=$(tomlq '.package.version' Cargo.toml | tr -d '"')
- export CRATE_FILE=${CRATE_NAME}-${CRATE_VERSION}.crate
.prepare:
- *dependencies
- *ssh-connexion
- *version
release-dev:
image: rust:1.77
stage: packaging
# manuel
when: manual
# si la branche n'est pas main
rules:
- if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
script:
- *prepare
# on créé la version flottante
- export CRATE_VERSION=$CRATE_VERSION-$CI_COMMIT_SHORT_SHA
- export CRATE_FILE=${CRATE_NAME}-${CRATE_VERSION}.crate
# On remplace la version
- tomlq --arg VERSION $CRATE_VERSION -t '.package.version = $VERSION' Cargo.toml > Cargo.toml.modified
- mv Cargo.toml.modified Cargo.toml
- *packaging
release-prod:
image: rust:1.77
stage: packaging
# seulement si c'est main
only:
- main
script:
- *prepare
- *packaging
Pour le prochain, article on verra comment gérer le problème épineux des workspaces.
Ce travail est sous licence CC BY-NC-SA 4.0.