diff --git a/.github/workflows/ci-db-tests.yml b/.github/workflows/ci-db-tests.yml index 545e0e53..7a4aa3d1 100644 --- a/.github/workflows/ci-db-tests.yml +++ b/.github/workflows/ci-db-tests.yml @@ -16,6 +16,7 @@ jobs: php-version: [ '8.1' ] env: LC_ALL: C + extensions: openswoole-4.11.1, pdo_sqlsrv-5.10.1 steps: - name: Checkout code uses: actions/checkout@v2 @@ -25,12 +26,25 @@ jobs: - name: Start database server if: ${{ inputs.platform != 'sqlite:ci' }} run: docker-compose -f docker-compose.yml -f docker-compose.ci.yml up -d shlink_db_${{ inputs.platform }} + - name: Setup cache environment + id: extcache + uses: shivammathur/cache-extensions@v1 + with: + php-version: ${{ matrix.php-version }} + extensions: ${{ env.extensions }} + key: db-tests-extensions-${{ inputs.platform }} + - name: Cache extensions + uses: actions/cache@v2 + with: + path: ${{ steps.extcache.outputs.dir }} + key: ${{ steps.extcache.outputs.key }} + restore-keys: ${{ steps.extcache.outputs.key }} - name: Use PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-version }} tools: composer - extensions: openswoole-4.11.1, pdo_sqlsrv-5.10.1 + extensions: ${{ env.extensions }} coverage: pcov ini-values: pcov.directory=module - name: Install dependencies @@ -41,7 +55,7 @@ jobs: - name: Run tests run: composer test:db:${{ inputs.platform }} - name: Upload code coverage - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 if: ${{ matrix.php-version == '8.1' && inputs.platform == 'sqlite:ci' }} with: name: coverage-db diff --git a/.github/workflows/ci-mutation-tests.yml b/.github/workflows/ci-mutation-tests.yml index 4ed47af4..16937a2e 100644 --- a/.github/workflows/ci-mutation-tests.yml +++ b/.github/workflows/ci-mutation-tests.yml @@ -14,20 +14,35 @@ jobs: strategy: matrix: php-version: [ '8.1' ] + env: + extensions: openswoole-4.11.1 steps: - name: Checkout code uses: actions/checkout@v2 + - name: Setup cache environment + id: extcache + uses: shivammathur/cache-extensions@v1 + with: + php-version: ${{ matrix.php-version }} + extensions: ${{ env.extensions }} + key: mutation-tests-extensions-${{ inputs.test-group }} + - name: Cache extensions + uses: actions/cache@v2 + with: + path: ${{ steps.extcache.outputs.dir }} + key: ${{ steps.extcache.outputs.key }} + restore-keys: ${{ steps.extcache.outputs.key }} - name: Use PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-version }} tools: composer - extensions: openswoole-4.11.1 + extensions: ${{ env.extensions }} coverage: pcov ini-values: pcov.directory=module - name: Install dependencies run: composer install --no-interaction --prefer-dist - - uses: actions/download-artifact@v2 + - uses: actions/download-artifact@v3 with: path: build - if: ${{ inputs.test-group == 'unit' }} diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index 1d2f5063..078bc551 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -14,6 +14,8 @@ jobs: strategy: matrix: php-version: ['8.1'] + env: + extensions: openswoole-4.11.1 steps: - name: Checkout code uses: actions/checkout@v2 @@ -23,18 +25,31 @@ jobs: - name: Start maria database server if: ${{ inputs.test-group == 'cli' }} run: docker-compose -f docker-compose.yml -f docker-compose.ci.yml up -d shlink_db_maria + - name: Setup cache environment + id: extcache + uses: shivammathur/cache-extensions@v1 + with: + php-version: ${{ matrix.php-version }} + extensions: ${{ env.extensions }} + key: tests-extensions-${{ inputs.test-group }} + - name: Cache extensions + uses: actions/cache@v2 + with: + path: ${{ steps.extcache.outputs.dir }} + key: ${{ steps.extcache.outputs.key }} + restore-keys: ${{ steps.extcache.outputs.key }} - name: Use PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-version }} tools: composer - extensions: openswoole-4.11.1 + extensions: ${{ env.extensions }} coverage: pcov ini-values: pcov.directory=module - name: Install dependencies run: composer install --no-interaction --prefer-dist - run: composer test:${{ inputs.test-group }}:ci - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 if: ${{ matrix.php-version == '8.1' }} with: name: coverage-${{ inputs.test-group }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f3ed416f..c76f47bc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,15 +15,30 @@ jobs: matrix: php-version: ['8.1'] command: ['cs', 'stan', 'swagger:validate'] + env: + extensions: openswoole-4.11.1 steps: - name: Checkout code uses: actions/checkout@v2 + - name: Setup cache environment + id: extcache + uses: shivammathur/cache-extensions@v1 + with: + php-version: ${{ matrix.php-version }} + extensions: ${{ env.extensions }} + key: tests-extensions-${{ matrix.command }} + - name: Cache extensions + uses: actions/cache@v2 + with: + path: ${{ steps.extcache.outputs.dir }} + key: ${{ steps.extcache.outputs.key }} + restore-keys: ${{ steps.extcache.outputs.key }} - name: Use PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-version }} tools: composer - extensions: openswoole-4.11.1 + extensions: ${{ env.extensions }} coverage: none - name: Install dependencies run: composer install --no-interaction --prefer-dist @@ -116,7 +131,7 @@ jobs: php-version: ${{ matrix.php-version }} coverage: pcov ini-values: pcov.directory=module - - uses: actions/download-artifact@v2 + - uses: actions/download-artifact@v3 with: path: build - run: mv build/coverage-unit/coverage-unit.cov build/coverage-unit.cov diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 4903fe52..6ff6ec15 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -25,7 +25,7 @@ jobs: run: ./build.sh ${GITHUB_REF#refs/tags/v} - if: ${{ matrix.swoole == 'no' }} run: ./build.sh ${GITHUB_REF#refs/tags/v} --no-swoole - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: name: dist-files-${{ matrix.php-version }}-${{ matrix.swoole }} path: build @@ -36,7 +36,7 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v2 - - uses: actions/download-artifact@v2 + - uses: actions/download-artifact@v3 with: path: build - name: Publish release with assets diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5f620893..feb437ad 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -123,8 +123,7 @@ Depending on the kind of contribution, maybe not all kinds of tests are needed, * Run `./indocker composer test:api` to run API E2E tests. For these, the Postgres database engine is used. * Run `./indocker composer test:cli` to run CLI E2E tests. For these, the Maria DB database engine is used. * Run `./indocker composer infect:test` to run both unit and database tests (over sqlite) and then apply mutations to them with [infection](https://infection.github.io/). -* Run `./indocker composer ci` to run all previous commands together. This command is run during the project's continuous integration. -* Run `./indocker composer ci:parallel` to do the same as in previous case, but parallelizing non-conflicting tasks as much as possible. +* Run `./indocker composer ci` to run all previous commands together, parallelizing non-conflicting tasks as much as possible. ## Pull request process @@ -136,7 +135,7 @@ Once everything is clear, to provide a pull request to this project, you should The base branch should always be `develop`, and the target branch for the pull request should also be `develop`. -Before your branch can be merged, all the checks described in [Running code checks](#running-code-checks) have to be passing. You can verify that manually by running `./indocker composer ci:parallel`, or wait for the build to be run automatically after the pull request is created. +Before your branch can be merged, all the checks described in [Running code checks](#running-code-checks) have to be passing. You can verify that manually by running `./indocker composer ci`, or wait for the build to be run automatically after the pull request is created. ## Architectural Decision Records diff --git a/composer.json b/composer.json index 627829aa..0cc0e65c 100644 --- a/composer.json +++ b/composer.json @@ -99,13 +99,6 @@ }, "scripts": { "ci": [ - "@cs", - "@stan", - "@swagger:validate", - "@test:ci", - "@infect:ci" - ], - "ci:parallel": [ "@parallel cs stan swagger:validate test:unit:ci test:db:sqlite:ci test:db:mysql test:db:maria test:db:postgres test:db:ms", "@parallel infect:test:api infect:test:cli infect:ci:unit infect:ci:db" ], @@ -113,19 +106,11 @@ "cs:fix": "phpcbf", "stan": "APP_ENV=test php vendor/bin/phpstan analyse module/*/src module/*/config config docker/config data/migrations --level=8", "test": [ - "@test:unit", - "@test:db", - "@test:api", - "@test:cli" + "@parallel test:unit test:db", + "@parallel test:api test:cli" ], - "test:ci": [ - "@test:unit:ci", - "@test:db", - "@test:api:ci", - "@test:cli:ci" - ], - "test:unit": "@php vendor/bin/phpunit --order-by=random --colors=always --coverage-php build/coverage-unit.cov --testdox", - "test:unit:ci": "@test:unit --coverage-xml=build/coverage-unit/coverage-xml --log-junit=build/coverage-unit/junit.xml", + "test:unit": "@php vendor/bin/phpunit --order-by=random --colors=always --testdox", + "test:unit:ci": "@test:unit --coverage-php=build/coverage-unit.cov --coverage-xml=build/coverage-unit/coverage-xml --log-junit=build/coverage-unit/junit.xml", "test:unit:pretty": "@test:unit --coverage-html build/coverage-unit/coverage-html", "test:db": "@parallel test:db:sqlite:ci test:db:mysql test:db:maria test:db:postgres test:db:ms", "test:db:sqlite": "APP_ENV=test php vendor/bin/phpunit --order-by=random --colors=always --testdox -c phpunit-db.xml", @@ -136,8 +121,10 @@ "test:db:ms": "DB_DRIVER=mssql composer test:db:sqlite", "test:api": "bin/test/run-api-tests.sh", "test:api:ci": "GENERATE_COVERAGE=yes composer test:api", - "test:cli": "APP_ENV=test DB_DRIVER=maria TEST_ENV=cli php vendor/bin/phpunit --order-by=random --colors=always --testdox -c phpunit-cli.xml", - "test:cli:ci": "GENERATE_COVERAGE=yes composer test:cli -- --log-junit=build/coverage-cli/junit.xml", + "test:api:pretty": "GENERATE_COVERAGE=pretty composer test:api", + "test:cli": "APP_ENV=test DB_DRIVER=maria TEST_ENV=cli php vendor/bin/phpunit --order-by=random --colors=always --testdox -c phpunit-cli.xml --log-junit=build/coverage-cli/junit.xml", + "test:cli:ci": "GENERATE_COVERAGE=yes composer test:cli", + "test:cli:pretty": "GENERATE_COVERAGE=pretty composer test:cli", "infect:ci:base": "infection --threads=4 --log-verbosity=default --only-covered --only-covering-test-cases --skip-initial-tests", "infect:ci:unit": "@infect:ci:base --coverage=build/coverage-unit --min-msi=84", "infect:ci:db": "@infect:ci:base --coverage=build/coverage-db --min-msi=95 --configuration=infection-db.json", @@ -166,12 +153,10 @@ }, "scripts-descriptions": { "ci": "Alias for \"cs\", \"stan\", \"swagger:validate\", \"test:ci\" and \"infect:ci\"", - "ci:parallel": "Same as \"ci\", but parallelizing tasks as much as possible", "cs": "Checks coding styles", "cs:fix": "Fixes coding styles, when possible", "stan": "Inspects code with phpstan", "test": "Runs all test suites", - "test:ci": "Runs all test suites, generating all needed reports and logs for CI envs", "test:unit": "Runs unit test suites", "test:unit:ci": "Runs unit test suites, generating all needed reports and logs for CI envs", "test:unit:pretty": "Runs unit test suites and generates an HTML code coverage report", @@ -183,7 +168,11 @@ "test:db:postgres": "Runs database test suites on a PostgreSQL database", "test:db:ms": "Runs database test suites on a Microsoft SQL Server database", "test:api": "Runs API test suites", - "test:api:ci": "Runs API test suites, and generates code coverage reports", + "test:api:ci": "Runs API test suites, and generates code coverage for CI", + "test:api:pretty": "Runs API test suites, and generates code coverage in HTML format", + "test:cli": "Runs CLI test suites", + "test:cli:ci": "Runs CLI test suites, and generates code coverage for CI", + "test:cli:pretty": "Runs CLI test suites, and generates code coverage in HTML format", "infect:ci": "Checks unit and db tests quality applying mutation testing with existing reports and logs", "infect:ci:unit": "Checks unit tests quality applying mutation testing with existing reports and logs", "infect:ci:db": "Checks db tests quality applying mutation testing with existing reports and logs", diff --git a/config/test/test_config.global.php b/config/test/test_config.global.php index e82d9da5..8998dd22 100644 --- a/config/test/test_config.global.php +++ b/config/test/test_config.global.php @@ -28,6 +28,7 @@ use Symfony\Component\Console\Event\ConsoleTerminateEvent; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use function file_exists; +use function Functional\contains; use function Laminas\Stratigility\middleware; use function Shlinkio\Shlink\Config\env; use function sprintf; @@ -39,7 +40,8 @@ use const ShlinkioTest\Shlink\SWOOLE_TESTING_PORT; $isApiTest = env('TEST_ENV') === 'api'; $isCliTest = env('TEST_ENV') === 'cli'; $isE2eTest = $isApiTest || $isCliTest; -$generateCoverage = env('GENERATE_COVERAGE') === 'yes'; +$coverageType = env('GENERATE_COVERAGE'); +$generateCoverage = contains(['yes', 'pretty'], $coverageType); $coverage = null; if ($isE2eTest && $generateCoverage) { @@ -52,7 +54,7 @@ if ($isE2eTest && $generateCoverage) { /** * @param 'api'|'cli' $type */ -$exportCoverage = static function (string $type = 'api') use (&$coverage): void { +$exportCoverage = static function (string $type = 'api') use (&$coverage, $coverageType): void { if ($coverage === null) { return; } @@ -66,9 +68,12 @@ $exportCoverage = static function (string $type = 'api') use (&$coverage): void $coverage->merge(require $covPath); } - (new PHP())->process($coverage, $covPath); - (new Xml(Version::getVersionString()))->process($coverage, $basePath . '/coverage-xml'); - (new Html())->process($coverage, $basePath . '/coverage-html'); + if ($coverageType === 'pretty') { + (new Html())->process($coverage, $basePath . '/coverage-html'); + } else { + (new PHP())->process($coverage, $covPath); + (new Xml(Version::getVersionString()))->process($coverage, $basePath . '/coverage-xml'); + } }; $buildDbConnection = static function (): array {