From 9fda36a7fba7152c5593121bd9afa3f47b27cb4a Mon Sep 17 00:00:00 2001 From: Achim Fritz Date: Fri, 20 Mar 2026 09:04:27 +0100 Subject: [PATCH] !!![TASK] change requirements Support TYPO3 v13 and v14 simplify ci workflow --- .github/workflows/ci.yml | 69 ++-- Build/Scripts/runTests.sh | 333 ------------------ Classes/Hooks/DatahandlerHook.php | 5 +- Configuration/PageTS/main.tsconfig | 1 - Configuration/Services.yaml | 8 + .../Functional/Hooks/DatahandlerHookTest.php | 5 +- composer.json | 12 +- 7 files changed, 60 insertions(+), 373 deletions(-) delete mode 100755 Build/Scripts/runTests.sh delete mode 100644 Configuration/PageTS/main.tsconfig create mode 100644 Configuration/Services.yaml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 869d7b2..04a83b1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,33 +13,46 @@ jobs: runs-on: ubuntu-22.04 strategy: matrix: - php: [ '7.4', '8.0', '8.1' ] - TYPO3: [ '11' ] - include: - - TYPO3: '12' - php: '8.1' - - TYPO3: '13' - php: '8.3' - - TYPO3: '14' - php: '8.4' + php: [ '8.2', '8.5' ] + TYPO3: [ '13', '14' ] steps: - name: Checkout - uses: actions/checkout@v4 - - - name: Install testing system - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -t ${{ matrix.TYPO3 }} -s composerInstall - - - name: Composer validate - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -t ${{ matrix.TYPO3 }} -s composerValidate - - - name: Lint PHP - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -t ${{ matrix.TYPO3 }} -s lint - - - name: CGL - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -t ${{ matrix.TYPO3 }} -s cgl -n - - - name: phpstan - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -t ${{ matrix.TYPO3 }} -s phpstan - - - name: Functional Tests with mariadb - run: Build/Scripts/runTests.sh -p ${{ matrix.php }} -t ${{ matrix.TYPO3 }} -s functional + uses: actions/checkout@v2 + + - name: Set up PHP Version + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + tools: composer:v2 + + - name: Start MySQL + run: sudo /etc/init.d/mysql start + + - name: Validate composer.json and composer.lock + run: composer validate + + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: ~/.composer/cache + key: dependencies-composer-${{ hashFiles('composer.json') }} + + - name: Install composer dependencies TYPO3 14 + if: matrix.TYPO3 == '14' + run: | + composer install --no-progress --no-interaction + - name: Install composer dependencies TYPO3 13 + if: matrix.TYPO3 == '13' + run: | + composer require typo3/cms-backend:^13.4 --no-progress --no-interaction --dev -W + - name: Phpstan + run: .Build/bin/phpstan analyze -c Build/phpstan.neon + - name: Phpcsfix + run: .Build/bin/php-cs-fixer fix --config=Build/php-cs-fixer.php --dry-run --stop-on-violation --using-cache=no + - name: Functional Tests + run: | + export typo3DatabaseName="typo3"; + export typo3DatabaseHost="127.0.0.1"; + export typo3DatabaseUsername="root"; + export typo3DatabasePassword="root"; + .Build/bin/phpunit -c Build/phpunit/FunctionalTests.xml Tests/Functional diff --git a/Build/Scripts/runTests.sh b/Build/Scripts/runTests.sh deleted file mode 100755 index 74ea7ac..0000000 --- a/Build/Scripts/runTests.sh +++ /dev/null @@ -1,333 +0,0 @@ -#!/usr/bin/env bash - -# -# doktypemapper test runner. -# -# Executes test suites using direct docker/podman container commands -# with ghcr.io/typo3/core-testing-* images. -# - -cleanUp() { - ATTACHED_CONTAINERS=$(${CONTAINER_BIN} ps --filter network=${NETWORK} --format='{{.Names}}' 2>/dev/null) - for ATTACHED_CONTAINER in ${ATTACHED_CONTAINERS}; do - ${CONTAINER_BIN} kill ${ATTACHED_CONTAINER} >/dev/null 2>&1 - done - ${CONTAINER_BIN} network rm ${NETWORK} >/dev/null 2>&1 -} - -waitFor() { - local HOST=${1} - local PORT=${2} - local TESTCOMMAND=" - COUNT=0; - while ! nc -z ${HOST} ${PORT} 2>/dev/null; do - if [ \"\${COUNT}\" -gt 20 ]; then - echo \"Can not connect to ${HOST} port ${PORT}. Aborting.\"; - exit 1; - fi; - sleep 1; - COUNT=\$((COUNT + 1)); - done; - " - ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} --network ${NETWORK} --name wait-for-${SUFFIX} ${IMAGE_PHP} /bin/sh -c "${TESTCOMMAND}" - if [ $? -gt 0 ]; then - kill -SIGTERM "${BASH_PID}" 2>/dev/null - fi -} - -loadHelp() { - read -r -d '' HELP < - Specifies which test suite to run - - cgl: PHP coding guidelines check - - composerInstall: "composer install" - - composerValidate: "composer validate" - - functional: functional tests - - lint: PHP linting - - phpstan: PHPStan static analysis - - unit (default): PHP unit tests - - update: pull latest container images - - -b - Container binary to use (default: docker) - - -t <11|12|13|14> - TYPO3 core major version for testing. - - 12 (default) - - -d - Only with -s functional - Specifies on which DBMS tests are performed - - mariadb (default): use MariaDB - - postgres: use PostgreSQL - - sqlite: use SQLite - - -p <7.4|8.0|8.1|8.2|8.3|8.4> - Specifies the PHP minor version to be used - - 8.1 (default) - - -e "" - Only with -s functional|unit - Additional options to send to phpunit. - Example -e "-v --filter canRetrieveValueWithGP" - - -x - Only with -s functional|unit - Send information to host instance for xdebug break points. - - -y - Send xdebug information to a different port than default 9003. - - -n - Only with -s cgl - Activate dry-run in CGL check that does not actively change files. - - -u - Update existing container images. - - -v - Enable verbose script output. Shows variables and docker commands. - - -h - Show this help. - -Examples: - # Run unit tests using PHP 8.1 - ./Build/Scripts/runTests.sh - - # Run unit tests using PHP 8.4 - ./Build/Scripts/runTests.sh -p 8.4 - - # Run functional tests with MariaDB - ./Build/Scripts/runTests.sh -s functional - - # Install composer dependencies for TYPO3 14 - ./Build/Scripts/runTests.sh -s composerInstall -t 14 -p 8.4 -EOF -} - -# Go to the directory this script is located, so everything else is relative -# to this dir, no matter from where this script is called. -THIS_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)" -cd "${THIS_SCRIPT_DIR}" || exit 1 - -# Go to extension root -cd ../../ || exit 1 -ROOT_DIR=$(pwd) - -# Option defaults -TEST_SUITE="unit" -DBMS="mariadb" -PHP_VERSION="8.1" -PHP_XDEBUG_ON=0 -PHP_XDEBUG_PORT=9003 -EXTRA_TEST_OPTIONS="" -SCRIPT_VERBOSE=0 -CGLCHECK_DRY_RUN="" -TYPO3="12" -CONTAINER_BIN="docker" - -# Option parsing -OPTIND=1 -INVALID_OPTIONS=() -while getopts ":s:b:d:p:e:t:xy:nhuv" OPT; do - case ${OPT} in - s) - TEST_SUITE=${OPTARG} - ;; - b) - CONTAINER_BIN=${OPTARG} - ;; - d) - DBMS=${OPTARG} - ;; - p) - PHP_VERSION=${OPTARG} - ;; - t) - TYPO3=${OPTARG} - ;; - e) - EXTRA_TEST_OPTIONS=${OPTARG} - ;; - x) - PHP_XDEBUG_ON=1 - ;; - y) - PHP_XDEBUG_PORT=${OPTARG} - ;; - h) - loadHelp - echo "${HELP}" - exit 0 - ;; - n) - CGLCHECK_DRY_RUN="-n" - ;; - u) - TEST_SUITE=update - ;; - v) - SCRIPT_VERBOSE=1 - ;; - \?) - INVALID_OPTIONS+=(${OPTARG}) - ;; - :) - INVALID_OPTIONS+=(${OPTARG}) - ;; - esac -done - -# Exit on invalid options -if [ ${#INVALID_OPTIONS[@]} -ne 0 ]; then - echo "Invalid option(s):" >&2 - for I in "${INVALID_OPTIONS[@]}"; do - echo "-${I}" >&2 - done - echo >&2 - loadHelp - echo "${HELP}" >&2 - exit 1 -fi - -# Set $1 to first mass argument, this is the optional test file or test directory to execute -shift $((OPTIND - 1)) -TEST_FILE=${1} - -if [ ${SCRIPT_VERBOSE} -eq 1 ]; then - set -x -fi - -# Container setup -PHP_MINOR="${PHP_VERSION/./}" -IMAGE_PHP="ghcr.io/typo3/core-testing-php${PHP_MINOR}:latest" -SUFFIX=$(echo $RANDOM) -NETWORK="doktypemapper-${SUFFIX}" - -${CONTAINER_BIN} network create ${NETWORK} >/dev/null 2>&1 - -BASH_PID=$$ - -CONTAINER_COMMON_PARAMS="--rm --network ${NETWORK} --user $(id -u):$(id -g) -v ${ROOT_DIR}:${ROOT_DIR} -w ${ROOT_DIR}" - -if [ ${PHP_XDEBUG_ON} -eq 0 ]; then - XDEBUG_MODE="-e XDEBUG_MODE=off" - XDEBUG_CONFIG="" -else - HOST_OS_IP=$(${CONTAINER_BIN} run --rm --network ${NETWORK} alpine ip route | awk '/default/ { print $3 }') - XDEBUG_MODE="-e XDEBUG_MODE=debug,develop" - XDEBUG_CONFIG="-e XDEBUG_CONFIG=\"client_port=${PHP_XDEBUG_PORT} client_host=${HOST_OS_IP}\"" -fi - -# Suite execution -case ${TEST_SUITE} in - cgl) - if [ -n "${CGLCHECK_DRY_RUN}" ]; then - CGLCHECK_DRY_RUN="--dry-run --diff" - fi - COMMAND="php -dxdebug.mode=off .Build/vendor/friendsofphp/php-cs-fixer/php-cs-fixer fix -v ${CGLCHECK_DRY_RUN} --config=Build/php-cs-fixer.php --using-cache=no" - ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} ${XDEBUG_MODE} --name cgl-${SUFFIX} ${IMAGE_PHP} /bin/sh -c "${COMMAND}" - SUITE_EXIT_CODE=$? - ;; - composerInstall) - COMMAND="php -v | grep '^PHP'; " - if [ "${TYPO3}" -eq 11 ]; then - COMMAND+="composer require typo3/cms-backend:^11.5 --dev -W --no-progress --no-interaction" - elif [ "${TYPO3}" -eq 12 ]; then - COMMAND+="composer require typo3/cms-backend:^12.4 --dev -W --no-progress --no-interaction" - elif [ "${TYPO3}" -eq 13 ]; then - COMMAND+="composer require typo3/cms-backend:^13.4 --dev -W --no-progress --no-interaction" - elif [ "${TYPO3}" -eq 14 ]; then - COMMAND+="composer require typo3/cms-backend:^14.0 --dev -W --no-progress --no-interaction" - else - COMMAND+="composer install --dev --no-progress --no-interaction" - fi - ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} -v ${HOME}:${HOME} ${XDEBUG_MODE} --name composer-install-${SUFFIX} ${IMAGE_PHP} /bin/sh -c "${COMMAND}" - SUITE_EXIT_CODE=$? - ;; - composerValidate) - COMMAND="php -v | grep '^PHP'; composer validate" - ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} -v ${HOME}:${HOME} ${XDEBUG_MODE} --name composer-validate-${SUFFIX} ${IMAGE_PHP} /bin/sh -c "${COMMAND}" - SUITE_EXIT_CODE=$? - ;; - functional) - case ${DBMS} in - mariadb) - ${CONTAINER_BIN} run --rm --network ${NETWORK} --name mariadb-${SUFFIX} \ - -e MYSQL_ROOT_PASSWORD=funcp \ - --tmpfs /var/lib/mysql/:rw,noexec,nosuid \ - -d mariadb:10 - waitFor mariadb-${SUFFIX} 3306 - CONTAINERPARAMS="-e typo3DatabaseName=func_test -e typo3DatabaseUsername=root -e typo3DatabasePassword=funcp -e typo3DatabaseHost=mariadb-${SUFFIX}" - ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} ${CONTAINERPARAMS} ${XDEBUG_MODE} ${XDEBUG_CONFIG} \ - -v ${HOME}:${HOME} --name functional-mariadb-${SUFFIX} ${IMAGE_PHP} \ - /bin/sh -c "php -v | grep '^PHP'; .Build/bin/phpunit -c Build/phpunit/FunctionalTests.xml ${EXTRA_TEST_OPTIONS} ${TEST_FILE}" - SUITE_EXIT_CODE=$? - ;; - postgres) - ${CONTAINER_BIN} run --rm --network ${NETWORK} --name postgres-${SUFFIX} \ - -e POSTGRES_PASSWORD=funcp \ - -e POSTGRES_USER=$(id -un) \ - --tmpfs /var/lib/postgresql/data:rw,noexec,nosuid \ - -d postgres:10 - waitFor postgres-${SUFFIX} 5432 - CONTAINERPARAMS="-e typo3DatabaseDriver=pdo_pgsql -e typo3DatabaseName=func_test -e typo3DatabaseUsername=$(id -un) -e typo3DatabasePassword=funcp -e typo3DatabaseHost=postgres-${SUFFIX}" - ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} ${CONTAINERPARAMS} ${XDEBUG_MODE} ${XDEBUG_CONFIG} \ - -v ${HOME}:${HOME} --name functional-postgres-${SUFFIX} ${IMAGE_PHP} \ - /bin/sh -c "php -v | grep '^PHP'; .Build/bin/phpunit -c Build/phpunit/FunctionalTests.xml ${EXTRA_TEST_OPTIONS} ${TEST_FILE}" - SUITE_EXIT_CODE=$? - ;; - sqlite) - ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} ${XDEBUG_MODE} ${XDEBUG_CONFIG} \ - -v ${HOME}:${HOME} \ - -e typo3DatabaseDriver=pdo_sqlite \ - --name functional-sqlite-${SUFFIX} ${IMAGE_PHP} \ - /bin/sh -c "php -v | grep '^PHP'; .Build/bin/phpunit -c Build/phpunit/FunctionalTests.xml ${EXTRA_TEST_OPTIONS} ${TEST_FILE}" - SUITE_EXIT_CODE=$? - ;; - *) - echo "Invalid -d option argument ${DBMS}" >&2 - echo >&2 - loadHelp - echo "${HELP}" >&2 - exit 1 - esac - ;; - lint) - COMMAND="php -v | grep '^PHP'; find . -name \\*.php ! -path './.Build/*' -print0 | xargs -0 -n1 -P4 php -dxdebug.mode=off -l >/dev/null" - ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} ${XDEBUG_MODE} --name lint-${SUFFIX} ${IMAGE_PHP} /bin/sh -c "${COMMAND}" - SUITE_EXIT_CODE=$? - ;; - phpstan) - COMMAND="php -v | grep '^PHP'; php -dxdebug.mode=off .Build/bin/phpstan analyze -c Build/phpstan.neon --no-progress --no-interaction" - ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} -v ${HOME}:${HOME} ${XDEBUG_MODE} --name phpstan-${SUFFIX} ${IMAGE_PHP} /bin/sh -c "${COMMAND}" - SUITE_EXIT_CODE=$? - ;; - unit) - COMMAND="php -v | grep '^PHP'; .Build/bin/phpunit -c Build/phpunit/UnitTests.xml ${EXTRA_TEST_OPTIONS} ${TEST_FILE}" - ${CONTAINER_BIN} run ${CONTAINER_COMMON_PARAMS} -v ${HOME}:${HOME} ${XDEBUG_MODE} ${XDEBUG_CONFIG} --name unit-${SUFFIX} ${IMAGE_PHP} /bin/sh -c "${COMMAND}" - SUITE_EXIT_CODE=$? - ;; - update) - # Pull ghcr.io/typo3/core-testing-* images - ${CONTAINER_BIN} images ghcr.io/typo3/core-testing-*:latest --format "{{.Repository}}:latest" | xargs -I {} ${CONTAINER_BIN} pull {} - # Remove dangling images - ${CONTAINER_BIN} images ghcr.io/typo3/core-testing-* --filter "dangling=true" --format "{{.ID}}" | xargs -I {} ${CONTAINER_BIN} rmi {} - ;; - *) - echo "Invalid -s option argument ${TEST_SUITE}" >&2 - echo >&2 - loadHelp - echo "${HELP}" >&2 - exit 1 -esac - -cleanUp - -exit $SUITE_EXIT_CODE diff --git a/Classes/Hooks/DatahandlerHook.php b/Classes/Hooks/DatahandlerHook.php index 0dc02bc..82e4391 100644 --- a/Classes/Hooks/DatahandlerHook.php +++ b/Classes/Hooks/DatahandlerHook.php @@ -12,12 +12,13 @@ * of the License, or any later version. */ +use Symfony\Component\DependencyInjection\Attribute\Autoconfigure; use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Core\DataHandling\DataHandler; -use TYPO3\CMS\Core\SingletonInterface; use TYPO3\CMS\Core\Utility\MathUtility; -class DatahandlerHook implements SingletonInterface +#[Autoconfigure(public: true)] +class DatahandlerHook { protected ?string $previousBackendLayout = null; diff --git a/Configuration/PageTS/main.tsconfig b/Configuration/PageTS/main.tsconfig deleted file mode 100644 index f8877b8..0000000 --- a/Configuration/PageTS/main.tsconfig +++ /dev/null @@ -1 +0,0 @@ -@import 'EXT:doktypemapper/Configuration/Sets/Doktypemapper/page.tsconfig' diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml new file mode 100644 index 0000000..60c8013 --- /dev/null +++ b/Configuration/Services.yaml @@ -0,0 +1,8 @@ +services: + _defaults: + autowire: true + autoconfigure: true + public: false + + B13\Doktypemapper\: + resource: '../Classes/*' diff --git a/Tests/Functional/Hooks/DatahandlerHookTest.php b/Tests/Functional/Hooks/DatahandlerHookTest.php index 05d625d..ebe5e9f 100644 --- a/Tests/Functional/Hooks/DatahandlerHookTest.php +++ b/Tests/Functional/Hooks/DatahandlerHookTest.php @@ -12,6 +12,7 @@ * of the License, or any later version. */ +use PHPUnit\Framework\Attributes\Test; use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\DataHandling\DataHandler; @@ -25,9 +26,7 @@ class DatahandlerHookTest extends FunctionalTestCase 'typo3conf/ext/doktypemapper', ]; - /** - * @test - */ + #[Test] public function backendLayoutIsSetForConfiguredDoktype(): void { $this->importCSVDataSet(__DIR__ . '/Fixtures/Datahandler/backendLayoutIsSetForConfiguredDoktype.csv'); diff --git a/composer.json b/composer.json index 185079f..44b3d9c 100644 --- a/composer.json +++ b/composer.json @@ -13,8 +13,7 @@ } }, "require": { - "php": "^7.4 || ^8.0", - "typo3/cms-backend": "^11.5 || ^12.4 || ^13.1 || ^14.0" + "typo3/cms-backend": "^13.4 || ^14.1" }, "autoload": { "psr-4": { @@ -22,10 +21,11 @@ } }, "require-dev": { - "saschaegerer/phpstan-typo3": "^1.8 || ^2.0", - "typo3/coding-standards": "^0.5.5", - "typo3/tailor": "^1.1", - "typo3/testing-framework": "^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^11.0", + "friendsofphp/php-cs-fixer": "^3.94", + "phpstan/phpstan": "^2.1", + "typo3/testing-framework": "^9.3", + "typo3/coding-standards": "^0.8.0" }, "config": { "vendor-dir": ".Build/vendor",