diff --git a/.github/workflows/infection.yml b/.github/workflows/infection.yml index 983dcbca..ee05ec1f 100644 --- a/.github/workflows/infection.yml +++ b/.github/workflows/infection.yml @@ -9,15 +9,62 @@ on: - 'composer.*' - 'phpunit*' - '.github/workflows/infection.yml' - push: - branches: - - develop - paths: - - '**.php' - - 'composer.*' - - 'phpunit*' - - '.github/workflows/infection.yml' + workflow_call: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read jobs: - infection: - uses: codeigniter4/.github/.github/workflows/infection.yml@main + main: + name: Mutation Testing + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, '[ci skip]')" + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.1' + tools: infection, phpunit + extensions: intl, json, mbstring, gd, xml, sqlite3 + coverage: xdebug + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up problem matchers for PHPUnit + run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" + + - name: Configure matchers + uses: mheap/phpunit-matcher-action@v1 + + - name: Get composer cache directory + run: echo "COMPOSER_CACHE_FILES_DIR=$(composer config cache-files-dir)" >> $GITHUB_ENV + + - name: Cache composer dependencies + uses: actions/cache@v3 + with: + path: ${{ env.COMPOSER_CACHE_FILES_DIR }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install dependencies + run: | + if [ -f composer.lock ]; then + composer install --no-progress --no-interaction --prefer-dist --optimize-autoloader + else + composer update --no-progress --no-interaction --prefer-dist --optimize-autoloader + fi + + - name: Run Infection for added files only + run: | + git fetch --depth=1 origin $GITHUB_BASE_REF + infection --threads=max --git-diff-lines --git-diff-base=origin/$GITHUB_BASE_REF --ignore-msi-with-no-mutations --only-covered --logger-github + env: + GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/phpcsfixer.yml b/.github/workflows/phpcsfixer.yml index ee1221ac..1a9233ba 100644 --- a/.github/workflows/phpcsfixer.yml +++ b/.github/workflows/phpcsfixer.yml @@ -13,7 +13,55 @@ on: paths: - '**.php' - '.github/workflows/phpcsfixer.yml' + workflow_call: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read jobs: - phpcsfixer: - uses: codeigniter4/.github/.github/workflows/phpcsfixer.yml@main + build: + name: PHP ${{ matrix.php-versions }} Coding Standards + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, '[ci skip]')" + strategy: + fail-fast: false + matrix: + php-versions: ['8.1'] + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + extensions: json, tokenizer + coverage: none + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Get composer cache directory + run: echo "COMPOSER_CACHE_FILES_DIR=$(composer config cache-files-dir)" >> $GITHUB_ENV + + - name: Cache composer dependencies + uses: actions/cache@v3 + with: + path: ${{ env.COMPOSER_CACHE_FILES_DIR }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install dependencies + run: | + if [ -f composer.lock ]; then + composer install --no-progress --no-interaction --prefer-dist --optimize-autoloader + else + composer update --no-progress --no-interaction --prefer-dist --optimize-autoloader + fi + + - name: Check code for standards compliance + run: vendor/bin/php-cs-fixer fix --verbose --ansi --dry-run --using-cache=no --diff diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 58e2add5..ee06002b 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -17,7 +17,66 @@ on: - 'composer.*' - 'phpstan*' - '.github/workflows/phpstan.yml' + workflow_call: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read jobs: - phpstan: - uses: codeigniter4/.github/.github/workflows/phpstan.yml@main + build: + name: PHP ${{ matrix.php-versions }} Static Analysis + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, '[ci skip]')" + strategy: + fail-fast: false + matrix: + php-versions: ['8.1'] + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + tools: phpstan, phpunit + extensions: intl, json, mbstring, xml + coverage: none + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Get composer cache directory + run: echo "COMPOSER_CACHE_FILES_DIR=$(composer config cache-files-dir)" >> $GITHUB_ENV + + - name: Cache composer dependencies + uses: actions/cache@v3 + with: + path: ${{ env.COMPOSER_CACHE_FILES_DIR }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }}-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Create PHPStan cache directory + run: mkdir -p build/phpstan + + - name: Cache PHPStan results + uses: actions/cache@v3 + with: + path: build/phpstan + key: ${{ runner.os }}-phpstan-${{ github.sha }} + restore-keys: ${{ runner.os }}-phpstan- + + - name: Install dependencies + run: | + if [ -f composer.lock ]; then + composer install --no-progress --no-interaction --prefer-dist --optimize-autoloader + else + composer update --no-progress --no-interaction --prefer-dist --optimize-autoloader + fi + + - name: Run static analysis + run: vendor/bin/phpstan analyze diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 490da8c1..3bba810d 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -25,7 +25,7 @@ jobs: if: "!contains(github.event.head_commit.message, '[ci skip]')" strategy: matrix: - php-versions: ['7.4', '8.0', '8.1'] + php-versions: ['8.1'] steps: - name: Checkout @@ -39,7 +39,7 @@ jobs: extensions: intl, json, mbstring, gd, xdebug, xml, sqlite3 coverage: xdebug env: - COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Get composer cache directory run: echo "COMPOSER_CACHE_FILES_DIR=$(composer config cache-files-dir)" >> $GITHUB_ENV @@ -66,7 +66,7 @@ jobs: TACHYCARDIA_MONITOR_GA: enabled GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - if: matrix.php-versions == '8.0' + - if: matrix.php-versions == '8.1' name: Run Coveralls continue-on-error: true run: | diff --git a/.github/workflows/rector.yml b/.github/workflows/rector.yml index 7759986f..4662a9c5 100644 --- a/.github/workflows/rector.yml +++ b/.github/workflows/rector.yml @@ -17,6 +17,14 @@ on: - 'composer.*' - 'rector.php' - '.github/workflows/rector.yml' + workflow_call: + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +permissions: + contents: read jobs: build: @@ -26,7 +34,7 @@ jobs: strategy: fail-fast: false matrix: - php-versions: ['7.4', '8.0', '8.1'] + php-versions: ['8.1'] steps: - name: Checkout @@ -40,7 +48,7 @@ jobs: extensions: intl, json, mbstring, xml coverage: none env: - COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Get composer cache directory run: echo "COMPOSER_CACHE_FILES_DIR=$(composer config cache-files-dir)" >> $GITHUB_ENV @@ -61,6 +69,4 @@ jobs: fi - name: Analyze for refactoring - run: | - composer global require --dev rector/rector:^0.15.1 - rector process --dry-run --no-progress-bar + run: vendor/bin/rector process --dry-run --no-progress-bar diff --git a/app/Entities/GitHub/ReleasePromise.php b/app/Entities/GitHub/ReleasePromise.php index a3ee5007..f91f2d1b 100644 --- a/app/Entities/GitHub/ReleasePromise.php +++ b/app/Entities/GitHub/ReleasePromise.php @@ -25,10 +25,8 @@ class ReleasePromise extends Release /** * API call to fetch the additional data. - * - * @var Closure|null */ - private $resolver; + private ?Closure $resolver = null; /** * Stores the resolver along with data. diff --git a/app/Libraries/Blog.php b/app/Libraries/Blog.php index 39f424e1..e4555128 100644 --- a/app/Libraries/Blog.php +++ b/app/Libraries/Blog.php @@ -250,7 +250,7 @@ protected function readPost(string $folder, string $filename) foreach ($contents as $line) { if (trim($line) === '---') { - $inFrontMatter = $inFrontMatter ? false : true; + $inFrontMatter = ! $inFrontMatter; if (! $inFrontMatter) { $inBody = true; diff --git a/rector.php b/rector.php index fa02e9e8..0fb460f2 100644 --- a/rector.php +++ b/rector.php @@ -1,11 +1,11 @@ sets([ SetList::DEAD_CODE, LevelSetList::UP_TO_PHP_74, - PHPUnitSetList::PHPUNIT_SPECIFIC_METHOD, + PHPUnitSetList::PHPUNIT_CODE_QUALITY, PHPUnitSetList::PHPUNIT_100, ]); @@ -79,31 +78,14 @@ JsonThrowOnErrorRector::class, StringifyStrNeedlesRector::class, + YieldDataProviderRector::class, // Note: requires php 8 RemoveUnusedPromotedPropertyRector::class, AnnotationWithValueToAttributeRector::class, - // Ignore tests that might make calls without a result - RemoveEmptyMethodCallRector::class => [ - __DIR__ . '/tests', - ], - - // Ignore files that should not be namespaced to their folder - NormalizeNamespaceByPSR4ComposerAutoloadRector::class => [ - __DIR__ . '/app/Helpers', - ], - // May load view files directly when detecting classes StringClassNameToClassConstantRector::class, - - // May be uninitialized on purpose - AddDefaultValueForUndefinedVariableRector::class, - - // PHPStan will report false positive errors - UnnecessaryTernaryExpressionRector::class => [ - __DIR__ . '/app/Libraries/Blog.php', - ], ]); // auto import fully qualified class names @@ -112,7 +94,6 @@ $rectorConfig->rule(SimplifyUselessVariableRector::class); $rectorConfig->rule(RemoveAlwaysElseRector::class); $rectorConfig->rule(CountArrayToEmptyArrayComparisonRector::class); - $rectorConfig->rule(ForToForeachRector::class); $rectorConfig->rule(ChangeNestedForeachIfsToEarlyContinueRector::class); $rectorConfig->rule(ChangeIfElseValueAssignToEarlyReturnRector::class); $rectorConfig->rule(SimplifyStrposLowerRector::class); @@ -125,12 +106,18 @@ $rectorConfig->rule(UnusedForeachValueToArrayKeysRector::class); $rectorConfig->rule(ChangeArrayPushToArrayAssignRector::class); $rectorConfig->rule(UnnecessaryTernaryExpressionRector::class); - $rectorConfig->rule(AddPregQuoteDelimiterRector::class); $rectorConfig->rule(SimplifyRegexPatternRector::class); $rectorConfig->rule(FuncGetArgsToVariadicParamRector::class); $rectorConfig->rule(MakeInheritedMethodVisibilitySameAsParentRector::class); $rectorConfig->rule(SimplifyEmptyArrayCheckRector::class); - $rectorConfig->rule(NormalizeNamespaceByPSR4ComposerAutoloadRector::class); + $rectorConfig + ->ruleWithConfiguration(TypedPropertyFromAssignsRector::class, [ + /** + * The INLINE_PUBLIC value is default to false to avoid BC break, if you use for libraries and want to preserve BC break, you don't need to configure it, as it included in LevelSetList::UP_TO_PHP_74 + * Set to true for projects that allow BC break + */ + TypedPropertyFromAssignsRector::INLINE_PUBLIC => false, + ]); $rectorConfig->rule(StringClassNameToClassConstantRector::class); $rectorConfig->rule(PrivatizeFinalClassPropertyRector::class); $rectorConfig->rule(CompleteDynamicPropertiesRector::class);