diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..172e2c07 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,104 @@ +# Adapted from https://github.com/TYPO3GmbH/blog/blob/master/.github/workflows/ci.yml +name: CI + +on: + push: + branches: [TYPO3_11] + pull_request: + branches: [TYPO3_11] + +jobs: + build: + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + typo3: [ '^11.5' ] + php: [ '7.4', '8.0', '8.1', '8.2', '8.3' ] + + steps: + - id: checkout + name: Checkout + uses: actions/checkout@v5 + + - id: setup_php + name: Set up PHP version ${{ matrix.php }} + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + tools: composer:v2 + + - name: Validate composer.json and composer.lock + run: composer validate + + - id: security + name: Security audit + if: ${{ always() && steps.install.conclusion == 'success' }} + run: | + composer audit + + - id: composer-cache-vars + name: Composer Cache Vars + run: | + echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + echo "timestamp=$(date +"%s")" >> $GITHUB_OUTPUT + + - id: composer-cache-dependencies + name: Cache Composer dependencies + uses: actions/cache@v4 + with: + path: ${{ steps.composer-cache-vars.outputs.dir }} + key: ${{ runner.os }}-composer-${{ matrix.php }}-${{ matrix.typo3 }}-${{ steps.composer-cache-vars.outputs.timestamp }} + restore-keys: | + ${{ runner.os }}-composer-${{ matrix.php }}-${{ matrix.typo3 }}- + ${{ runner.os }}-composer-${{ matrix.php }}- + ${{ runner.os }}-composer- + + - id: install + name: Install dependencies with typo3/cms-core:${{ matrix.typo3 }} + run: | + composer require typo3/cms-core:${{ matrix.typo3 }} --no-progress --no-update + composer require typo3/cms-backend:${{ matrix.typo3 }} --no-progress --no-update + composer require typo3/cms-extbase:${{ matrix.typo3 }} --no-progress --no-update + composer require typo3/cms-recordlist:${{ matrix.typo3 }} --no-progress --no-update + composer require typo3/cms-frontend:${{ matrix.typo3 }} --no-progress --no-update + composer require typo3/cms-rte-ckeditor:${{ matrix.typo3 }} --no-progress --no-update + composer install + git checkout composer.json + + - id: lint + name: Lint + if: ${{ always() && steps.install.conclusion == 'success' }} + run: | + composer ci:test:php:lint + + - id: phpstan + name: PHPStan + if: ${{ always() && steps.install.conclusion == 'success' }} + run: | + composer ci:test:php:phpstan -- --error-format=github + + - id: functional + name: Functional Tests + if: ${{ always() && steps.install.conclusion == 'success' }} + env: + typo3DatabaseDriver: pdo_sqlite + run: | + composer ci:test:php:functional + + - id: coverage + name: Generate Coverage Report + if: ${{ always() && steps.functional.conclusion == 'success' && matrix.php == '8.1' }} + env: + typo3DatabaseDriver: pdo_sqlite + run: | + composer ci:coverage:functional + + - id: upload-coverage + name: Upload Coverage to Codecov + if: ${{ always() && steps.coverage.conclusion == 'success' && matrix.php == '8.1' }} + uses: codecov/codecov-action@v5 + with: + files: .Build/logs/clover.xml + fail_ci_if_error: false diff --git a/.github/workflows/phpcs.yml b/.github/workflows/phpcs.yml deleted file mode 100644 index 2785b504..00000000 --- a/.github/workflows/phpcs.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: PHP_CodeSniffer - -on: [push, pull_request] - -jobs: - run: - runs-on: ${{ matrix.operating-system }} - - strategy: - matrix: - operating-system: [ubuntu-22.04] - php-version: ['7.4', '8.0', '8.1', '8.2'] - - name: Testing PHP ${{ matrix.php-version }} on ${{ matrix.operating-system }} - - steps: - - uses: shivammathur/setup-php@master - with: - php-version: ${{ matrix.php-version }} - extensions: json,intl,mbstring - - - name: Checkout repository - uses: actions/checkout@v3 - - - run: composer validate - - run: composer install --no-progress - - run: .Build/bin/phpcs Classes/ --standard=PSR12 diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml deleted file mode 100644 index 327a6b50..00000000 --- a/.github/workflows/phpstan.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: PHPStan - -on: [push, pull_request] - -jobs: - run: - runs-on: ${{ matrix.operating-system }} - - strategy: - matrix: - operating-system: [ubuntu-22.04] - php-version: ['7.4', '8.0', '8.1', '8.2'] - - name: Testing PHP ${{ matrix.php-version }} on ${{ matrix.operating-system }} - - steps: - - uses: shivammathur/setup-php@master - with: - php-version: ${{ matrix.php-version }} - extensions: json,intl,mbstring - - - name: Checkout repository - uses: actions/checkout@v3 - - - run: composer validate - - run: composer install --no-progress - - run: .Build/bin/phpstan analyse -c phpstan.neon diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml deleted file mode 100644 index 658b4fb8..00000000 --- a/.github/workflows/testing.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: FunctionalTests - -on: [push, pull_request] - -jobs: - run: - runs-on: ${{ matrix.operating-system }} - - strategy: - matrix: - operating-system: [ubuntu-22.04] - php-version: ['7.4', '8.0', '8.1'] - db: ['mariadb', 'postgres'] - - name: Testing PHP ${{ matrix.php-version }} on ${{ matrix.operating-system }} - - steps: - - uses: shivammathur/setup-php@master - with: - php-version: ${{ matrix.php-version }} - extensions: json,intl,mbstring - - - name: Checkout repository - uses: actions/checkout@v3 - - - run: Build/Scripts/runTests.sh -p ${{ matrix.php-version }} -s composerInstall - - run: Build/Scripts/runTests.sh -p ${{ matrix.php-version }} -s functional -d ${{matrix.db}} diff --git a/Build/phpstan-baseline.neon b/Build/phpstan-baseline.neon new file mode 100644 index 00000000..22ba0900 --- /dev/null +++ b/Build/phpstan-baseline.neon @@ -0,0 +1,161 @@ +parameters: + ignoreErrors: + - + message: "#^Method Netresearch\\\\RteCKEditorImage\\\\Backend\\\\Preview\\\\RteImagePreviewRenderer\\:\\:walk\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: ../Classes/Backend/Preview/RteImagePreviewRenderer.php + + - + message: "#^Property Netresearch\\\\RteCKEditorImage\\\\Backend\\\\Preview\\\\RteImagePreviewRenderer\\:\\:\\$toRemove type has no value type specified in iterable type array\\.$#" + count: 1 + path: ../Classes/Backend/Preview/RteImagePreviewRenderer.php + + - + message: "#^Call to an undefined method object\\:\\:getFileObject\\(\\)\\.$#" + count: 1 + path: ../Classes/Controller/ImageLinkRenderingController.php + + - + message: "#^Call to an undefined method object\\:\\:getLogger\\(\\)\\.$#" + count: 1 + path: ../Classes/Controller/ImageLinkRenderingController.php + + - + message: "#^Call to an undefined method object\\:\\:setMagicImageMaximumDimensions\\(\\)\\.$#" + count: 1 + path: ../Classes/Controller/ImageLinkRenderingController.php + + - + message: "#^PHPDoc tag @var for variable \\$result has no value type specified in iterable type array\\.$#" + count: 1 + path: ../Classes/Controller/ImageLinkRenderingController.php + + - + message: "#^Call to an undefined method object\\:\\:getFileObject\\(\\)\\.$#" + count: 1 + path: ../Classes/Controller/ImageRenderingController.php + + - + message: "#^Call to an undefined method object\\:\\:getLogger\\(\\)\\.$#" + count: 1 + path: ../Classes/Controller/ImageRenderingController.php + + - + message: "#^Call to an undefined method object\\:\\:setMagicImageMaximumDimensions\\(\\)\\.$#" + count: 1 + path: ../Classes/Controller/ImageRenderingController.php + + - + message: "#^Parameter \\#1 \\$haystack of function strpos expects string, string\\|null given\\.$#" + count: 1 + path: ../Classes/Controller/ImageRenderingController.php + + - + message: "#^Parameter \\#1 \\$(string1|str1) of function strncasecmp expects string, string\\|null given\\.$#" + count: 1 + path: ../Classes/Controller/ImageRenderingController.php + + - + message: "#^Parameter \\#1 \\$(string1|str1) of function strncmp expects string, string\\|null given\\.$#" + count: 1 + path: ../Classes/Controller/ImageRenderingController.php + + - + message: "#^PHPDoc tag @var for variable \\$bparams has no value type specified in iterable type array\\.$#" + count: 1 + path: ../Classes/Controller/SelectImageController.php + + - + message: "#^Property Netresearch\\\\RteCKEditorImage\\\\Controller\\\\SelectImageController\\:\\:\\$magicImageService \\(TYPO3\\\\CMS\\\\Core\\\\Resource\\\\Service\\\\MagicImageService\\) does not accept object\\.$#" + count: 1 + path: ../Classes/Controller/SelectImageController.php + + - + message: "#^Property Netresearch\\\\RteCKEditorImage\\\\Controller\\\\SelectImageController\\:\\:\\$resourceFactory \\(TYPO3\\\\CMS\\\\Core\\\\Resource\\\\ResourceFactory\\) does not accept object\\.$#" + count: 1 + path: ../Classes/Controller/SelectImageController.php + + - + message: "#^Property Netresearch\\\\RteCKEditorImage\\\\Controller\\\\SelectImageController\\:\\:\\$richText \\(TYPO3\\\\CMS\\\\Core\\\\Configuration\\\\Richtext\\) does not accept object\\.$#" + count: 1 + path: ../Classes/Controller/SelectImageController.php + + - + message: "#^Call to an undefined method object\\:\\:createMagicImage\\(\\)\\.$#" + count: 3 + path: ../Classes/Database/RteImagesDbHook.php + + - + message: "#^Call to an undefined method object\\:\\:getCache\\(\\)\\.$#" + count: 1 + path: ../Classes/Database/RteImagesDbHook.php + + - + message: "#^Call to an undefined method object\\:\\:getDefaultBackendStoragePid\\(\\)\\.$#" + count: 1 + path: ../Classes/Database/RteImagesDbHook.php + + - + message: "#^Call to an undefined method object\\:\\:getFileObject\\(\\)\\.$#" + count: 2 + path: ../Classes/Database/RteImagesDbHook.php + + - + message: "#^Call to an undefined method object\\:\\:load\\(\\)\\.$#" + count: 1 + path: ../Classes/Database/RteImagesDbHook.php + + - + message: "#^Call to an undefined method object\\:\\:parse\\(\\)\\.$#" + count: 1 + path: ../Classes/Database/RteImagesDbHook.php + + - + message: "#^Call to an undefined method object\\:\\:retrieveFileOrFolderObject\\(\\)\\.$#" + count: 1 + path: ../Classes/Database/RteImagesDbHook.php + + - + message: "#^Call to an undefined method object\\:\\:setAspect\\(\\)\\.$#" + count: 2 + path: ../Classes/Database/RteImagesDbHook.php + + - + message: "#^Call to an undefined method object\\:\\:setMagicImageMaximumDimensions\\(\\)\\.$#" + count: 1 + path: ../Classes/Database/RteImagesDbHook.php + + - + message: "#^Class Netresearch\\\\RteCKEditorImage\\\\Database\\\\RteImagesDbHook has an uninitialized property \\$pObj\\. Give it default value or assign it in the constructor\\.$#" + count: 1 + path: ../Classes/Database/RteImagesDbHook.php + + - + message: "#^Class Netresearch\\\\RteCKEditorImage\\\\Database\\\\RteImagesDbHook has an uninitialized property \\$transformationKey\\. Give it default value or assign it in the constructor\\.$#" + count: 1 + path: ../Classes/Database/RteImagesDbHook.php + + - + message: "#^Method Netresearch\\\\RteCKEditorImage\\\\Database\\\\RteImagesDbHook\\:\\:getProcessedFile\\(\\) has parameter \\$attribArray with no value type specified in iterable type array\\.$#" + count: 1 + path: ../Classes/Database/RteImagesDbHook.php + + - + message: "#^Call to an undefined method object\\:\\:getLogger\\(\\)\\.$#" + count: 1 + path: ../ext_localconf.php + + - + message: "#^Call to an undefined method object\\:\\:getMessageQueueByIdentifier\\(\\)\\.$#" + count: 1 + path: ../ext_localconf.php + + - + message: "#^Call to an undefined method object\\:\\:getQueryBuilderForTable\\(\\)\\.$#" + count: 1 + path: ../ext_localconf.php + + - + message: "#^Call to an undefined method object\\:\\:isEnvironmentInBackendMode\\(\\)\\.$#" + count: 1 + path: ../ext_localconf.php diff --git a/Build/phpstan.neon b/Build/phpstan.neon new file mode 100644 index 00000000..7111a58b --- /dev/null +++ b/Build/phpstan.neon @@ -0,0 +1,28 @@ +includes: + - %currentWorkingDirectory%/.Build/vendor/phpstan/phpstan-strict-rules/rules.neon +# - %currentWorkingDirectory%/.Build/vendor/phpstan/phpstan-phpunit/rules.neon + - %currentWorkingDirectory%/Build/phpstan-baseline.neon + +parameters: + # Level 8 is appropriate for TYPO3 v11 compatibility + level: 8 + + paths: + - %currentWorkingDirectory%/Classes/ + - %currentWorkingDirectory%/Configuration/ + - %currentWorkingDirectory%/Resources/ + - %currentWorkingDirectory%/Tests/ + - %currentWorkingDirectory%/ext_localconf.php + + excludePaths: + - %currentWorkingDirectory%/.Build/* + - %currentWorkingDirectory%/ext_emconf.php + + # Strict configuration options for maximum code quality + treatPhpDocTypesAsCertain: false + reportUnmatchedIgnoredErrors: true + + # Advanced type inference and checking + inferPrivatePropertyTypeFromConstructor: true + checkMissingCallableSignature: true + checkUninitializedProperties: true diff --git a/Build/phpunit/FunctionalTests.xml b/Build/phpunit/FunctionalTests.xml index 976a3645..96f86c45 100644 --- a/Build/phpunit/FunctionalTests.xml +++ b/Build/phpunit/FunctionalTests.xml @@ -44,6 +44,11 @@ ../../Tests/Functional/ + + + ../../Classes + +