Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add real test and CS/PHPStan to CI #46

Merged
merged 2 commits into from
Apr 10, 2024
Merged
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
105 changes: 105 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: CI

on:
push:
pull_request:

permissions:
contents: read

jobs:
cs:
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')"

name: Coding Style

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.3"
extensions: mbstring
tools: composer:v2
coverage: none

- name: Set COMPOSER_ROOT_VERSION
run: echo "COMPOSER_ROOT_VERSION=0.3.99" >> $GITHUB_ENV

- name: Install dependencies
run: composer install --prefer-dist --no-interaction --no-progress

- name: Check Coding Style - PHP
run: vendor/bin/php-cs-fixer fix --dry-run --using-cache=no --diff --verbose

- name: Check composer.json format
run: |
composer remove --no-interaction roundcube/roundcubemail
composer validate --strict --no-check-lock && composer normalize --dry-run --no-check-lock

phpstan:
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')"

name: Static Analysis

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.3"
extensions: mbstring
tools: composer:v2
coverage: none

- name: Set COMPOSER_ROOT_VERSION
run: echo "COMPOSER_ROOT_VERSION=0.3.99" >> $GITHUB_ENV

- name: Install dependencies
run: composer install --prefer-dist --no-interaction --no-progress

- name: Run Static Analysis
run: vendor/bin/phpstan analyse

test:
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[ci skip]')"

strategy:
fail-fast: false
matrix:
php: ["7.3", "7.4", "8.0", "8.1", "8.2", "8.3"]

name: Test / PHP ${{ matrix.php }}

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: mbstring
tools: composer:v2
coverage: none

- name: Set COMPOSER_ROOT_VERSION
run: echo "COMPOSER_ROOT_VERSION=0.3.99" >> $GITHUB_ENV

- name: Test - install plugin
run: |
cd test-composer
composer install --prefer-dist --no-interaction --no-progress

- name: Test - verify install
run: |
cd test-composer
ls -lah vendor/roundcube/roundcubemail/plugins/carddav
ls -lah vendor/roundcube/roundcubemail/plugins/carddav/config.inc.php
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
composer.lock
composer.phar
/composer.lock
/vendor/

/test-composer/*
!/test-composer/composer.json
100 changes: 100 additions & 0 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?php

declare(strict_types=1);

use PhpCsFixer\Config;
use PhpCsFixer\Finder;

$finder = Finder::create()
->in([__DIR__])
->exclude(['vendor'])
->ignoreDotFiles(false);

return (new Config())
->setRiskyAllowed(true)
->setRules([
'@PhpCsFixer' => true,
'@PhpCsFixer:risky' => true,
'@PHP74Migration' => true,
'@PHP74Migration:risky' => true,

// required by PSR-12
'concat_space' => [
'spacing' => 'one',
],

// disable some too strict rules
'phpdoc_types_order' => [
'null_adjustment' => 'always_last',
'sort_algorithm' => 'none',
],
'single_line_throw' => false,
'yoda_style' => [
'equal' => false,
'identical' => false,
],
'native_constant_invocation' => true,
'native_function_invocation' => false,
'void_return' => false,
'blank_line_before_statement' => [
'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'exit'],
],
'final_internal_class' => false,
'combine_consecutive_issets' => false,
'combine_consecutive_unsets' => false,
'multiline_whitespace_before_semicolons' => false,
'no_superfluous_elseif' => false,
'ordered_class_elements' => false,
'php_unit_internal_class' => false,
'php_unit_test_class_requires_covers' => false,
'phpdoc_add_missing_param_annotation' => false,
'return_assignment' => false,
'comment_to_phpdoc' => false,
'general_phpdoc_annotation_remove' => [
'annotations' => ['author', 'copyright', 'throws'],
],

// fn => without curly brackets is less readable,
// also prevent bounding of unwanted variables for GC
'use_arrow_functions' => false,

# TODO
'align_multiline_comment' => false,
'array_indentation' => false,
'binary_operator_spaces' => false,
'blank_line_after_opening_tag' => false,
'blank_line_before_statement' => false,
'concat_space' => false,
'control_structure_continuation_position' => false,
'declare_strict_types' => false,
'explicit_string_variable' => false,
'function_declaration' => false,
'function_to_constant' => false,
'general_phpdoc_annotation_remove' => false,
'include' => false,
'list_syntax' => false,
'method_argument_space' => false,
'native_constant_invocation' => false,
'new_with_parentheses' => false,
'no_alias_functions' => false,
'no_empty_phpdoc' => false,
'no_spaces_after_function_name' => false,
'no_superfluous_phpdoc_tags' => false,
'ordered_imports' => false,
'phpdoc_indent' => false,
'phpdoc_no_alias_tag' => false,
'phpdoc_no_package' => false,
'phpdoc_separation' => false,
'phpdoc_summary' => false,
'single_line_empty_body' => false,
'single_quote' => false,
'single_space_around_construct' => false,
'spaces_inside_parentheses' => false,
'static_lambda' => false,
'strict_comparison' => false,
'strict_param' => false,
'string_implicit_backslashes' => false,
'yoda_style' => false,
])
->setFinder($finder)
->setCacheFile(sys_get_temp_dir() . '/php-cs-fixer.' . md5(__DIR__) . '.cache');
41 changes: 31 additions & 10 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "roundcube/plugin-installer",
"description": "A composer-installer for Roundcube plugins and skins.",
"license": "GPL-3.0-or-later",
"type": "composer-plugin",
"license": "GPL-3.0+",
"authors": [
{
"name": "Thomas Bruederli",
Expand All @@ -17,21 +17,42 @@
"email": "[email protected]"
}
],
"require": {
"php": ">=7.3 <8.4",
"composer-plugin-api": "^1.0 || ^2.0",
"roundcube/roundcubemail": "*"
},
"require-dev": {
"composer/composer": "^2.0",
"ergebnis/composer-normalize": "^2.13",
"friendsofphp/php-cs-fixer": "^3.0",
"phpstan/extension-installer": "^1.1",
"phpstan/phpstan": "^1.2",
"phpstan/phpstan-deprecation-rules": "^1.0",
"phpstan/phpstan-strict-rules": "^1.3"
},
"repositories": [
{
"type": "git",
"url": "https://github.com/roundcube/roundcubemail.git"
}
],
"minimum-stability": "dev",
"prefer-stable": true,
"autoload": {
"psr-0": {
"Roundcube\\Composer": "src/"
"psr-4": {
"Roundcube\\Composer\\": "src/"
}
},
"config": {
"allow-plugins": {
"ergebnis/composer-normalize": true,
"phpstan/extension-installer": true
}
},
"extra": {
"class": [
"Roundcube\\Composer\\RoundcubeInstaller"
]
},
"require": {
"composer-plugin-api": "^1.0 || ^2.0",
"roundcube/roundcubemail": "*"
},
"require-dev": {
"composer/composer": "*"
}
}
61 changes: 61 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
includes:
- phar://phpstan.phar/conf/bleedingEdge.neon

parameters:
level: 4
paths:
- .
excludePaths:
- vendor

ignoreErrors:
# relax strict rules
- '~^Only booleans are allowed in .+, .+ given( on the (left|right) side)?\.~'
- '~^Construct empty\(\) is not allowed\. Use more strict comparison\.~'
- '~^Loose comparison via "[=!]=" is not allowed\.~'

# TODO
-
message: '~^Anonymous function uses \$this assigned to variable \$self. Use \$this directly in the function body\.$~'
path: 'src/ExtensionInstaller.php'
count: 3
-
message: '~^Constant RCMAIL_VERSION not found\.$~'
path: 'src/ExtensionInstaller.php'
count: 3
-
message: '~^Call to static method db_init\(\) on an unknown class rcmail_utils\.$~'
path: 'src/ExtensionInstaller.php'
count: 1
-
message: '~^Call to static method db_update\(\) on an unknown class rcmail_utils\.$~'
path: 'src/ExtensionInstaller.php'
count: 1
-
message: '~^Method Roundcube\\Composer\\ExtensionInstaller::install\(\) should return React\\Promise\\PromiseInterface<void\|null>|null but return statement is missing\.$~'
path: 'src/ExtensionInstaller.php'
count: 3
-
message: '~^Undefined variable: \$rootdir$~'
path: 'src/ExtensionInstaller.php'
count: 1
-
message: '~^Short ternary operator is not allowed\. Use null coalesce operator if applicable or consider using long ternary\.$~'
path: 'src/ExtensionInstaller.php'
count: 1
-
message: '~^Instantiated class rcube_config not found\.$~'
path: 'src/ExtensionInstaller.php'
count: 1
-
message: '~^Call to method resolve_paths\(\) on an unknown class rcube_config\.$~'
path: 'src/ExtensionInstaller.php'
count: 1
-
message: '~^Call to function in_array\(\) requires parameter #3 to be set\.$~'
path: 'src/PluginInstaller.php'
count: 1
-
message: '~^Call to function array_search\(\) requires parameter #3 to be set\.$~'
path: 'src/PluginInstaller.php'
count: 1
File renamed without changes.
File renamed without changes.
23 changes: 23 additions & 0 deletions test-composer/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "roundcube/plugin-installer-test",
"require": {
"roundcube/carddav": "^4 || ^5"
},
"repositories": [
{
"type": "git",
"url": "https://github.com/roundcube/roundcubemail.git"
},
{
"type": "path",
"url": ".."
}
],
"minimum-stability": "dev",
"prefer-stable": true,
"config": {
"allow-plugins": {
"roundcube/plugin-installer": true
}
}
}