PrestaFlow en CI hors GitHub Actions : GitLab, Bitbucket, CircleCI, Jenkins
Décor
L’article 2 de la série a posé deux niveaux de CI :
- Niveau 1 — la CLI PrestaFlow dans un workflow, sans compte prestaflow.io, avec Docker pour lancer Flashlight à la main.
- Niveau 2 — l’intégration officielle qui gère Flashlight, la matrice, le commentaire PR/MR, et la synchro plateforme (report URL, historique, régressions visuelles).
Au moment où l’article 2 est paru, le niveau 2 n’existait que pour GitHub Actions. Ce n’est plus le cas : trois nouvelles intégrations officielles sont disponibles, chacune avec ses propres inputs et sa mécanique.
| Plateforme | Niveau 2 officiel | Référence |
|---|---|---|
| GitHub | Action | PrestaFlow/github-action@v2 |
| GitLab | CI/CD Component | gitlab.com/prestaflow/ci/prestaflow@v0.1.0 |
| Bitbucket | Pipe Docker | prestaflow/pipe-push:1.0.0 |
| CircleCI | Orb | prestaflow/prestaflow@1.0.0 |
| Jenkins | — (niveau 1 uniquement) | pipeline scripté |
Cette annexe donne les gabarits pour ces quatre plateformes, avec pour chacune le niveau 1 (autonome, sans compte) et le niveau 2 (intégration officielle) quand il existe.
Ce qui doit tourner, quel que soit le CI
Le workflow niveau 1 fait cinq choses, dans l’ordre :
git clonedu projet (implicite dans tout CI)- Installer PHP (typiquement 8.2) et Composer
composer install- Démarrer Flashlight en arrière-plan, attendre qu’il réponde en HTTP
- Lancer
./vendor/bin/prestaflow run tests/prestaflowavec les env vars pointant surhttp://localhost/
Toute la variation d’un CI à l’autre au niveau 1 concerne uniquement la syntaxe pour exprimer ces cinq étapes, plus les mécanismes de secrets et d’artifacts. Le niveau 2 remplace ces étapes par un appel à l’intégration officielle, qui les regroupe et ajoute la remontée vers la plateforme.
GitLab CI
Niveau 1 — CLI seule
Créez .gitlab-ci.yml à la racine :
stages:
- test
e2e:
stage: test
image: php:8.2-cli
services:
- name: prestashop/prestashop-flashlight:8.1.7
alias: prestashop
variables:
PRESTAFLOW_PS_VERSION: "8.1.7"
PRESTAFLOW_LOCALE: fr
PRESTAFLOW_FO_URL: http://prestashop/
PRESTAFLOW_BO_URL: http://prestashop/admin-dev/
PRESTAFLOW_BO_EMAIL: admin@prestashop.com
PRESTAFLOW_BO_PASSWD: prestashop
PRESTAFLOW_HEADLESS: "true"
before_script:
- apt-get update && apt-get install -y curl chromium libgd-dev unzip git
- docker-php-ext-install gd
- curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
- composer install --prefer-dist --no-progress
- for i in $(seq 1 60); do curl -sf http://prestashop/ > /dev/null && break; sleep 2; done
script:
- ./vendor/bin/prestaflow run tests/prestaflow
artifacts:
when: on_failure
paths:
- tests/prestaflow/reports/
- prestaflow/screens/errors/
expire_in: 1 week
Trois particularités GitLab :
services:permet de lancer un conteneur en side-car, accessible par son alias comme hostname (iciprestashop). Plus propre que ledocker run -dmanuel de GitHub Actions.image:de niveau job = le conteneur qui exécute le script. On prendphp:8.2-cliofficiel et on y ajoute Chromium + composer.artifacts:ne s’attache qu’on_failure— même pattern que leif: failure()de GitHub. Le rapport HTML et les captures d’erreur restent téléchargeables 7 jours.
Niveau 2 — CI/CD Component
Depuis la v0.1.0, PrestaFlow expose un component GitLab standard :
include:
- component: gitlab.com/prestaflow/ci/prestaflow@v0.1.0
inputs:
token: $PRESTAFLOW_TOKEN
project_id: pk_01ABCDEF
flashlight: "true"
ps_version: "9.0.0"
suites: "BackOffice,FrontOffice"
visual: "true"
mr_comment: "true"
Les inputs clés : token (variable masquée), project_id (Product Key pk_…), flashlight (bootstrap PS via Docker), ps_version, suites (filtre), visual (baselines + diffs), mr_comment, execute, upload_artifacts.
Deux env vars à configurer côté projet :
PRESTAFLOW_TOKEN— variable CI/CD masquée pour l’API.GITLAB_TOKEN— token GitLab avec scopeapipour poster les notes MR. LeCI_JOB_TOKENpar défaut ne peut pas commenter les MR, c’est le piège classique.
Le component publie un artifact prestaflow.env (format dotenv) exposant PRESTAFLOW_REPORT_ID, PRESTAFLOW_REPORT_URL, PRESTAFLOW_PASSED/FAILED/SKIPPED/TOTAL, PRESTAFLOW_DURATION_MS, PRESTAFLOW_STATUS. Un job downstream y accède via needs: [{job: prestaflow, artifacts: true}].
Matrice multi-versions PS avec parallel:matrix: :
test-ps:
parallel:
matrix:
- PS_VERSION: ["8.1.7", "9.0.0"]
variables:
ps_version: $PS_VERSION
Bitbucket Pipelines
Niveau 1 — CLI seule
Créez bitbucket-pipelines.yml :
image: php:8.2-cli
pipelines:
default:
- step:
name: E2E — PrestaShop 8.1.7
services:
- flashlight
script:
- apt-get update && apt-get install -y curl chromium libgd-dev unzip git
- docker-php-ext-install gd
- curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
- composer install --prefer-dist --no-progress
- for i in $(seq 1 60); do curl -sf http://localhost/ > /dev/null && break; sleep 2; done
- export PRESTAFLOW_FO_URL=http://localhost/
- export PRESTAFLOW_BO_URL=http://localhost/admin-dev/
- export PRESTAFLOW_BO_EMAIL=admin@prestashop.com
- export PRESTAFLOW_BO_PASSWD=prestashop
- export PRESTAFLOW_HEADLESS=true
- ./vendor/bin/prestaflow run tests/prestaflow
artifacts:
- tests/prestaflow/reports/**
- prestaflow/screens/errors/**
definitions:
services:
flashlight:
image: prestashop/prestashop-flashlight:8.1.7
Deux particularités Bitbucket :
- La syntaxe
services:se déclare dans un blocdefinitions:séparé et se référence dans lestep:par son nom. Les services partagent le réseau du step, donc on parle à Flashlight viahttp://localhost/— pas via un alias. - Les artefacts sont toujours produits, il n’existe pas de conditionnel natif
on_failure— on paie donc un peu plus de stockage. Alternative :&& exit 0 || (tar cf reports.tgz tests/prestaflow/reports/ && exit 1)pour un tar conditionnel dans le script.
Niveau 2 — Pipe officiel
Depuis la 1.0.0, PrestaFlow publie un pipe Docker sur Docker Hub :
image: php:8.3-cli
pipelines:
pull-requests:
'**':
- step:
name: PrestaFlow
services: [docker]
artifacts: [prestaflow.env]
script:
- pipe: docker://prestaflow/pipe-push:1.0.0
variables:
TOKEN: $PRESTAFLOW_TOKEN
PROJECT_ID: pk_01ABC...
FLASHLIGHT: 'true'
PS_VERSION: '9.0.0'
BITBUCKET_ACCESS_TOKEN: $PRESTAFLOW_BITBUCKET_TOKEN
- step:
name: Notify
script:
- . prestaflow.env
- echo "Report → $PRESTAFLOW_REPORT_URL"
Variables principales : TOKEN, PROJECT_ID, FLASHLIGHT, PS_VERSION, SUITES, VISUAL (défaut true), PR_COMMENT (auto), EXECUTE, FLASHLIGHT_MOUNT (auto/root/modules/themes), BITBUCKET_ACCESS_TOKEN pour les commentaires PR.
Deux points à noter :
services: [docker]est obligatoire dès queFLASHLIGHT=true— le pipe monte le sidecar MariaDB et le conteneur PS via le daemon Docker du runner.- Commentaires PR idempotents — le pipe insère un marqueur
<!-- prestaflow-run:<project-key> -->dans la note, ce qui lui permet de mettre à jour un commentaire existant plutôt que d’en ajouter un à chaque run. Rien à faire côté config.
Le prestaflow.env produit contient les mêmes variables que le component GitLab (PRESTAFLOW_REPORT_URL, PRESTAFLOW_STATUS, etc.) et se source dans un step suivant.
CircleCI
CircleCI a longtemps été le grand absent de cet inventaire. Il a maintenant son orb officiel prestaflow/prestaflow@1.0.0, publié en canal stable (le canal volatile reste dispo pour les fixes non-taggés).
L’orb expose un push all-in-one plus des commandes granulaires (flashlight, run-tests, visual-download, upload, comment-pr, set-outputs, install-deps) qu’on compose soi-même si besoin.
.circleci/config.yml minimal :
version: 2.1
orbs:
prestaflow: prestaflow/prestaflow@1.0.0
workflows:
test:
jobs:
- prestaflow/test:
project_id: pk_01ABCDEFGHIJKLMNOPQR10
flashlight: true
ps_version: "9.0.0"
context: prestaflow
Trois particularités CircleCI :
- Exécuteur
machineobligatoire dès qu’on active Flashlight —setup_remote_dockerne permet pas les bind mounts dont Flashlight a besoin. L’orb bascule automatiquement, mais gardez-le en tête pour vos surcoûts crédits. GITHUB_TOKENouBITBUCKET_ACCESS_TOKENà créer à la main — CircleCI n’injecte pas de token VCS par défaut. Sans ça, pas de commentaire PR (mais le run remonte quand même côté plateforme).- Outputs via
BASH_ENV— les variables (PRESTAFLOW_REPORT_URL, etc.) sont exportées dansBASH_ENVet dans unprestaflow.envartifact, plutôt qu’en outputs de step comme sur GitHub.
Jenkins (déclaratif)
Jenkins n’a pas d’intégration officielle — le niveau 2 y passe par un sh curl vers l’API prestaflow.io depuis un pipeline scripté (voir la fin de l’article). Le niveau 1 reste donc la voie normale.
Créez Jenkinsfile à la racine :
pipeline {
agent {
docker {
image 'php:8.2-cli'
args '--network host'
}
}
environment {
PRESTAFLOW_PS_VERSION = '8.1.7'
PRESTAFLOW_LOCALE = 'fr'
PRESTAFLOW_FO_URL = 'http://localhost/'
PRESTAFLOW_BO_URL = 'http://localhost/admin-dev/'
PRESTAFLOW_BO_EMAIL = 'admin@prestashop.com'
PRESTAFLOW_BO_PASSWD = credentials('prestashop-admin-passwd')
PRESTAFLOW_HEADLESS = 'true'
}
stages {
stage('Prepare') {
steps {
sh 'apt-get update && apt-get install -y curl chromium libgd-dev unzip git'
sh 'docker-php-ext-install gd'
sh 'curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer'
sh 'composer install --prefer-dist --no-progress'
}
}
stage('Start Flashlight') {
steps {
sh 'docker run -d --rm --name ps --network host prestashop/prestashop-flashlight:8.1.7'
sh 'for i in $(seq 1 60); do curl -sf http://localhost/ && break; sleep 2; done'
}
}
stage('Run PrestaFlow') {
steps {
sh './vendor/bin/prestaflow run tests/prestaflow'
}
}
}
post {
failure {
archiveArtifacts artifacts: 'tests/prestaflow/reports/**,prestaflow/screens/errors/**', allowEmptyArchive: true
}
always {
sh 'docker rm -f ps 2>/dev/null || true'
}
}
}
Trois particularités Jenkins :
- Docker-in-Docker requis — l’agent est un conteneur PHP, mais on lance Flashlight via un
docker runqui doit passer le socket Docker de l’host. C’est du DinD, à configurer côté Jenkins (mount de/var/run/docker.sock, sinon Cloud plugin type Kubernetes). credentials()— Jenkins Credentials Store fournit les secrets sous forme de variables d’environnement quand on les référence viacredentials(...). Plus verbeux mais plus explicite que les secrets GitHub/GitLab.post { always }garantit la stop du conteneur Flashlight même en cas d’échec, évitant les zombies sur le nœud.
Ce qui reste identique partout
Peu importe le CI et le niveau, les mêmes règles s’appliquent :
- Wait explicite après le boot Flashlight — 30 à 60 secondes. Sans quoi le premier
ittombe sur une boutique pas prête, avec une capture d’erreur inutile. - Env vars
PRESTAFLOW_*— mêmes noms, mêmes rôles, quelle que soit la plateforme. Le code de la lib ne connaît rien du CI qui l’exécute. - Artefacts sur échec — le rapport HTML dans
tests/prestaflow/reports/, les captures d’erreur dansprestaflow/screens/errors/. Les rendre téléchargeables est essentiel pour debug hors du CI. - Exit code non-nul de la CLI = job rouge. Ne pas court-circuiter avec un
|| truebien intentionné qui rendrait le CI aveugle.
Au niveau 2, les quatre intégrations officielles (Action, Component, Pipe, Orb) exposent les mêmes clés de sortie — PRESTAFLOW_REPORT_ID/URL/PASSED/FAILED/SKIPPED/TOTAL/DURATION_MS/STATUS — via le mécanisme natif de leur plateforme (step outputs, dotenv artifact, BASH_ENV). Le contrat côté downstream est stable, ce qui rend les workflows portables d’une plateforme à l’autre.
Le cas Jenkins : niveau 2 fait maison
Sans intégration officielle, deux options si vous êtes sur Jenkins et voulez la synchro plateforme :
- Rester au niveau 1 — vous avez le CI qui rougit sur les régressions fonctionnelles. Vous n’avez ni le commentaire PR agrégé, ni l’historique côté plateforme, ni les régressions visuelles synchronisées. C’est déjà utile.
- Faire soi-même le POST vers l’API prestaflow.io — la plateforme expose
POST /api/projects/{id}/runs(visible dans l’annexe cloud runs, badgeuploaded_via: api). Unshqui prend leresults.jsonproduit par PrestaFlow et le pousse viacurlavec lePRESTAFLOW_TOKEN. Le badgeapiest prévu pour ça — c’est exactement le canal utilisé par les intégrations officielles quand elles remontent leurs résultats.
Ce second cas justifierait à lui seul un article dédié (auth, retries, formatage, artifacts screenshots). Pour l’instant, on note l’option et on renvoie à la doc API.
Notes
Dans la Série Prestaflow — article 5 sur 14