Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 86 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,14 +137,10 @@ jobs:
PLUGIN_CODE: ${{ matrix.plugin_code }}
working-directory: 'ec-cube'
run: |
# 有効化したプラグインのルーティングはコンテナのコンパイル時に確定する。
# phpunit プロセスでの遅延コンパイルに任せると DB/タイミングで有効プラグイン一覧を
# 取りこぼし RouteNotFound になることがあるため、クリーンなプロセスで warmup して確定させる。
bin/console cache:clear --no-warmup
# cache:clear は秒精度の fresh 判定で有効化前のコンテナを残すことがあるため、直接削除して warmup する
rm -rf var/cache/test
bin/console cache:warmup
# 有効プラグインのルートがコンテナに載っていることを確認する。
# EccubeExtension::configurePlugins() はビルド時の DB 接続に失敗すると
# 全プラグインを無効とみなして正常終了するため、warmup の成否では検知できない。
# 有効プラグインのルートがコンテナに載っていることを確認する (warmup の成否では検知できない)
bin/console debug:router | grep -q product_review_index
./vendor/bin/phpunit -c app/Plugin/${PLUGIN_CODE}/phpunit.xml.dist app/Plugin/${PLUGIN_CODE}/Tests

Expand All @@ -169,3 +165,86 @@ jobs:
PLUGIN_CODE: ${{ matrix.plugin_code }}
working-directory: 'ec-cube'
run: bin/console eccube:plugin:uninstall --code=${PLUGIN_CODE}

static-analysis:
name: Static Analysis
runs-on: ubuntu-24.04
# 静的解析は DB 種別に依存しないため、SQLite 1 構成で一度だけ実行する。
# (php-cs-fixer / rector は DB 不要だが、phpstan は objectManagerLoader が
# カーネルを起動し EccubeExtension が dtb_plugin を読むため本体+DBが必要)
env:
PLUGIN_CODE: ProductReview44
APP_ENV: 'test'
APP_DEBUG: 0
DATABASE_URL: 'sqlite:///var/eccube.db'
DATABASE_SERVER_VERSION: 3
DATABASE_CHARSET: 'utf8'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false

- name: Setup PHP
uses: nanasess/setup-php@master
with:
php-version: '8.5'
# xdebug が有効だと解析が大幅に遅くなるため無効化する
extensions: ':xdebug'

- name: Archive Plugin
run: |
tar cvzf ${GITHUB_WORKSPACE}/${PLUGIN_CODE}.tar.gz ./*
- name: Checkout EC-CUBE
uses: actions/checkout@v4
with:
repository: 'EC-CUBE/ec-cube'
ref: '4.4'
path: 'ec-cube'
persist-credentials: false

- name: Get Composer Cache Directory
id: composer-cache
run: |
echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT"
- uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-composer-
- name: Install to composer
working-directory: 'ec-cube'
run: composer install --no-interaction -o --apcu-autoloader --ignore-platform-req=ext-redis

- name: Setup EC-CUBE
working-directory: 'ec-cube'
run: |
# SQLite はファイルベースで CREATE DATABASE が無く, DBAL 4 では
# SQLitePlatform::getCreateDatabaseSQL が未サポートで例外になるため
# doctrine:database:create は実行しない (schema:create が DB ファイルを生成する)。
bin/console doctrine:schema:create
# プラグイン有効化時に DeviceType 等のマスタデータを参照するため fixtures を投入する
bin/console eccube:fixtures:load
- name: Setup Plugin
working-directory: 'ec-cube'
run: |
bin/console eccube:plugin:install --code=${PLUGIN_CODE} --path=${GITHUB_WORKSPACE}/${PLUGIN_CODE}.tar.gz
## enable は ProductReviewConfig エンティティを参照するため、install 後に
## cache:clear でマッピングを登録してから enable する(順序を入れ替えると MappingException)
bin/console cache:clear --no-warmup
bin/console eccube:plugin:enable --code=${PLUGIN_CODE}

- name: Run php-cs-fixer
working-directory: 'ec-cube'
run: ./vendor/bin/php-cs-fixer fix --config=app/Plugin/${PLUGIN_CODE}/Resource/.php-cs-fixer.dist.php --dry-run --diff

- name: Run Rector
working-directory: 'ec-cube'
run: ./vendor/bin/rector process --config=app/Plugin/${PLUGIN_CODE}/Resource/rector.php --dry-run

- name: Run PHPStan
working-directory: 'ec-cube'
run: |
bin/console cache:clear --no-warmup
./vendor/bin/phpstan analyse -c app/Plugin/${PLUGIN_CODE}/phpstan.neon.dist --no-progress
3 changes: 3 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ jobs:
working-directory: ../
run: |
rm -rf $GITHUB_WORKSPACE/.github
# 静的解析の設定は配布パッケージに含めない
rm -f $GITHUB_WORKSPACE/phpstan.neon.dist
rm -f $GITHUB_WORKSPACE/Resource/rector.php "$GITHUB_WORKSPACE/Resource/.php-cs-fixer.dist.php"
find $GITHUB_WORKSPACE -name "dummy" -delete
find $GITHUB_WORKSPACE -name ".git*" -and ! -name ".gitkeep" -print0 | xargs -0 rm -rf
chmod -R o+w $GITHUB_WORKSPACE
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# 静的解析・テストツールのキャッシュ
.php-cs-fixer.cache
.phpunit.result.cache
5 changes: 2 additions & 3 deletions Controller/Admin/ProductReviewController.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,8 @@ public function __construct(
protected ProductReviewRepository $productReviewRepository,
protected ProductReviewConfigRepository $productReviewConfigRepository,
protected CsvExportService $csvExportService,
private readonly PaginatorInterface $paginator
)
{
private readonly PaginatorInterface $paginator,
) {
}

/**
Expand Down
57 changes: 57 additions & 0 deletions Resource/.php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

if (php_sapi_name() !== 'cli') {
throw new \LogicException();
}

$header = <<<EOL
This file is part of EC-CUBE

Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.

http://www.ec-cube.co.jp/

For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
EOL;

$rules = [
'@Symfony' => true,
'array_syntax' => ['syntax' => 'short'],
'phpdoc_align' => false,
'phpdoc_summary' => false,
'phpdoc_annotation_without_dot' => false,
'no_superfluous_phpdoc_tags' => false,
'increment_style' => false,
'yoda_style' => false,
'header_comment' => ['header' => $header],
'phpdoc_add_missing_param_annotation' => true,
'phpdoc_param_order' => true,
'phpdoc_to_comment' => false, // /** @var */ を変換してしまうため
'phpdoc_trim' => true,
'global_namespace_import' => [
'import_classes' => false,
'import_constants' => false,
'import_functions' => false,
],
// PHPDocの型をネイティブ型へ
'phpdoc_to_param_type' => true,
'phpdoc_to_return_type' => true,
// プロパティのネイティブ型化は無効。EC-CUBE のテスト基盤が tearDown で全プロパティに
// null を代入するため、テストプロパティを非null native 型にすると TypeError になる。
'phpdoc_to_property_type' => false,
];

$finder = \PhpCsFixer\Finder::create()
->in(dirname(__DIR__))
->exclude(['vendor', 'node_modules', 'Resource'])
->name('*.php')
;
$config = new \PhpCsFixer\Config();

return $config
->setRules($rules)
->setFinder($finder)
->setRiskyAllowed(true)
->setUnsupportedPhpVersionAllowed(true)
;
61 changes: 61 additions & 0 deletions Resource/rector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

declare(strict_types=1);

/*
* This file is part of EC-CUBE
*
* Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
*
* http://www.ec-cube.co.jp/
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

use Rector\Config\RectorConfig;
use Rector\Doctrine\Set\DoctrineSetList;
use Rector\Renaming\Rector\Name\RenameClassRector;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Symfony\Set\SymfonySetList;
use Rector\ValueObject\PhpVersion;

return RectorConfig::configure()
// EC-CUBE 4.4 の最小サポートバージョンに合わせる
->withPhpVersion(PhpVersion::PHP_82)
// プラグインのソースディレクトリ
->withPaths([
dirname(__DIR__).'/Controller',
dirname(__DIR__).'/Entity',
dirname(__DIR__).'/Form',
dirname(__DIR__).'/Repository',
dirname(__DIR__).'/PluginManager.php',
dirname(__DIR__).'/ProductReviewEvent.php',
dirname(__DIR__).'/ProductReviewNav.php',
])
->withSkip([
dirname(__DIR__).'/vendor',
dirname(__DIR__).'/node_modules',
])
->withSets([
LevelSetList::UP_TO_PHP_82,
// Symfony 7.4 対応 (@Route → #[Route], @Template, buildForm(): void 等)
SymfonySetList::SYMFONY_74,
SymfonySetList::SYMFONY_CODE_QUALITY,
// Doctrine ORM 3.0 / DBAL 3.0 対応 (@ORM → #[ORM], 型付きプロパティ)
DoctrineSetList::DOCTRINE_CODE_QUALITY,
DoctrineSetList::DOCTRINE_DBAL_30,
DoctrineSetList::ANNOTATIONS_TO_ATTRIBUTES,
])
// Symfony/Doctrine 等のアノテーション → アトリビュート変換を有効化
->withAttributesSets()
// #[Route] は付与されるが use 文が旧 Annotation のまま残るため Attribute へ統一する
->withConfiguredRule(RenameClassRector::class, [
'Symfony\Component\Routing\Annotation\Route' => 'Symfony\Component\Routing\Attribute\Route',
])
->withImportNames(
importShortClasses: false,
importDocBlockNames: true,
importNames: true
)
->withParallel();
17 changes: 17 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
parameters:
level: 6
paths:
- .
excludePaths:
- Resource/*
- Tests/bootstrap.php
doctrine:
objectManagerLoader: ../../../tests/object-manager.php
ignoreErrors:
# Entity のプロパティは ?type = null にしているが、該当カラムは DB 上 not-null。
# Symfony のフォームはバリデーションの前にデータマッピングを行い、空文字は empty_data で
# null になるため、非 nullable にすると保存時に TypeError で 500 になる。
# 実行時は Doctrine が必ず値を入れるため実害はなく、本体コアの Entity も同じ形。
-
message: '#type mapping mismatch: property can contain .+ but database expects .+#'
identifier: doctrine.columnType
Loading