Aide-mémoire¶
Une page à ouvrir quand on est bloqué: "je veux faire X, qu'est-ce que j'écris ?".
Oui, c'est claude qui a fait ça
CI: je veux que...¶
| Je veux que... | J'écris |
|---|---|
le job tourne seulement sur main |
rules: - if: '$CI_COMMIT_BRANCH == "main"' |
le job tourne partout sauf sur main |
- if: '$CI_COMMIT_BRANCH == "main"' + when: never, puis - when: on_success |
| le job tourne seulement dans une MR | - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' |
le job tourne seulement dans une MR vers main |
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main"' |
| le job tourne seulement quand on push un tag | - if: '$CI_COMMIT_TAG' (ou '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_TAG') |
| le job soit lancé à la main | when: manual dans la règle |
| le job tourne même si un job d'avant a échoué | when: always |
| le job tourne seulement si un job d'avant a échoué | when: on_failure |
| le job soit retardé | when: delayed + start_in: 30 minutes |
| pas de pipeline en double (push + MR) | workflow avec $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS en never |
| aucune pipeline sur un push de tag | workflow: $CI_COMMIT_TAG en never |
aucune pipeline sur main |
workflow: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH en never |
| le job utilise mon runner | tags: [self-hosted] (ou shell à l'éval) |
| le job garde des fichiers | artifacts: paths: [dist/] + expire_in: 1 hour |
| le job récupère les fichiers d'un job précis | needs: - job: build + artifacts: true |
| tout le monde ait le même tag/image | default: ou image: global |
| le job lise tout l'historique git | variables: GIT_DEPTH: "0" |
| un secret dans la pipeline | Settings > CI/CD > Variables puis $MA_VARIABLE |
CI: ça ne marche pas¶
| Symptôme | Cause probable | Page |
|---|---|---|
| job bloqué en pending | aucun runner avec le tag demandé (ou pas de tag alors que le runner n'accepte que les jobs taggés) | runners |
| pipeline impossible à créer, "no jobs" | tous les jobs exclus par leurs rules, ou workflow qui bloque tout |
rules |
yaml invalide sur une ligne echo "Truc: $X" |
: dans une ligne non quotée: mettre la ligne entre '...' ou utiliser un bloc | (voir la page CI GitLab) |
CI GitLab |
apt-get/sudo apt demande un mot de passe |
runner lancé par un utilisateur normal | runners |
image: ignorée |
le runner est en mode shell | runners |
| variable FTP vide dans le job | variable Protected sur une branche non protégée, ou nom différent du yaml | mots-clés |
site publié avec des 404 sur /assets/... |
base: "./" manquant dans vite.config.js |
runners |
npm ci échoue |
package-lock.json absent ou pas à jour (ou ignoré par .gitignore) |
mots-clés |
Git: je veux...¶
| Je veux... | Commande |
|---|---|
| voir ce qui a changé | git status / git diff / git diff --staged |
| modifier le dernier commit (pas encore poussé) | git add fichier puis git commit --amend |
| défaire le dernier commit, garder les modifs | git reset HEAD~1 |
| défaire un commit déjà poussé | git revert <hash> |
| jeter les modifs d'un fichier | git restore fichier |
| retirer un fichier du staging | git restore --staged fichier |
| arrêter de suivre un fichier sans le supprimer | git rm --cached fichier puis .gitignore |
| voir le graphe avec les tags | git log --oneline --graph --all --decorate |
| voir les branches distantes aussi | git branch -a |
| renommer la branche courante | git branch -m nouveau-nom |
| voir mes remotes | git remote -v |
| créer et pousser un tag | git tag v1.0.0 puis git push origin v1.0.0 |
| supprimer un tag en local | git tag -d v1.0.0 |
| supprimer un tag sur le remote | git push origin --delete v1.0.0 |
| récupérer sans merger | git fetch origin main |
| récupérer et merger | git pull origin main |
refusing to merge unrelated histories |
git pull origin main --allow-unrelated-histories |
| git réclame comment réconcilier | ajouter --no-rebase |
| changer l'URL du remote | git remote set-url origin <url> |
Quel type de commit ?¶
| Situation | Message |
|---|---|
| premier commit | chore(project): initial commit |
| j'ajoute une fonctionnalité | feat(scope): ... |
| je corrige un bug | fix(scope): ... |
je modifie le .gitlab-ci.yml |
ci(scope): ... |
| je modifie le README | docs(readme): ... |
| j'ajoute des tests | test(scope): ... |
| je change une dépendance ou la config vite | build(scope): ... |
| je renomme/réorganise sans changer le comportement | refactor(scope): ... |
| je change l'api et ça casse l'ancienne | feat(api)!: ... (donc version majeure) |
Questions types (avec réponses)¶
1. Un job a uniquement rules: - if: '$CI_COMMIT_BRANCH == "main"' avec when: never. Quand tourne-t-il ?
Jamais: sur main la règle dit never, ailleurs aucune règle ne correspond. Si c'est le seul job, la pipeline ne peut même pas être créée.
2. Que se passe-t-il quand aucune règle rules ne correspond ?
Le job ne tourne pas (comme when: never).
3. Comment éviter deux pipelines (push + MR) pour le même commit ?
Un workflow qui accepte merge_request_event, refuse (never) un push sur une branche qui a une MR ouverte, et accepte les autres push de branche.
4. Comment connaître le nom de $CI_DEFAULT_BRANCH d'un dépôt ?
Settings > Repository > Branch defaults.
5. Quelle est la différence entre git fetch et git pull ?
fetch télécharge sans toucher aux fichiers (crée origin/main), pull = fetch + merge.
6. Pourquoi un tag ne part-il pas avec git push ?
Les tags sont poussés explicitement: git push origin v1.0.0 ou git push --tags.
7. Quel tag après un fix ? après un feat ? après un feat! ?
v1.0.0 devient v1.0.1 (patch), v1.1.0 (mineur), v2.0.0 (majeur).
8. Pourquoi image: est-il ignoré sur le runner de l'éval ?
Parce que c'est un runner shell: le job tourne directement sur la machine, sans conteneur.
9. Pourquoi ne peut-on pas faire sudo apt update dans un job de runner lancé en utilisateur normal ?
Il n'y a personne pour taper le mot de passe. Solution du cours: un utilisateur dédié avec NOPASSWD dans sudoers, qui enregistre et lance le runner.
10. Où mettre le mot de passe FTP ?
Dans Settings > CI/CD > Variables, utilisé comme $FTP_PASS. Jamais dans le yaml ni dans le dépôt.
11. Quelle est la différence entre cache et artifacts ?
cache accélère (dépendances), non garanti. artifacts transmet et conserve des fichiers produits (dist/), téléchargeables.
12. Que contient $CI_COMMIT_TAG dans une pipeline de merge request ?
Rien: il n'est défini que dans une pipeline déclenchée par un tag.
13. Pourquoi le fichier .env n'est-il pas versionné, et comment l'équipe ops fait-elle ?
Il contient des secrets (clés d'API). On versionne un .env.example sans valeurs, et les vraies valeurs sont fournies à l'environnement de build (par exemple en variables CI/CD, préfixées VITE_). En revanche, un fichier de config sans secret comme vite.config.js doit être versionné.