From 0d44d1f7b0d500d88934c3373d1b2a2c8a4373bb Mon Sep 17 00:00:00 2001
From: Dave Long <dave@longwaveconsulting.com>
Date: Thu, 23 Nov 2023 10:33:20 +0000
Subject: [PATCH] Issue #3402203 by fjgarlin: Improve the test-only job
 workflow

---
 .gitlab-ci.yml                     | 18 +++++++++-
 .gitlab-ci/pipeline-test-only.yml  | 57 ++++++++++++++++++++++++++++++
 .gitlab-ci/pipeline.yml            | 36 +++----------------
 .gitlab-ci/scripts/server-setup.sh |  7 ++++
 .gitlab-ci/scripts/test-only.sh    | 29 +++++++++++++++
 5 files changed, 114 insertions(+), 33 deletions(-)
 create mode 100644 .gitlab-ci/pipeline-test-only.yml
 create mode 100755 .gitlab-ci/scripts/server-setup.sh
 create mode 100755 .gitlab-ci/scripts/test-only.sh

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 608936c56cfc..7246f5c3924d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -125,7 +125,7 @@ default:
       allow_failure: true
 
 # Default configuration.
-'PHP 8.2 MySQL 8':
+'DEFAULT: PHP 8.2 MySQL 8':
   <<: *default-stage
   variables:
     _TARGET_PHP: "8.2"
@@ -137,6 +137,22 @@ default:
     - if: $CI_PIPELINE_SOURCE == "merge_request_event"
     - if: $PERFORMANCE_TEST == "1"
 
+'DEFAULT: Test-only':
+  <<: [ *default-stage, *with-composer ]
+  when: manual
+  allow_failure: true
+  variables:
+    _TARGET_PHP: "8.2"
+    _TARGET_DB: "mysql-8"
+  rules:
+    - if: $CI_PIPELINE_SOURCE == "push" && $CI_PROJECT_ROOT_NAMESPACE == "project"
+    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
+  trigger:
+    # Rely on the status of the child pipeline.
+    strategy: depend
+    include:
+      - local: .gitlab-ci/pipeline-test-only.yml
+
 # Run on commit, or manually.
 'PHP 8.1 MySQL 5.7':
   <<: [ *default-stage, *run-on-commit ]
diff --git a/.gitlab-ci/pipeline-test-only.yml b/.gitlab-ci/pipeline-test-only.yml
new file mode 100644
index 000000000000..73bce83e2cb7
--- /dev/null
+++ b/.gitlab-ci/pipeline-test-only.yml
@@ -0,0 +1,57 @@
+# cspell:ignore drupaltestbot drupaltestbotpw
+
+stages:
+  - 🗜️ Test
+
+variables:
+  FF_NETWORK_PER_BUILD: 1
+  SIMPLETEST_BASE_URL: http://localhost/subdirectory
+  DB_DRIVER: mysql
+  MYSQL_ROOT_PASSWORD: root
+  MYSQL_DATABASE: mysql
+  MYSQL_USER: drupaltestbot
+  MYSQL_PASSWORD: drupaltestbotpw
+  POSTGRES_DB: drupaltestbot
+  POSTGRES_USER: drupaltestbot
+  POSTGRES_PASSWORD: drupaltestbotpw
+
+'🩹 Test-only changes':
+  stage: 🗜️ Test
+  interruptible: true
+  image:
+    name: $_CONFIG_DOCKERHUB_ROOT/php-$_TARGET_PHP-apache:production
+  rules:
+    - if: $CI_PIPELINE_SOURCE == "parent_pipeline" && $PERFORMANCE_TEST != "1"
+  needs:
+    - pipeline: $PARENT_PIPELINE_ID
+      job: '📦️ Composer'
+  services:
+    - name: $_CONFIG_DOCKERHUB_ROOT/$_TARGET_DB:production
+      alias: database
+    - name: $_CONFIG_DOCKERHUB_ROOT/chromedriver:production
+      alias: chrome
+      entrypoint:
+        - chromedriver
+        - "--no-sandbox"
+        - "--log-path=/tmp/chromedriver.log"
+        - "--verbose"
+        - "--whitelisted-ips="
+  before_script:
+    - |
+      [[ $_TARGET_DB == sqlite* ]] && export SIMPLETEST_DB=sqlite://localhost/$CI_PROJECT_DIR/sites/default/files/db.sqlite?module=sqlite
+      [[ $_TARGET_DB == mysql* ]] && export SIMPLETEST_DB=mysql://$MYSQL_USER:$MYSQL_PASSWORD@database/$MYSQL_DATABASE?module=mysql
+      [[ $_TARGET_DB == mariadb* ]] && export SIMPLETEST_DB=mysql://$MYSQL_USER:$MYSQL_PASSWORD@database/$MYSQL_DATABASE?module=mysql
+      [[ $_TARGET_DB == pgsql* ]] && export SIMPLETEST_DB=pgsql://$POSTGRES_USER:$POSTGRES_PASSWORD@database/$POSTGRES_DB?module=pgsql
+    - $CI_PROJECT_DIR/.gitlab-ci/scripts/server-setup.sh
+  script:
+    - $CI_PROJECT_DIR/.gitlab-ci/scripts/test-only.sh
+  after_script:
+    - sed -i "s#$CI_PROJECT_DIR/##" ./sites/default/files/simpletest/phpunit-*.xml || true
+  artifacts:
+    when: always
+    expire_in: 6 mos
+    reports:
+      junit: ./sites/default/files/simpletest/phpunit-*.xml
+    paths:
+      - ./sites/default/files/simpletest/phpunit-*.xml
+      - ./sites/simpletest/browser_output
diff --git a/.gitlab-ci/pipeline.yml b/.gitlab-ci/pipeline.yml
index ec2de2595bc8..370b430729dc 100644
--- a/.gitlab-ci/pipeline.yml
+++ b/.gitlab-ci/pipeline.yml
@@ -20,16 +20,12 @@ default:
   image:
     name: $_CONFIG_DOCKERHUB_ROOT/php-$_TARGET_PHP-apache:production
   before_script:
-  - |
-      ln -s $CI_PROJECT_DIR /var/www/html/subdirectory
-      sudo service apache2 start
+    - |
       [[ $_TARGET_DB == sqlite* ]] && export SIMPLETEST_DB=sqlite://localhost/$CI_PROJECT_DIR/sites/default/files/db.sqlite?module=sqlite
       [[ $_TARGET_DB == mysql* ]] && export SIMPLETEST_DB=mysql://$MYSQL_USER:$MYSQL_PASSWORD@database/$MYSQL_DATABASE?module=mysql
       [[ $_TARGET_DB == mariadb* ]] && export SIMPLETEST_DB=mysql://$MYSQL_USER:$MYSQL_PASSWORD@database/$MYSQL_DATABASE?module=mysql
       [[ $_TARGET_DB == pgsql* ]] && export SIMPLETEST_DB=pgsql://$POSTGRES_USER:$POSTGRES_PASSWORD@database/$POSTGRES_DB?module=pgsql
-      mkdir -p ./sites/simpletest ./sites/default/files ./build/logs/junit /var/www/.composer
-      chown -R www-data:www-data ./sites ./build/logs/junit ./vendor /var/www/
-      sudo -u www-data git config --global --add safe.directory $CI_PROJECT_DIR
+    - $CI_PROJECT_DIR/.gitlab-ci/scripts/server-setup.sh
   after_script:
     - sed -i "s#$CI_PROJECT_DIR/##" ./sites/default/files/simpletest/phpunit-*.xml || true
   artifacts:
@@ -132,34 +128,10 @@ variables:
     - <<: *with-database
     - <<: *with-chrome
   script:
-    - export TARGET_BRANCH=${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}${CI_COMMIT_BRANCH}
-    - git fetch -vn --depth=50 "$CI_MERGE_REQUEST_PROJECT_URL" "+refs/heads/$TARGET_BRANCH:refs/heads/$TARGET_BRANCH"
-    - |
-      echo "ℹ️ Changes from ${TARGET_BRANCH}"
-      git diff ${CI_MERGE_REQUEST_DIFF_BASE_SHA} --name-only
-      echo "If this list contains more files than what you changed, then you need to rebase your branch."
-      echo "1️⃣ Reverting non test changes"
-      if [[ $(git diff ${CI_MERGE_REQUEST_DIFF_BASE_SHA} --diff-filter=DM --name-only|grep -Ev "*/tests/*"|grep -v .gitlab-ci|grep -v scripts/run-tests.sh) ]]; then
-        git diff ${CI_MERGE_REQUEST_DIFF_BASE_SHA} --diff-filter=DM --name-only|grep -Ev "*/tests/*"|grep -v .gitlab-ci|grep -v scripts/run-tests.sh|while read file;do
-          echo "↩️ Reverting $file";
-          git checkout refs/heads/${TARGET_BRANCH} -- $file;
-        done
-      fi
-      if [[ $(git diff ${CI_MERGE_REQUEST_DIFF_BASE_SHA} --diff-filter=A --name-only|grep -Ev "*/tests/*"|grep -v .gitlab-ci|grep -v scripts/run-tests.sh) ]]; then
-        git diff ${CI_MERGE_REQUEST_DIFF_BASE_SHA} --diff-filter=A --name-only|grep -Ev "*/tests/*"|grep -v .gitlab-ci|grep -v scripts/run-tests.sh|while read file;do
-          echo "🗑️️ Deleting $file";
-          git rm $file;
-        done
-      fi
-      echo "2️⃣ Running test changes for this branch"
-      if [[ $(git diff ${CI_MERGE_REQUEST_DIFF_BASE_SHA} --name-only|grep -E "Test.php$") ]]; then
-        for test in `git diff ${CI_MERGE_REQUEST_DIFF_BASE_SHA} --name-only|grep -E "Test.php$"`; do
-          sudo SIMPLETEST_BASE_URL="$SIMPLETEST_BASE_URL" SIMPLETEST_DB="$SIMPLETEST_DB" MINK_DRIVER_ARGS_WEBDRIVER="$MINK_DRIVER_ARGS_WEBDRIVER" -u www-data ./vendor/bin/phpunit -c core $test --log-junit=./sites/default/files/simpletest/phpunit-`echo $test|sed 's/\//_/g' `.xml;
-        done;
-      fi
+    - $CI_PROJECT_DIR/.gitlab-ci/scripts/test-only.sh
 
 '⚙️️ PHPUnit Kernel':
-  <<: [*with-composer, *run-tests, *default-job-settings ]
+  <<: [ *with-composer, *run-tests, *default-job-settings ]
   parallel: 2
   variables:
     TESTSUITE: PHPUnit-Kernel
diff --git a/.gitlab-ci/scripts/server-setup.sh b/.gitlab-ci/scripts/server-setup.sh
new file mode 100755
index 000000000000..2d51188b0129
--- /dev/null
+++ b/.gitlab-ci/scripts/server-setup.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+ln -s $CI_PROJECT_DIR /var/www/html/subdirectory
+sudo service apache2 start
+mkdir -p ./sites/simpletest ./sites/default/files ./build/logs/junit /var/www/.composer
+chown -R www-data:www-data ./sites ./build/logs/junit ./vendor /var/www/
+sudo -u www-data git config --global --add safe.directory $CI_PROJECT_DIR
diff --git a/.gitlab-ci/scripts/test-only.sh b/.gitlab-ci/scripts/test-only.sh
new file mode 100755
index 000000000000..6e49f9de8f92
--- /dev/null
+++ b/.gitlab-ci/scripts/test-only.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+export TARGET_BRANCH=${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}${CI_COMMIT_BRANCH}
+git fetch -vn --depth=50 "$CI_MERGE_REQUEST_PROJECT_URL" "+refs/heads/$TARGET_BRANCH:refs/heads/$TARGET_BRANCH"
+
+echo "ℹ️ Changes from ${TARGET_BRANCH}"
+git diff ${CI_MERGE_REQUEST_DIFF_BASE_SHA} --name-only
+echo "If this list contains more files than what you changed, then you need to rebase your branch."
+
+echo "1️⃣ Reverting non test changes"
+if [[ $(git diff ${CI_MERGE_REQUEST_DIFF_BASE_SHA} --diff-filter=DM --name-only|grep -Ev "*/tests/*"|grep -v .gitlab-ci|grep -v scripts/run-tests.sh) ]]; then
+git diff ${CI_MERGE_REQUEST_DIFF_BASE_SHA} --diff-filter=DM --name-only|grep -Ev "*/tests/*"|grep -v .gitlab-ci|grep -v scripts/run-tests.sh|while read file;do
+  echo "↩️ Reverting $file";
+  git checkout refs/heads/${TARGET_BRANCH} -- $file;
+done
+fi
+if [[ $(git diff ${CI_MERGE_REQUEST_DIFF_BASE_SHA} --diff-filter=A --name-only|grep -Ev "*/tests/*"|grep -v .gitlab-ci|grep -v scripts/run-tests.sh) ]]; then
+git diff ${CI_MERGE_REQUEST_DIFF_BASE_SHA} --diff-filter=A --name-only|grep -Ev "*/tests/*"|grep -v .gitlab-ci|grep -v scripts/run-tests.sh|while read file;do
+  echo "🗑️️ Deleting $file";
+  git rm $file;
+done
+fi
+
+echo "2️⃣ Running test changes for this branch"
+if [[ $(git diff ${CI_MERGE_REQUEST_DIFF_BASE_SHA} --name-only|grep -E "Test.php$") ]]; then
+for test in `git diff ${CI_MERGE_REQUEST_DIFF_BASE_SHA} --name-only|grep -E "Test.php$"`; do
+  sudo SIMPLETEST_BASE_URL="$SIMPLETEST_BASE_URL" SIMPLETEST_DB="$SIMPLETEST_DB" MINK_DRIVER_ARGS_WEBDRIVER="$MINK_DRIVER_ARGS_WEBDRIVER" -u www-data ./vendor/bin/phpunit -c core $test --log-junit=./sites/default/files/simpletest/phpunit-`echo $test|sed 's/\//_/g' `.xml;
+done;
+fi
-- 
GitLab