From 624d0cdc1666f33c77433b95bd845115c7391d0e Mon Sep 17 00:00:00 2001
From: Fabrice Gangler <fabrice.gangler@adullact.org>
Date: Mon, 30 Dec 2024 12:04:54 +0100
Subject: [PATCH] ci: improve process to build and push all images to Gitlab
 container registry

---
 .gitlab/ci/Dockerfiles/10_build_all-images.sh |  21 ++++
 .../20_build_and-push_all-images.sh           |  23 ++++
 .gitlab/ci/Dockerfiles/30_push_all-images.sh  |  19 +++
 .gitlab/ci/Dockerfiles/README.md              |  38 ++++--
 .gitlab/ci/Dockerfiles/config_all-images.sh   |  10 ++
 .../Dockerfiles/config_gitlab-repository.sh   |   6 +
 .../Dockerfiles/lib/docker-all-images.lib.sh  |  79 +++++++++++++
 .../ci/Dockerfiles/lib/docker-image.lib.sh    |  45 ++++++++
 .../50_build_image_with-cache.sh              |  16 +++
 .../60_build_image_without-cache.sh           |  16 +++
 .../lib/symlink_source/70_push_image.sh       |  16 +++
 .../80_builld_and_push_image.sh               |  17 +++
 .../50_build_image_with-cache.sh              |   1 +
 .../60_build_image_without-cache.sh           |   1 +
 .../php-8.1_composer/70_push_image.sh         |   1 +
 .../80_builld_and_push_image.sh               |   1 +
 .../php-8.1_composer/config_docker-image.sh   |   7 ++
 .../50_build_image_with-cache.sh              |   1 +
 .../60_build_image_without-cache.sh           |   1 +
 .../php-8.2_composer/70_push_image.sh         |   1 +
 .../80_builld_and_push_image.sh               |   1 +
 .../php-8.2_composer/config_docker-image.sh   |   7 ++
 .../50_build_image_with-cache.sh              |   1 +
 .../60_build_image_without-cache.sh           |   1 +
 .../php-8.3_composer/70_push_image.sh         |   1 +
 .../80_builld_and_push_image.sh               |   1 +
 .../php-8.3_composer/config_docker-image.sh   |   7 ++
 .../50_build_image_with-cache.sh              |   1 +
 .../60_build_image_without-cache.sh           |   1 +
 .../php-8.4_composer/70_push_image.sh         |   1 +
 .../80_builld_and_push_image.sh               |   1 +
 .../php-8.4_composer/config_docker-image.sh   |   7 ++
 .../php.8.1_composer_phive/Dockerfile         | 108 ------------------
 .../php.8.1_composer_phive/README.md          |  53 ---------
 .gitlab/ci/config/shellcheckrc                |   1 +
 .gitlab/ci/job.linters.gitlab-ci.yml          |   2 +
 Makefile                                      |  24 +++-
 37 files changed, 363 insertions(+), 175 deletions(-)
 create mode 100755 .gitlab/ci/Dockerfiles/10_build_all-images.sh
 create mode 100755 .gitlab/ci/Dockerfiles/20_build_and-push_all-images.sh
 create mode 100755 .gitlab/ci/Dockerfiles/30_push_all-images.sh
 create mode 100644 .gitlab/ci/Dockerfiles/config_all-images.sh
 create mode 100644 .gitlab/ci/Dockerfiles/config_gitlab-repository.sh
 create mode 100644 .gitlab/ci/Dockerfiles/lib/docker-all-images.lib.sh
 create mode 100644 .gitlab/ci/Dockerfiles/lib/docker-image.lib.sh
 create mode 100755 .gitlab/ci/Dockerfiles/lib/symlink_source/50_build_image_with-cache.sh
 create mode 100755 .gitlab/ci/Dockerfiles/lib/symlink_source/60_build_image_without-cache.sh
 create mode 100755 .gitlab/ci/Dockerfiles/lib/symlink_source/70_push_image.sh
 create mode 100755 .gitlab/ci/Dockerfiles/lib/symlink_source/80_builld_and_push_image.sh
 create mode 120000 .gitlab/ci/Dockerfiles/php-8.1_composer/50_build_image_with-cache.sh
 create mode 120000 .gitlab/ci/Dockerfiles/php-8.1_composer/60_build_image_without-cache.sh
 create mode 120000 .gitlab/ci/Dockerfiles/php-8.1_composer/70_push_image.sh
 create mode 120000 .gitlab/ci/Dockerfiles/php-8.1_composer/80_builld_and_push_image.sh
 create mode 100644 .gitlab/ci/Dockerfiles/php-8.1_composer/config_docker-image.sh
 create mode 120000 .gitlab/ci/Dockerfiles/php-8.2_composer/50_build_image_with-cache.sh
 create mode 120000 .gitlab/ci/Dockerfiles/php-8.2_composer/60_build_image_without-cache.sh
 create mode 120000 .gitlab/ci/Dockerfiles/php-8.2_composer/70_push_image.sh
 create mode 120000 .gitlab/ci/Dockerfiles/php-8.2_composer/80_builld_and_push_image.sh
 create mode 100644 .gitlab/ci/Dockerfiles/php-8.2_composer/config_docker-image.sh
 create mode 120000 .gitlab/ci/Dockerfiles/php-8.3_composer/50_build_image_with-cache.sh
 create mode 120000 .gitlab/ci/Dockerfiles/php-8.3_composer/60_build_image_without-cache.sh
 create mode 120000 .gitlab/ci/Dockerfiles/php-8.3_composer/70_push_image.sh
 create mode 120000 .gitlab/ci/Dockerfiles/php-8.3_composer/80_builld_and_push_image.sh
 create mode 100644 .gitlab/ci/Dockerfiles/php-8.3_composer/config_docker-image.sh
 create mode 120000 .gitlab/ci/Dockerfiles/php-8.4_composer/50_build_image_with-cache.sh
 create mode 120000 .gitlab/ci/Dockerfiles/php-8.4_composer/60_build_image_without-cache.sh
 create mode 120000 .gitlab/ci/Dockerfiles/php-8.4_composer/70_push_image.sh
 create mode 120000 .gitlab/ci/Dockerfiles/php-8.4_composer/80_builld_and_push_image.sh
 create mode 100644 .gitlab/ci/Dockerfiles/php-8.4_composer/config_docker-image.sh
 delete mode 100644 .gitlab/ci/Dockerfiles/php.8.1_composer_phive/Dockerfile
 delete mode 100644 .gitlab/ci/Dockerfiles/php.8.1_composer_phive/README.md
 create mode 100644 .gitlab/ci/config/shellcheckrc

diff --git a/.gitlab/ci/Dockerfiles/10_build_all-images.sh b/.gitlab/ci/Dockerfiles/10_build_all-images.sh
new file mode 100755
index 0000000..c7b9051
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/10_build_all-images.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+##############################################################################################
+set   -o errexit    # enable exit if one of command fails
+set   -o pipefail   # enable exit if one of pipe command fails
+set   -o nounset    # enable exit if any of variables is not set
+# set   -o xtrace     # all executed commands are printed to the terminal
+##############################################################################################
+source config_all-images.sh
+source config_gitlab-repository.sh
+source lib/docker-all-images.lib.sh
+source lib/docker-image.lib.sh
+##############################################################################################
+trap   handle_error ERR  # Set the error handler function
+trap   handle_exit  EXIT # Set the exit handler function
+##############################################################################################
+(check_all_images_configuration) # executed in a subshell
+(remove_all_images)              # executed in a subshell
+(build_all_images)               # executed in a subshell
+(resume_build)                   # executed in a subshell
+##############################################################################################
+exit 0
diff --git a/.gitlab/ci/Dockerfiles/20_build_and-push_all-images.sh b/.gitlab/ci/Dockerfiles/20_build_and-push_all-images.sh
new file mode 100755
index 0000000..d8b3180
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/20_build_and-push_all-images.sh
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+##############################################################################################
+set   -o errexit    # enable exit if one of command fails
+set   -o pipefail   # enable exit if one of pipe command fails
+set   -o nounset    # enable exit if any of variables is not set
+# set   -o xtrace     # all executed commands are printed to the terminal
+##############################################################################################
+source config_all-images.sh
+source config_gitlab-repository.sh
+source lib/docker-all-images.lib.sh
+source lib/docker-image.lib.sh
+##############################################################################################
+trap   handle_error ERR  # Set the error handler function
+trap   handle_exit  EXIT # Set the exit handler function
+##############################################################################################
+(check_all_images_configuration) # executed in a subshell
+(remove_all_images)              # executed in a subshell
+(build_all_images)               # executed in a subshell
+(resume_build)                   # executed in a subshell
+(push_all_imagess)               # executed in a subshell
+(resume_build)                   # executed in a subshell
+##############################################################################################
+exit 0
diff --git a/.gitlab/ci/Dockerfiles/30_push_all-images.sh b/.gitlab/ci/Dockerfiles/30_push_all-images.sh
new file mode 100755
index 0000000..5a6e47c
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/30_push_all-images.sh
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+##############################################################################################
+set   -o errexit    # enable exit if one of command fails
+set   -o pipefail   # enable exit if one of pipe command fails
+set   -o nounset    # enable exit if any of variables is not set
+# set   -o xtrace     # all executed commands are printed to the terminal
+##############################################################################################
+source config_all-images.sh
+source config_gitlab-repository.sh
+source lib/docker-all-images.lib.sh
+source lib/docker-image.lib.sh
+##############################################################################################
+trap   handle_error ERR  # Set the error handler function
+trap   handle_exit  EXIT # Set the exit handler function
+##############################################################################################
+(push_all_imagess)               # executed in a subshell
+(resume_build)                   # executed in a subshell
+##############################################################################################
+exit 0
diff --git a/.gitlab/ci/Dockerfiles/README.md b/.gitlab/ci/Dockerfiles/README.md
index d1d7811..c088ac1 100644
--- a/.gitlab/ci/Dockerfiles/README.md
+++ b/.gitlab/ci/Dockerfiles/README.md
@@ -1,10 +1,32 @@
-# CI ~ Docker images of prerequisites
+# CI - Docker images of prerequisites
+
+## Docker images
 
 Docker images of prerequisites usign by **Gitlab CI**:
-- [PHP 8.1, Composer and Phive](./php.8.1_composer_phive/)
-- [PHP 8.2, Composer and Phive](./php.8.2_composer_phive/)
-- [PHP 8.3, Composer and Phive](./php.8.3_composer_phive/)
-- [Ubuntu 22.04, PHP 8.1 (Ubuntu packages), Composer, Symfony-CLI, Xdebug and Make](./php.8.1_composer/)
-- [Ubuntu 22.04, PHP 8.2 (ppa:ondrej/php), Composer, Symfony-CLI, Xdebug and Make](./php.8.2_composer/)
-- [Ubuntu 24.04, PHP 8.3 (Ubuntu packages), Composer, Symfony-CLI, Xdebug and Make](./php.8.3_composer/)
-- [Ubuntu 24.04, PHP 8.4 (ppa:ondrej/php), Composer, Symfony-CLI, Xdebug and Make](./php.8.4_composer/)
+- [Ubuntu 22.04, PHP 8.1 (Ubuntu packages), Composer, Symfony-CLI, Xdebug and Make](php-8.1_composer/)
+- [Ubuntu 22.04, PHP 8.2 (ppa:ondrej/php), Composer, Symfony-CLI, Xdebug and Make](php-8.2_composer/)
+- [Ubuntu 24.04, PHP 8.3 (Ubuntu packages), Composer, Symfony-CLI, Xdebug and Make](php-8.3_composer/)
+- [Ubuntu 24.04, PHP 8.4 (ppa:ondrej/php), Composer, Symfony-CLI, Xdebug and Make](php-8.4_composer/)
+
+## How to build and push all images to Gitlab container registry?
+
+### Configuration
+
+see: 
+- [`config_all-images.sh`](config_all-images.sh)
+- [`config_gitlab-repository.sh`](config_gitlab-repository.sh)
+
+
+### Build all images
+
+```bash
+cd .gitlab/ci/Dockerfiles
+./10_build_all-images.sh
+```
+
+### Push all images to Gitlab container registry
+
+```bash
+cd .gitlab/ci/Dockerfiles
+./30_push_all-images.sh
+```
diff --git a/.gitlab/ci/Dockerfiles/config_all-images.sh b/.gitlab/ci/Dockerfiles/config_all-images.sh
new file mode 100644
index 0000000..50acb82
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/config_all-images.sh
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+# shellcheck disable=SC2034  # Don't warn about unused variables in this file
+##############################################################################################
+DOCKERFILE_DIRECTORIES=(
+    'php-8.1_composer'
+    'php-8.2_composer'
+    'php-8.3_composer'
+    'php-8.4_composer'
+)
+##############################################################################################
diff --git a/.gitlab/ci/Dockerfiles/config_gitlab-repository.sh b/.gitlab/ci/Dockerfiles/config_gitlab-repository.sh
new file mode 100644
index 0000000..1fc881a
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/config_gitlab-repository.sh
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+# shellcheck disable=SC2034  # Don't warn about unused variables in this file
+##############################################################################################
+GITLAB_URI="gitlab.adullact.net:4567"
+GITLAB_REPOSITORY="comptoir/comptoir-du-libre"
+##############################################################################################
diff --git a/.gitlab/ci/Dockerfiles/lib/docker-all-images.lib.sh b/.gitlab/ci/Dockerfiles/lib/docker-all-images.lib.sh
new file mode 100644
index 0000000..3f7775a
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/lib/docker-all-images.lib.sh
@@ -0,0 +1,79 @@
+#!/usr/bin/env bash
+##############################################################################################
+# shellcheck disable=SC2317  # Don't warn about unreachable commands in this file
+##############################################################################################
+
+# Check all images configuration
+check_all_images_configuration () {
+    echo  ""
+    echo  "-------------- CHECK CONFIGURATION -------------------------"
+    for DOCKERFILE_DIRECTORY in "${DOCKERFILE_DIRECTORIES[@]}"
+    do
+         (    # executed in a subshell
+              echo  "---> Check [ ${DOCKERFILE_DIRECTORY} ] configuration"
+              cd "${DOCKERFILE_DIRECTORY}" || exit 255
+              source "config_docker-image.sh"
+              if [ "${DOCKERFILE_DIRECTORY}" != "${DOCKER_IMAGE_NAME}" ]; then
+                  echo "EROOR :"
+                  echo "[ ${DOCKERFILE_DIRECTORY} ] directory and [ ${DOCKER_IMAGE_NAME} ] image are not identicatl."
+                  false
+              fi
+         )
+    done
+}
+
+# Remove all images
+remove_all_images () {
+    echo  ""
+    echo  "-------------- REMOVE ALL IMAGES -------------------------"
+    for DOCKERFILE_DIRECTORY in "${DOCKERFILE_DIRECTORIES[@]}"
+    do
+        echo  "---> Remove [ ${DOCKERFILE_DIRECTORY} ] image"
+        cd "${DOCKERFILE_DIRECTORY}" || exit 255
+        source "config_docker-image.sh"
+        remove_docker-image && cd .. || exit 255
+    done
+}
+
+
+# Build all images
+build_all_images () {
+    echo  ""
+    echo  "-------------- BUILD ALL IMAGES -------------------------"
+    for DOCKERFILE_DIRECTORY in "${DOCKERFILE_DIRECTORIES[@]}"
+    do
+        echo  ""
+        echo  "-------------> Build [ ${DOCKERFILE_DIRECTORY} ] image"
+        cd "${DOCKERFILE_DIRECTORY}" || exit 255
+        source "config_docker-image.sh"
+        build_docker-image_without-cache && cd .. || exit 255
+    done
+}
+
+
+# Push all images
+push_all_imagess () {
+    echo  ""
+    echo  "-------------- PUSH ALL IMAGES -------------------------"
+    for DOCKERFILE_DIRECTORY in "${DOCKERFILE_DIRECTORIES[@]}"
+    do
+        echo  ""
+        echo  "-------------> Push [ ${DOCKERFILE_DIRECTORY} ] image"
+        cd "${DOCKERFILE_DIRECTORY}" || exit 255
+        source "config_docker-image.sh"
+        push_docker-image && cd .. || exit 255
+    done
+}
+
+resume_build () {
+    echo  ""
+    echo  "-------------- RESUME BUILD -------------------------"
+    for DOCKERFILE_DIRECTORY in "${DOCKERFILE_DIRECTORIES[@]}"
+    do
+        docker images | grep "${DOCKERFILE_DIRECTORY}" || (
+            echo "ERROR: Image [ ${DOCKERFILE_DIRECTORY} ] does not exist" && false
+        )
+    done
+}
+
+
diff --git a/.gitlab/ci/Dockerfiles/lib/docker-image.lib.sh b/.gitlab/ci/Dockerfiles/lib/docker-image.lib.sh
new file mode 100644
index 0000000..a980f0b
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/lib/docker-image.lib.sh
@@ -0,0 +1,45 @@
+#!/usr/bin/env bash
+##############################################################################################
+# shellcheck disable=SC2317  # Don't warn about unreachable commands in this file
+##############################################################################################
+
+# Function to handle errors
+handle_error() {
+    echo "----------------------------------------------------------"
+    echo "----> FAIL : an ERROR occurred"
+    exit 1
+}
+
+# Function to handle script exit
+handle_exit() {
+    echo "----------------------------------------------------------"
+    echo "----> EXIT : script interrupted"
+    echo ""
+    exit 255
+}
+
+# Buil Docker image with cache (useful for debugging)
+build_docker-image_with-cache () {
+# docker images | grep "${DOCKER_IMAGE_NAME}"
+  docker build --progress plain -t "${GITLAB_URI}/${GITLAB_REPOSITORY}/${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_VERSION}" .
+  docker images | grep "${DOCKER_IMAGE_NAME}"
+}
+
+# Build Docker image without cache (must be used to push a new Docker image or update Docker image)
+build_docker-image_without-cache () {
+  docker pull "${DOCKER_IMAGE_FROM}"
+  docker image remove "${GITLAB_URI}/${GITLAB_REPOSITORY}/${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_VERSION}"  || true
+  docker build --no-cache --progress plain -t "${GITLAB_URI}/${GITLAB_REPOSITORY}/${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_VERSION}" .
+  docker images | grep "${DOCKER_IMAGE_NAME}"
+}
+
+# Remvoe Docker image
+remove_docker-image () {
+  docker image remove "${GITLAB_URI}/${GITLAB_REPOSITORY}/${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_VERSION}"  || true
+}
+
+# Login to Gitlab and push image to Gitlab container registry
+push_docker-image () {
+  docker login "${GITLAB_URI}"
+  docker push "${GITLAB_URI}/${GITLAB_REPOSITORY}/${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_VERSION}"
+}
\ No newline at end of file
diff --git a/.gitlab/ci/Dockerfiles/lib/symlink_source/50_build_image_with-cache.sh b/.gitlab/ci/Dockerfiles/lib/symlink_source/50_build_image_with-cache.sh
new file mode 100755
index 0000000..e263f1f
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/lib/symlink_source/50_build_image_with-cache.sh
@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+##############################################################################################
+set   -o errexit    # enable exit if one of command fails
+set   -o pipefail   # enable exit if one of pipe command fails
+set   -o nounset    # enable exit if any of variables is not set
+# set   -o xtrace     # all executed commands are printed to the terminal
+##############################################################################################
+source ../lib/docker-image.lib.sh
+source ../config_gitlab-repository.sh
+source config_docker-image.sh
+##############################################################################################
+trap   handle_error ERR  # Set the error handler function
+trap   handle_exit  EXIT # Set the exit handler function
+##############################################################################################
+build_docker-image_with-cache
+##############################################################################################
diff --git a/.gitlab/ci/Dockerfiles/lib/symlink_source/60_build_image_without-cache.sh b/.gitlab/ci/Dockerfiles/lib/symlink_source/60_build_image_without-cache.sh
new file mode 100755
index 0000000..6830d17
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/lib/symlink_source/60_build_image_without-cache.sh
@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+##############################################################################################
+set   -o errexit    # enable exit if one of command fails
+set   -o pipefail   # enable exit if one of pipe command fails
+set   -o nounset    # enable exit if any of variables is not set
+# set   -o xtrace     # all executed commands are printed to the terminal
+##############################################################################################
+source ../lib/docker-image.lib.sh
+source ../config_gitlab-repository.sh
+source config_docker-image.sh
+##############################################################################################
+trap   handle_error ERR  # Set the error handler function
+trap   handle_exit  EXIT # Set the exit handler function
+##############################################################################################
+build_docker-image_without-cache
+##############################################################################################
\ No newline at end of file
diff --git a/.gitlab/ci/Dockerfiles/lib/symlink_source/70_push_image.sh b/.gitlab/ci/Dockerfiles/lib/symlink_source/70_push_image.sh
new file mode 100755
index 0000000..8af7d8b
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/lib/symlink_source/70_push_image.sh
@@ -0,0 +1,16 @@
+#!/usr/bin/env bash
+##############################################################################################
+set   -o errexit    # enable exit if one of command fails
+set   -o pipefail   # enable exit if one of pipe command fails
+set   -o nounset    # enable exit if any of variables is not set
+# set   -o xtrace     # all executed commands are printed to the terminal
+##############################################################################################
+source ../lib/docker-image.lib.sh
+source ../config_gitlab-repository.sh
+source config_docker-image.sh
+##############################################################################################
+trap   handle_error ERR  # Set the error handler function
+trap   handle_exit  EXIT # Set the exit handler function
+##############################################################################################
+push_docker-image
+##############################################################################################
diff --git a/.gitlab/ci/Dockerfiles/lib/symlink_source/80_builld_and_push_image.sh b/.gitlab/ci/Dockerfiles/lib/symlink_source/80_builld_and_push_image.sh
new file mode 100755
index 0000000..8e038cd
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/lib/symlink_source/80_builld_and_push_image.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+##############################################################################################
+set   -o errexit    # enable exit if one of command fails
+set   -o pipefail   # enable exit if one of pipe command fails
+set   -o nounset    # enable exit if any of variables is not set
+# set   -o xtrace     # all executed commands are printed to the terminal
+##############################################################################################
+source ../lib/docker-image.lib.sh
+source ../config_gitlab-repository.sh
+source config_docker-image.sh
+##############################################################################################
+trap   handle_error ERR  # Set the error handler function
+trap   handle_exit  EXIT # Set the exit handler function
+##############################################################################################
+build_docker-image_without-cache
+push_docker-image
+##############################################################################################
diff --git a/.gitlab/ci/Dockerfiles/php-8.1_composer/50_build_image_with-cache.sh b/.gitlab/ci/Dockerfiles/php-8.1_composer/50_build_image_with-cache.sh
new file mode 120000
index 0000000..6cc2449
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/php-8.1_composer/50_build_image_with-cache.sh
@@ -0,0 +1 @@
+../lib/symlink_source/50_build_image_with-cache.sh
\ No newline at end of file
diff --git a/.gitlab/ci/Dockerfiles/php-8.1_composer/60_build_image_without-cache.sh b/.gitlab/ci/Dockerfiles/php-8.1_composer/60_build_image_without-cache.sh
new file mode 120000
index 0000000..6663129
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/php-8.1_composer/60_build_image_without-cache.sh
@@ -0,0 +1 @@
+../lib/symlink_source/60_build_image_without-cache.sh
\ No newline at end of file
diff --git a/.gitlab/ci/Dockerfiles/php-8.1_composer/70_push_image.sh b/.gitlab/ci/Dockerfiles/php-8.1_composer/70_push_image.sh
new file mode 120000
index 0000000..7d8673b
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/php-8.1_composer/70_push_image.sh
@@ -0,0 +1 @@
+../lib/symlink_source/70_push_image.sh
\ No newline at end of file
diff --git a/.gitlab/ci/Dockerfiles/php-8.1_composer/80_builld_and_push_image.sh b/.gitlab/ci/Dockerfiles/php-8.1_composer/80_builld_and_push_image.sh
new file mode 120000
index 0000000..f361fbd
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/php-8.1_composer/80_builld_and_push_image.sh
@@ -0,0 +1 @@
+../lib/symlink_source/80_builld_and_push_image.sh
\ No newline at end of file
diff --git a/.gitlab/ci/Dockerfiles/php-8.1_composer/config_docker-image.sh b/.gitlab/ci/Dockerfiles/php-8.1_composer/config_docker-image.sh
new file mode 100644
index 0000000..4bd5052
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/php-8.1_composer/config_docker-image.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+# shellcheck disable=SC2034  # Don't warn about unused variables in this file
+##############################################################################################
+DOCKER_IMAGE_FROM="ubuntu:22.04"
+DOCKER_IMAGE_NAME="php-8.1_composer"
+DOCKER_IMAGE_VERSION="1.0.0" # must be identical to LABEL.version in Dockerfile
+##############################################################################################
diff --git a/.gitlab/ci/Dockerfiles/php-8.2_composer/50_build_image_with-cache.sh b/.gitlab/ci/Dockerfiles/php-8.2_composer/50_build_image_with-cache.sh
new file mode 120000
index 0000000..6cc2449
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/php-8.2_composer/50_build_image_with-cache.sh
@@ -0,0 +1 @@
+../lib/symlink_source/50_build_image_with-cache.sh
\ No newline at end of file
diff --git a/.gitlab/ci/Dockerfiles/php-8.2_composer/60_build_image_without-cache.sh b/.gitlab/ci/Dockerfiles/php-8.2_composer/60_build_image_without-cache.sh
new file mode 120000
index 0000000..6663129
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/php-8.2_composer/60_build_image_without-cache.sh
@@ -0,0 +1 @@
+../lib/symlink_source/60_build_image_without-cache.sh
\ No newline at end of file
diff --git a/.gitlab/ci/Dockerfiles/php-8.2_composer/70_push_image.sh b/.gitlab/ci/Dockerfiles/php-8.2_composer/70_push_image.sh
new file mode 120000
index 0000000..7d8673b
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/php-8.2_composer/70_push_image.sh
@@ -0,0 +1 @@
+../lib/symlink_source/70_push_image.sh
\ No newline at end of file
diff --git a/.gitlab/ci/Dockerfiles/php-8.2_composer/80_builld_and_push_image.sh b/.gitlab/ci/Dockerfiles/php-8.2_composer/80_builld_and_push_image.sh
new file mode 120000
index 0000000..f361fbd
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/php-8.2_composer/80_builld_and_push_image.sh
@@ -0,0 +1 @@
+../lib/symlink_source/80_builld_and_push_image.sh
\ No newline at end of file
diff --git a/.gitlab/ci/Dockerfiles/php-8.2_composer/config_docker-image.sh b/.gitlab/ci/Dockerfiles/php-8.2_composer/config_docker-image.sh
new file mode 100644
index 0000000..85210c7
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/php-8.2_composer/config_docker-image.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+# shellcheck disable=SC2034  # Don't warn about unused variables in this file
+##############################################################################################
+DOCKER_IMAGE_FROM="ubuntu:22.04"
+DOCKER_IMAGE_NAME="php-8.2_composer"
+DOCKER_IMAGE_VERSION="1.0.0" # must be identical to LABEL.version in Dockerfile
+##############################################################################################
diff --git a/.gitlab/ci/Dockerfiles/php-8.3_composer/50_build_image_with-cache.sh b/.gitlab/ci/Dockerfiles/php-8.3_composer/50_build_image_with-cache.sh
new file mode 120000
index 0000000..6cc2449
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/php-8.3_composer/50_build_image_with-cache.sh
@@ -0,0 +1 @@
+../lib/symlink_source/50_build_image_with-cache.sh
\ No newline at end of file
diff --git a/.gitlab/ci/Dockerfiles/php-8.3_composer/60_build_image_without-cache.sh b/.gitlab/ci/Dockerfiles/php-8.3_composer/60_build_image_without-cache.sh
new file mode 120000
index 0000000..6663129
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/php-8.3_composer/60_build_image_without-cache.sh
@@ -0,0 +1 @@
+../lib/symlink_source/60_build_image_without-cache.sh
\ No newline at end of file
diff --git a/.gitlab/ci/Dockerfiles/php-8.3_composer/70_push_image.sh b/.gitlab/ci/Dockerfiles/php-8.3_composer/70_push_image.sh
new file mode 120000
index 0000000..7d8673b
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/php-8.3_composer/70_push_image.sh
@@ -0,0 +1 @@
+../lib/symlink_source/70_push_image.sh
\ No newline at end of file
diff --git a/.gitlab/ci/Dockerfiles/php-8.3_composer/80_builld_and_push_image.sh b/.gitlab/ci/Dockerfiles/php-8.3_composer/80_builld_and_push_image.sh
new file mode 120000
index 0000000..f361fbd
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/php-8.3_composer/80_builld_and_push_image.sh
@@ -0,0 +1 @@
+../lib/symlink_source/80_builld_and_push_image.sh
\ No newline at end of file
diff --git a/.gitlab/ci/Dockerfiles/php-8.3_composer/config_docker-image.sh b/.gitlab/ci/Dockerfiles/php-8.3_composer/config_docker-image.sh
new file mode 100644
index 0000000..42c07a6
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/php-8.3_composer/config_docker-image.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+# shellcheck disable=SC2034  # Don't warn about unused variables in this file
+##############################################################################################
+DOCKER_IMAGE_FROM="ubuntu:24.04"
+DOCKER_IMAGE_NAME="php-8.3_composer"
+DOCKER_IMAGE_VERSION="1.0.0" # must be identical to LABEL.version in Dockerfile
+##############################################################################################
diff --git a/.gitlab/ci/Dockerfiles/php-8.4_composer/50_build_image_with-cache.sh b/.gitlab/ci/Dockerfiles/php-8.4_composer/50_build_image_with-cache.sh
new file mode 120000
index 0000000..6cc2449
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/php-8.4_composer/50_build_image_with-cache.sh
@@ -0,0 +1 @@
+../lib/symlink_source/50_build_image_with-cache.sh
\ No newline at end of file
diff --git a/.gitlab/ci/Dockerfiles/php-8.4_composer/60_build_image_without-cache.sh b/.gitlab/ci/Dockerfiles/php-8.4_composer/60_build_image_without-cache.sh
new file mode 120000
index 0000000..6663129
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/php-8.4_composer/60_build_image_without-cache.sh
@@ -0,0 +1 @@
+../lib/symlink_source/60_build_image_without-cache.sh
\ No newline at end of file
diff --git a/.gitlab/ci/Dockerfiles/php-8.4_composer/70_push_image.sh b/.gitlab/ci/Dockerfiles/php-8.4_composer/70_push_image.sh
new file mode 120000
index 0000000..7d8673b
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/php-8.4_composer/70_push_image.sh
@@ -0,0 +1 @@
+../lib/symlink_source/70_push_image.sh
\ No newline at end of file
diff --git a/.gitlab/ci/Dockerfiles/php-8.4_composer/80_builld_and_push_image.sh b/.gitlab/ci/Dockerfiles/php-8.4_composer/80_builld_and_push_image.sh
new file mode 120000
index 0000000..f361fbd
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/php-8.4_composer/80_builld_and_push_image.sh
@@ -0,0 +1 @@
+../lib/symlink_source/80_builld_and_push_image.sh
\ No newline at end of file
diff --git a/.gitlab/ci/Dockerfiles/php-8.4_composer/config_docker-image.sh b/.gitlab/ci/Dockerfiles/php-8.4_composer/config_docker-image.sh
new file mode 100644
index 0000000..06cd6b2
--- /dev/null
+++ b/.gitlab/ci/Dockerfiles/php-8.4_composer/config_docker-image.sh
@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+# shellcheck disable=SC2034  # Don't warn about unused variables in this file
+##############################################################################################
+DOCKER_IMAGE_FROM="ubuntu:24.04"
+DOCKER_IMAGE_NAME="php-8.4_composer"
+DOCKER_IMAGE_VERSION="1.0.0" # must be identical to LABEL.version in Dockerfile
+##############################################################################################
diff --git a/.gitlab/ci/Dockerfiles/php.8.1_composer_phive/Dockerfile b/.gitlab/ci/Dockerfiles/php.8.1_composer_phive/Dockerfile
deleted file mode 100644
index e56296d..0000000
--- a/.gitlab/ci/Dockerfiles/php.8.1_composer_phive/Dockerfile
+++ /dev/null
@@ -1,108 +0,0 @@
-FROM ubuntu:22.04
-
-# System prerequisites
-RUN apt-get update                           && \
-    DEBIAN_FRONTEND=noninteractive              \
-    apt-get -y --no-install-recommends          \
-            install git                         \
-                    make                        \
-                    gpg-agent                   \
-                    software-properties-common  \
-                    ca-certificates             \
-                    curl                        \
-                    zip                         \
-                    unzip                       \
-                    gpg                      && \
-    rm -rf /var/lib/apt/lists/*
-
-# Allow to use another version of PHP than Ubuntu PHP version
-# RUN add-apt-repository ppa:ondrej/php
-
-# Webapp prerequisites - Install PHP and PHP extensions
-RUN apt-get update                           && \
-    DEBIAN_FRONTEND=noninteractive              \
-    apt-get -y --no-install-recommends          \
-            install php8.1                      \
-                    php8.1-bcmath               \
-                    php8.1-curl                 \
-                    php8.1-intl                 \
-                    php8.1-mbstring             \
-                    php8.1-pgsql                \
-                    php8.1-xml                  \
-                    php8.1-zip               && \
-    rm -rf /var/lib/apt/lists/*
-
-# QA prerequisites - Install PHIVE
-RUN curl -sSL https://phar.io/releases/phive.phar --output phive.phar         && \
-    chmod +x phive.phar                                                       && \
-    mv -v phive.phar /usr/local/bin/phive                                     && \
-    phive --version
-
-# Webapp prerequisites - Install COMPOSER
-RUN curl -sSL https://getcomposer.org/installer --output composer-setup.php     && \
-    php -r "if (hash_file('sha384', 'composer-setup.php') === 'dac665fdc30fdd8ec78b38b9800061b4150413ff2e3b6f88543c636f7cd84f6db9189d43a81e5503cda447da73c7e5b6') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" && \
-    php composer-setup.php                                                      && \
-    rm -v composer-setup.php                                                    && \
-    chmod +x composer.phar                                                      && \
-    mv -v composer.phar /usr/local/bin/composer                                 && \
-    composer  -V
-
-# QA prerequisites - Install Symfony CLI
-SHELL ["/bin/bash", "-o", "pipefail", "-c"]
-RUN curl -sS https://get.symfony.com/cli/installer | /bin/bash  && \
-    mv /root/.symfony5/bin/symfony /usr/local/bin/symfony       && \
-    symfony -V
-
-# Caching of all PHP dependencies declared in composer.json files
-WORKDIR "/php/"
-RUN REPO=https://gitlab.adullact.net/adullact/pki/tajine.git        && \
-    pwd                                                             && \
-    git clone ${REPO}                                               && \
-    cd tajine/                                                      && \
-    phive install  --force-accept-unsigned                             \
-                   --trust-gpg-keys                                    \
-661E97400F658E25,96141E4421A9B0D5,033E5F8D801A2F8D,F4D32E2C9343B2AE,B8F640134AB1782E,AA36B9960B5B823D,C5095986493B4AA0,8101FB57DD8130F0,95DE904AB800754A11D80B605E6DDE998AB73B8E,4AA394086372C20A,9093F8B32E4815AA,51C67305FFC2E5C0,E82B2FB314E9906E,12CE0F1D262429A5  && \
-    cd webapp/                                                  && \
-    composer install --no-progress                                     \
-                     --no-suggest                                      \
-                     --no-interaction                                  \
-                     --no-scripts                                   && \
-    rm -rf /php/tajine/
-    #        661E97400F658E25  ---> captainhook
-    #        96141E4421A9B0D5  ---> churn
-    #        033E5F8D801A2F8D  ---> composer-require-checker
-    #        F4D32E2C9343B2AE  ---> composer-unused
-    #        B8F640134AB1782E  ---> deptrac
-    #        AA36B9960B5B823D  ---> grumphp
-    #        C5095986493B4AA0  ---> infection
-    #        8101FB57DD8130F0  ---> phan
-    #        95DE904AB800754A11D80B605E6DDE998AB73B8E  ---> phpcbf, phpcs
-    #        4AA394086372C20A  ---> phpcpd, phploc, phpunit
-    #        9093F8B32E4815AA  ---> phpmd
-    #        51C67305FFC2E5C0  ---> phpstan
-    #        E82B2FB314E9906E  ---> php-cs-fixer
-    #                          ---> php-parallel-lint  ---> TODO use --force-accept-unsigned option
-    #        12CE0F1D262429A5  ---> psalm
-
-# CI prerequisites - Install PHP extensions mandatory to use Infection tool
-RUN apt-get update                           && \
-    DEBIAN_FRONTEND=noninteractive              \
-    apt-get -y --no-install-recommends          \
-            install php8.1-xdebug            && \
-    rm -rf /var/lib/apt/lists/*
-
-# Check cache
-RUN ls -l  /root/.phive/phars/       && \
-    du -hs /root/.phive/phars/       && \
-    du -hs  /root/.cache/composer/
-
-# Display software versions
-RUN echo "-------------------" && php --version      && \
-    echo "-------------------" && composer  -V       && \
-    echo "-------------------" && phive --version    && \
-    echo "-------------------" && symfony -V         && \
-    echo "-------------------"
-
-# Set Docker LABEL
-LABEL version="1.0.0"  \
-      description="Prerequisites for PHP 8.1, Composer, Phive, Symfony-CLI, Xdebug and Make"
diff --git a/.gitlab/ci/Dockerfiles/php.8.1_composer_phive/README.md b/.gitlab/ci/Dockerfiles/php.8.1_composer_phive/README.md
deleted file mode 100644
index 8d587fd..0000000
--- a/.gitlab/ci/Dockerfiles/php.8.1_composer_phive/README.md
+++ /dev/null
@@ -1,53 +0,0 @@
-# CI ~ Prerequisites for PHP 8.1, Composer, Phive, ...
-
-Docker image of prerequisites for PHP **8.1**, Composer, Phive, Symfony-CLI, Xdebug and Make.
-
-## To update Docker image
-
-### Edit Dockerfile
-
-Edit [Dockerfile](Dockerfile) according to your needs
-and in addition you must to change in this file `LABEL version="Checksum_Comptoir1.0.0"`
-following [semantic versioning](http://semver.org/) recommendations:
-
- ```shell script
- MAJOR.MINOR.PATCH
-    # MAJOR ---> a breaking change (incompatible API changes)
-    # MINOR ---> add a new feature
-    # PATCH ---> fix a bug
-```
-
-```dockerfile
-# Set Docker LABEL and display software versions
-LABEL version="Checksum_Comptoir1.0.0"  \
-      description="Prerequisites for PHP 8.1, Composer, Phive, Symfony-CLI, Xdebug and Make"
-```
-
-### Build Docker image and push to container registry
-
-Build new Docker image and push to [Gitlab container registry](https://gitlab.adullact.net/adullact/pki/tajine/container_registry)
-
-```bash
-# Configure variables
-# in particular DOCKER_IMAGE_VERSION
-# which must be identical to LABEL.version in Dockerfile
-GITLAB_URI="gitlab.adullact.net:4567"
-GITLAB_REPOSITORY="adullact/pki/tajine"
-DOCKER_IMAGE_NAME="php-8.1_composer_phive"
-DOCKER_IMAGE_VERSION="vChecksum_Comptoir1.0.0" # must be identical to LABEL.version in Dockerfile
-
-# Login to Gitlab
-docker login "${GITLAB_URI}"
-
-# Build new Docker image
-docker build --progress plain -t "${GITLAB_URI}/${GITLAB_REPOSITORY}/${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_VERSION}" .
-docker images | grep "${DOCKER_IMAGE_NAME}"
-
-# Push to Gitlab container registry
-docker push "${GITLAB_URI}/${GITLAB_REPOSITORY}/${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_VERSION}"
-
-# Logout to remove Gitlab credentials from $HOME/.docker/config.json file
-docker logout "${GITLAB_URI}"
-```
-
-
diff --git a/.gitlab/ci/config/shellcheckrc b/.gitlab/ci/config/shellcheckrc
new file mode 100644
index 0000000..256d0e6
--- /dev/null
+++ b/.gitlab/ci/config/shellcheckrc
@@ -0,0 +1 @@
+external-sources=true
\ No newline at end of file
diff --git a/.gitlab/ci/job.linters.gitlab-ci.yml b/.gitlab/ci/job.linters.gitlab-ci.yml
index f33f509..942007a 100644
--- a/.gitlab/ci/job.linters.gitlab-ci.yml
+++ b/.gitlab/ci/job.linters.gitlab-ci.yml
@@ -145,6 +145,8 @@ ShellCheck_linter:
 #         when: manual
 #         allow_failure: true
     image: koalaman/shellcheck-alpine:latest
+    before_script:
+        - cp "${CI_PROJECT_DIR}/.gitlab/ci/config/shellcheckrc"  "${CI_PROJECT_DIR}/.shellcheckrc"
     script:
         - find . -name '*.sh' -type f
         - find . -name '*.sh' -type f | xargs -I % shellcheck %
diff --git a/Makefile b/Makefile
index b7de3f4..994312c 100644
--- a/Makefile
+++ b/Makefile
@@ -48,6 +48,18 @@ routes: ## Display Symfony routes
 .PHONY: routes
 
 
+
+##
+##--- GITLAB CI - Prepare prerequisites ------------------------------------------------------------------
+
+dev_prepare_ci_build_all_images: ## Build all images used by Gitlab CI
+	cd .gitlab/ci/Dockerfiles && ./10_build_all-images.sh
+.PHONY: dev_prepare_ci_build_all_images
+
+dev_prepare_ci_push_all_images: ## Push all images used by Gitlab CI
+	cd .gitlab/ci/Dockerfiles && ./30_push_all-images.sh
+.PHONY: ci_prerequisites_push_all_images
+
 ##
 ##--- SYMFONY database --------------------------------------------------------
 
@@ -111,7 +123,7 @@ tests_coverage: ## Run all tests (PhpUnit) and save coverage in an HTML file
 	bin/phpunit  --configuration phpunit.xml.dist --testdox --strict-coverage --coverage-text  --coverage-html "${AUTO_DOC_PHPUNIT_DIR}"
 .PHONY: tests_coverage
 
-tests_mutation: ## Run mutation tests (Infection)
+tests_mutation: ## Run mutation tests (Infection)   TODO replace PHIVE by COMPOSER
 	rm -rf "${WEBAPP_DIR}/var/tmp/" || true
 	cd "${WEBAPP_DIR}" && ../bin/infection --min-covered-msi=70 --min-msi=20 --test-framework-options="${INFECTION_PHPUNIT_OPTION}"
 #	cd "${WEBAPP_DIR}" && ../bin/infection --logger-html="${AUTO_DOC_INFECTION_FILE}" --test-framework-options="${INFECTION_PHPUNIT_OPTION}"
@@ -138,17 +150,17 @@ sf_fix-coding-standard: ## ...
 
 twig_linter: ## Twig templates linter
 	webapp/bin/console lint:twig --show-deprecations webapp/templates/
-.PHONY: php_coding-standard
+.PHONY: twig_linter
 
-php_coding-standard: ## ...
+php_coding-standard: ## PHP coding standards, via PHPCS (PHP Code Sniffer)
 	bin/phpcs --standard=PSR12 --colors  webapp/src/ webapp/tests/ -s
 .PHONY: php_coding-standard
 
-php_coding-standard_diff: ## ...
+php_coding-standard_diff: ## PHP coding standards, via PHPCS (PHP Code Sniffer) + display DIFF
 	bin/phpcs --standard=PSR12 --colors  webapp/src/ webapp/tests/ --report=diff
 .PHONY: php_coding-standard_diff
 
-php_coding-standard_summary: ## ...
+php_coding-standard_summary: ## PHP coding standards, via PHPCS (PHP Code Sniffer), with summary report
 	bin/phpcs --standard=PSR12 --colors  webapp/src/ webapp/tests/ --report=summary
 .PHONY: php_coding-standard_summary
 
@@ -159,7 +171,7 @@ php_fix-coding-standard: ## ...
 
 ##
 ##--- OTHER -------------------------------------------------------------------
-php_linter: ## ...
+php_linter: ## PHP Linter
 	bin/parallel-lint --colors webapp/ --exclude webapp/vendor/ --exclude webapp/var/
 .PHONY: php_linter
 
-- 
GitLab