Projet : comment lancer un pipeline via l’API Gitlab ? (partie 2)
Rétrospective de la partie 1
Cet article est la deuxième partie du projet commencé ensembles le mois dernier. voici un petit résumé de la situation, nous avons :
- Une arborescence de code contenant notre index.html ainsi que nos fichiers de css et de js dans un dossier assets,
- un fichier index.html qui contient notre formulaire qui sera envoyé à Gitlab,
- un fichier styles.css qui contient nos styles de la page pour le rendre un peu plus sexy,
- un fichier js pour rendre la page dynamique (pour le moment, nous avons une alerte de confirmation et des messages de statuts seulement).
Vous êtes sensés avoir cette page :

Si vous n’avez pas lu cet article voici le lien, vous en aurez besoin pour la suite : https://codequeen.blog/2025/09/29/comment-lancer-un-pipeline-via-lapi-gitlab
La partie fonctionnelle
Petit point sur la partie fonctionnelle, je me rends compte que je n’ai pas détaillé dans la partie 1 comment l’application et le pipeline allaient fonctionner ensembles, oui honte sur moi. Faute avouée à moitié pardonnée, nous le ferons ici avant de continuer sur la suite de l’application.
Partons du principe que vous avez un projet de code avec un dossier tests contenu (tests unitaires, tests de régression automatisés… cela importe peu). ce projet est versionné sur Gitlab et fonctionne déjà.
Ce projet est déployé via un pipeline Gitlab et contient un ou plusieurs jobs de tests. Ces jobs lancent des commandes en ligne afin de lancer les tests et de générer des rapports concernant ceux ci.
Parce qu’un schéma vaut mieux qu’un long article, nous avons donc le fonctionnement suivant :

Maintenant que le fonctionnement est plus clair, commençons donc la partie du pipeline avant de reprendre le JS.
La partie Gitlab
Je pars du principe que vous avez déjà un pipeline fonctionnel sur votre projet, si ce n’est pas le cas je vous invite à lire l’article : https://codequeen.blog/2025/07/31/debuter-avec-gitlab-ci-cd-creer-son-premier-pipeline-devops-pas-a-pas.
De mon coté, les tests sont des tests de non régression avec l’outil Playwright, il est donc possible que vous deviez modifier l’image appelée ou les commandes de script, j’ai un dossier tests dans mon projet qui contient plusieurs fichiers ainsi que les configurations liées.
Nous allons modifier notre fichier .gitlab-ci.yml afin d’y ajouter notre étape de tests :
playwright_tests:
stage: test
image: mcr.microsoft.com/playwright:v1.50.1-jammy
script:
- npm ci
- npx playwright test
allow_failure: true
artifacts:
when: always
paths:
- playwright-report
expire_in: 1 day
when: manual
environment:
name: $CI_COMMIT_BRANCH
tags:
- $TAG
Ce pipeline se contente de lancer les tests du projet, de générer un rapport et de le stocker pendant 1 jour sur Gitlab. C’est un pipeline très simple qui peut être amélioré.
Le job est un job manuel, ainsi l’équipe fonctionnelle pourra le lancer à sa guise via notre application.
Attention, il est important que le pipeline se lance au moins une fois afin que le job de tests existe même s’il n’est pas lancé, sinon lors de nos appels API, nous ne pourrons pas le trouver et le lancer.
La partie JS
Commençons à implémenter les fonctions d’appels à l’API Gitlab, au total nous en utiliserons 4.
Les fonctions que nous allons coder se basent toutes sur la documentation officielle de Gitlab : Extend with GitLab | GitLab Docs.
Récupération du dernier pipeline crée
La première fonction sert à récupérer le dernier pipeline d’une branche :
async function getLastBranchPipeline(baseUrl, projectId, token, branchId) {
try {
const response = await fetch(`${baseUrl}/projects/${encodeURIComponent(projectId)}/pipelines?ref=${encodeURIComponent(branchId)}&per_page=1`, {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
});
if (!response.ok) {
displayMessage('error', "<p>❌ Erreur dans l'API GitLab...</p>");
}
const pipelines = await response.json();
if (Array.isArray(pipelines) && pipelines.length > 0) {
return pipelines[0].id;
} else {
displayMessage('error', "<p>❌ Aucun pipeline trouvé pour cette branche.</p>");
return '';
}
} catch (error) {
displayMessage('error', "<p>❌ Impossible de récupérer le dernier pipeline pour la branche.</p>");
return '';
}
}
Concrètement, la fonction fait un appel API a Gitlab pour récupérer les pipelines de la branche saisie avant de ne garder que le dernier, celui qui nous intéresse.
Il faut ensuite ajouter l’appel a notre fonction dans notre submitForm(), à la suite des autres comme ceci :
(async () => {
const pipelineId = await getLastBranchPipeline(BASE_URL, GITLAB_PROJECT_ID, GITLAB_TOKEN, environment);
console.log(pipelineId);
})();
Relancez le site, si la fonctionne marche bien vous devriez voir l’id du dernier pipeline lancé dans la console.
Récupération des jobs du pipeline récupéré
Une fois notre id de pipeline récupéré, nous allons ensuite récupérer nos jobs pour un pipeline. Cela nous permettra ensuite de filtrer sur le job qui nous intéresse.
La structure est identique à celle d’avant :
async function getPipelineJobsList(baseUrl, projectId, token, pipelineId) {
try {
const response = await fetch(`${baseUrl}/projects/${encodeURIComponent(projectId)}/pipelines/${encodeURIComponent(pipelineId)}/jobs`, {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
});
if (!response.ok) {
displayMessage('error', "<p>❌ Erreur dans l'API GitLab...</p>");
}
return response.json();
} catch (error) {
displayMessage('error', "<p>❌ Impossible de récupérer les jobs du pipeline.</p>");
return [];
}
}
Enfin, nous ajoutons cette seconde fonction à la fonction submitForm() sous la précédente. Une fois la liste des jobs du pipeline récupérés nous faisons un traitement afin de ne garder que l’id du job qui nous intéresses :
const jobs = await getPipelineJobsList(BASE_URL, GITLAB_PROJECT_ID, GITLAB_TOKEN, pipelineId);
console.log(jobs);
const job = Array.isArray(jobs) ? jobs.find(job => job.name === "playwright_tests") : null;
const JobId = job.id;
Afin de tester que cela fonctionne, on relance l’application. Nous avons maintenant en console l’environnement (la branche sélectionnée), l’id du pipeline ainsi qu’un tableau json de tous les jobs de ce pipeline avec leurs noms, les artifacts, le stage…
Lancement du job spécifique
Maintenant que nous avons notre Id de Job, nous pouvons faire un appel a l’API (attention, en POST celui ci) pour lancer le job manuellement :
async function launchJobById(baseUrl, projectId, token, jobId) {
try {
const response = await fetch(`${baseUrl}/projects/${encodeURIComponent(projectId)}/jobs/${encodeURIComponent(jobId)}/play`, {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
});
if (!response.ok) {
displayMessage('error', "<p>❌ Erreur dans l'API GitLab...</p>");
}
return response.json();
} catch (error) {
displayMessage('error', "<p>❌ Impossible de lancer le job.</p>");
return null;
}
}
Une fois la fonction appelée dans submitForm() et la page relancée votre pipeline job se lancera tout seul sur Gitlab, vous pourrez alors suivre son avancée directement sur l’IHM. L’application étant pour l’équipe fonctionnelle il faudra quand même penser a mettre à jour le statut du lancement sur notre page afin que l’équipe puisse suivre sans avoir a aller directement sur Gitlab.
await launchJobById(BASE_URL, GITLAB_PROJECT_ID, GITLAB_TOKEN, JobId);
Mise à jour de la page en temps réel
Notre derniere fonction à pour but de vérifier le statut de notre pipeline afin de mettre jour le statut de notre page. cette fonction se lance dans l’exemple toutes les minutes, le temps peut être adapté afin de ne pas faire trop d’appels, si l’on sait que le job prends 10 minutes, alors autant augmenter ce temps.
function watchPipelineStatus(baseUrl, projectId, token, jobId) {
const interval = setInterval(async () => {
try {
const response = await fetch(`${baseUrl}/projects/${encodeURIComponent(projectId)}/jobs/${encodeURIComponent(jobId)}`, {
method: "GET",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
});
if (!response.ok) {
displayMessage('error', "<p>❌ Erreur dans l'API GitLab...</p>");
}
const job = await response.json();
if (["success"].includes(job.status)) {
clearInterval(interval);
displayMessage('success', `<p>✅ Le job ${jobId} a réussi.</p>`);
return true;
} else if (["failed", "canceled"].includes(job.status)) {
clearInterval(interval);
displayMessage('error', `<p>❌ Le job ${jobId} a échoué. </p>`);
return true;
} else {
console.log(`Statut actuel du job ${jobId} : ${job.status}`);
}
} catch (error) {
displayMessage('error', "<p>❌ Erreur dans la récupération du status du job.</p>");
return false;
}
}, 60000); // 60000 ms = 1 minute
}
Enfin, ajoutons l’appel à cette fonction dans notre fonction submitForm() :
watchPipelineStatus(BASE_URL, GITLAB_PROJECT_ID, GITLAB_TOKEN, JobId);
Récapitulatif
Nous avons maintenant un simple site internet avec les fonctionnalités suivantes :
- Formulaire de choix d’un environnement,
- Gestion des statuts du lancement du job Gitlab lié à l’environnement en question,
- Récupération de l’environnement et lancement d’un job lié à celui ci automatiquement.
Ce projet est un projet très simple et rapide à implémenter, évidement il est possible de le rendre plus complet, de rajouter des fonctionnalités et de le personnaliser à volonté, avec cette base et la documentation de Gitlab, les possibilités sont vraiment nombreuses et intéressantes.
Si cet article vous plait, n’hésitez pas à commenter afin que j’en fasse plus dans ce genre la !


Laisser un commentaire