Skip to content

Commit 6661328

Browse files
authored
Merge pull request #46 from mvorisek/cs
Add real test and CS/PHPStan to CI
2 parents c22f795 + ab42c3d commit 6661328

10 files changed

Lines changed: 325 additions & 12 deletions

File tree

.github/workflows/ci.yml

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
cs:
12+
runs-on: ubuntu-latest
13+
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')"
14+
15+
name: Coding Style
16+
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
21+
- name: Setup PHP
22+
uses: shivammathur/setup-php@v2
23+
with:
24+
php-version: "8.3"
25+
extensions: mbstring
26+
tools: composer:v2
27+
coverage: none
28+
29+
- name: Set COMPOSER_ROOT_VERSION
30+
run: echo "COMPOSER_ROOT_VERSION=0.3.99" >> $GITHUB_ENV
31+
32+
- name: Install dependencies
33+
run: composer install --prefer-dist --no-interaction --no-progress
34+
35+
- name: Check Coding Style - PHP
36+
run: vendor/bin/php-cs-fixer fix --dry-run --using-cache=no --diff --verbose
37+
38+
- name: Check composer.json format
39+
run: |
40+
composer remove --no-interaction roundcube/roundcubemail
41+
composer validate --strict --no-check-lock && composer normalize --dry-run --no-check-lock
42+
43+
phpstan:
44+
runs-on: ubuntu-latest
45+
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')"
46+
47+
name: Static Analysis
48+
49+
steps:
50+
- name: Checkout code
51+
uses: actions/checkout@v4
52+
53+
- name: Setup PHP
54+
uses: shivammathur/setup-php@v2
55+
with:
56+
php-version: "8.3"
57+
extensions: mbstring
58+
tools: composer:v2
59+
coverage: none
60+
61+
- name: Set COMPOSER_ROOT_VERSION
62+
run: echo "COMPOSER_ROOT_VERSION=0.3.99" >> $GITHUB_ENV
63+
64+
- name: Install dependencies
65+
run: composer install --prefer-dist --no-interaction --no-progress
66+
67+
- name: Run Static Analysis
68+
run: vendor/bin/phpstan analyse
69+
70+
test:
71+
runs-on: ubuntu-latest
72+
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')"
73+
74+
strategy:
75+
fail-fast: false
76+
matrix:
77+
php: ["7.3", "7.4", "8.0", "8.1", "8.2", "8.3"]
78+
79+
name: Test / PHP ${{ matrix.php }}
80+
81+
steps:
82+
- name: Checkout code
83+
uses: actions/checkout@v4
84+
85+
- name: Setup PHP
86+
uses: shivammathur/setup-php@v2
87+
with:
88+
php-version: ${{ matrix.php }}
89+
extensions: mbstring
90+
tools: composer:v2
91+
coverage: none
92+
93+
- name: Set COMPOSER_ROOT_VERSION
94+
run: echo "COMPOSER_ROOT_VERSION=0.3.99" >> $GITHUB_ENV
95+
96+
- name: Test - install plugin
97+
run: |
98+
cd test-composer
99+
composer install --prefer-dist --no-interaction --no-progress
100+
101+
- name: Test - verify install
102+
run: |
103+
cd test-composer
104+
ls -lah vendor/roundcube/roundcubemail/plugins/carddav
105+
ls -lah vendor/roundcube/roundcubemail/plugins/carddav/config.inc.php

.gitignore

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
1-
composer.lock
2-
composer.phar
1+
/composer.lock
2+
/vendor/
3+
4+
/test-composer/*
5+
!/test-composer/composer.json

.php-cs-fixer.dist.php

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use PhpCsFixer\Config;
6+
use PhpCsFixer\Finder;
7+
8+
$finder = Finder::create()
9+
->in([__DIR__])
10+
->exclude(['vendor'])
11+
->ignoreDotFiles(false);
12+
13+
return (new Config())
14+
->setRiskyAllowed(true)
15+
->setRules([
16+
'@PhpCsFixer' => true,
17+
'@PhpCsFixer:risky' => true,
18+
'@PHP74Migration' => true,
19+
'@PHP74Migration:risky' => true,
20+
21+
// required by PSR-12
22+
'concat_space' => [
23+
'spacing' => 'one',
24+
],
25+
26+
// disable some too strict rules
27+
'phpdoc_types_order' => [
28+
'null_adjustment' => 'always_last',
29+
'sort_algorithm' => 'none',
30+
],
31+
'single_line_throw' => false,
32+
'yoda_style' => [
33+
'equal' => false,
34+
'identical' => false,
35+
],
36+
'native_constant_invocation' => true,
37+
'native_function_invocation' => false,
38+
'void_return' => false,
39+
'blank_line_before_statement' => [
40+
'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'exit'],
41+
],
42+
'final_internal_class' => false,
43+
'combine_consecutive_issets' => false,
44+
'combine_consecutive_unsets' => false,
45+
'multiline_whitespace_before_semicolons' => false,
46+
'no_superfluous_elseif' => false,
47+
'ordered_class_elements' => false,
48+
'php_unit_internal_class' => false,
49+
'php_unit_test_class_requires_covers' => false,
50+
'phpdoc_add_missing_param_annotation' => false,
51+
'return_assignment' => false,
52+
'comment_to_phpdoc' => false,
53+
'general_phpdoc_annotation_remove' => [
54+
'annotations' => ['author', 'copyright', 'throws'],
55+
],
56+
57+
// fn => without curly brackets is less readable,
58+
// also prevent bounding of unwanted variables for GC
59+
'use_arrow_functions' => false,
60+
61+
# TODO
62+
'align_multiline_comment' => false,
63+
'array_indentation' => false,
64+
'binary_operator_spaces' => false,
65+
'blank_line_after_opening_tag' => false,
66+
'blank_line_before_statement' => false,
67+
'concat_space' => false,
68+
'control_structure_continuation_position' => false,
69+
'declare_strict_types' => false,
70+
'explicit_string_variable' => false,
71+
'function_declaration' => false,
72+
'function_to_constant' => false,
73+
'general_phpdoc_annotation_remove' => false,
74+
'include' => false,
75+
'list_syntax' => false,
76+
'method_argument_space' => false,
77+
'native_constant_invocation' => false,
78+
'new_with_parentheses' => false,
79+
'no_alias_functions' => false,
80+
'no_empty_phpdoc' => false,
81+
'no_spaces_after_function_name' => false,
82+
'no_superfluous_phpdoc_tags' => false,
83+
'ordered_imports' => false,
84+
'phpdoc_indent' => false,
85+
'phpdoc_no_alias_tag' => false,
86+
'phpdoc_no_package' => false,
87+
'phpdoc_separation' => false,
88+
'phpdoc_summary' => false,
89+
'single_line_empty_body' => false,
90+
'single_quote' => false,
91+
'single_space_around_construct' => false,
92+
'spaces_inside_parentheses' => false,
93+
'static_lambda' => false,
94+
'strict_comparison' => false,
95+
'strict_param' => false,
96+
'string_implicit_backslashes' => false,
97+
'yoda_style' => false,
98+
])
99+
->setFinder($finder)
100+
->setCacheFile(sys_get_temp_dir() . '/php-cs-fixer.' . md5(__DIR__) . '.cache');

composer.json

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"name": "roundcube/plugin-installer",
33
"description": "A composer-installer for Roundcube plugins and skins.",
4+
"license": "GPL-3.0-or-later",
45
"type": "composer-plugin",
5-
"license": "GPL-3.0+",
66
"authors": [
77
{
88
"name": "Thomas Bruederli",
@@ -17,21 +17,42 @@
1717
"email": "roundcube@tehinterweb.co.uk"
1818
}
1919
],
20+
"require": {
21+
"php": ">=7.3 <8.4",
22+
"composer-plugin-api": "^1.0 || ^2.0",
23+
"roundcube/roundcubemail": "*"
24+
},
25+
"require-dev": {
26+
"composer/composer": "^2.0",
27+
"ergebnis/composer-normalize": "^2.13",
28+
"friendsofphp/php-cs-fixer": "^3.0",
29+
"phpstan/extension-installer": "^1.1",
30+
"phpstan/phpstan": "^1.2",
31+
"phpstan/phpstan-deprecation-rules": "^1.0",
32+
"phpstan/phpstan-strict-rules": "^1.3"
33+
},
34+
"repositories": [
35+
{
36+
"type": "git",
37+
"url": "https://github.com/roundcube/roundcubemail.git"
38+
}
39+
],
40+
"minimum-stability": "dev",
41+
"prefer-stable": true,
2042
"autoload": {
21-
"psr-0": {
22-
"Roundcube\\Composer": "src/"
43+
"psr-4": {
44+
"Roundcube\\Composer\\": "src/"
45+
}
46+
},
47+
"config": {
48+
"allow-plugins": {
49+
"ergebnis/composer-normalize": true,
50+
"phpstan/extension-installer": true
2351
}
2452
},
2553
"extra": {
2654
"class": [
2755
"Roundcube\\Composer\\RoundcubeInstaller"
2856
]
29-
},
30-
"require": {
31-
"composer-plugin-api": "^1.0 || ^2.0",
32-
"roundcube/roundcubemail": "*"
33-
},
34-
"require-dev": {
35-
"composer/composer": "*"
3657
}
3758
}

phpstan.neon.dist

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
includes:
2+
- phar://phpstan.phar/conf/bleedingEdge.neon
3+
4+
parameters:
5+
level: 4
6+
paths:
7+
- .
8+
excludePaths:
9+
- vendor
10+
11+
ignoreErrors:
12+
# relax strict rules
13+
- '~^Only booleans are allowed in .+, .+ given( on the (left|right) side)?\.~'
14+
- '~^Construct empty\(\) is not allowed\. Use more strict comparison\.~'
15+
- '~^Loose comparison via "[=!]=" is not allowed\.~'
16+
17+
# TODO
18+
-
19+
message: '~^Anonymous function uses \$this assigned to variable \$self. Use \$this directly in the function body\.$~'
20+
path: 'src/ExtensionInstaller.php'
21+
count: 3
22+
-
23+
message: '~^Constant RCMAIL_VERSION not found\.$~'
24+
path: 'src/ExtensionInstaller.php'
25+
count: 3
26+
-
27+
message: '~^Call to static method db_init\(\) on an unknown class rcmail_utils\.$~'
28+
path: 'src/ExtensionInstaller.php'
29+
count: 1
30+
-
31+
message: '~^Call to static method db_update\(\) on an unknown class rcmail_utils\.$~'
32+
path: 'src/ExtensionInstaller.php'
33+
count: 1
34+
-
35+
message: '~^Method Roundcube\\Composer\\ExtensionInstaller::install\(\) should return React\\Promise\\PromiseInterface<void\|null>|null but return statement is missing\.$~'
36+
path: 'src/ExtensionInstaller.php'
37+
count: 3
38+
-
39+
message: '~^Undefined variable: \$rootdir$~'
40+
path: 'src/ExtensionInstaller.php'
41+
count: 1
42+
-
43+
message: '~^Short ternary operator is not allowed\. Use null coalesce operator if applicable or consider using long ternary\.$~'
44+
path: 'src/ExtensionInstaller.php'
45+
count: 1
46+
-
47+
message: '~^Instantiated class rcube_config not found\.$~'
48+
path: 'src/ExtensionInstaller.php'
49+
count: 1
50+
-
51+
message: '~^Call to method resolve_paths\(\) on an unknown class rcube_config\.$~'
52+
path: 'src/ExtensionInstaller.php'
53+
count: 1
54+
-
55+
message: '~^Call to function in_array\(\) requires parameter #3 to be set\.$~'
56+
path: 'src/PluginInstaller.php'
57+
count: 1
58+
-
59+
message: '~^Call to function array_search\(\) requires parameter #3 to be set\.$~'
60+
path: 'src/PluginInstaller.php'
61+
count: 1
File renamed without changes.
File renamed without changes.
File renamed without changes.

test-composer/composer.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "roundcube/plugin-installer-test",
3+
"require": {
4+
"roundcube/carddav": "^4 || ^5"
5+
},
6+
"repositories": [
7+
{
8+
"type": "git",
9+
"url": "https://github.com/roundcube/roundcubemail.git"
10+
},
11+
{
12+
"type": "path",
13+
"url": ".."
14+
}
15+
],
16+
"minimum-stability": "dev",
17+
"prefer-stable": true,
18+
"config": {
19+
"allow-plugins": {
20+
"roundcube/plugin-installer": true
21+
}
22+
}
23+
}

0 commit comments

Comments
 (0)