diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..30cc58f --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,21 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + + # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + + # Maintain dependencies for Composer + - package-ecosystem: "composer" + directory: "/" + schedule: + interval: "weekly" + ignore: + - dependency-name: "oxid-esales/oxideshop-ce" diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml new file mode 100644 index 0000000..7eb1046 --- /dev/null +++ b/.github/workflows/development.yml @@ -0,0 +1,511 @@ +name: Development + +on: + workflow_call: + inputs: + php: + required: true + type: string + mysql: + required: true + type: string + template_engine: + type: string + default: 'both' + module_codecept_test_group: + type: string + default: 'fa_sitemap' + report_sonarcloud: + type: boolean + default: false + + workflow_dispatch: + inputs: + php: + description: 'PHP version' + required: true + default: '8.0' + type: choice + options: + - '8.0' + - '8.1' + mysql: + description: 'MySQL version' + required: true + default: '5.7.37' + type: choice + options: + - '5.7.37' + - '8.0' + template_engine: + description: 'Template engine - smarty with flow theme, twig with twig theme' + required: true + default: 'twig' + type: choice + options: + - 'both' + - 'twig' + - 'smarty' + module_codecept_test_group: + description: 'Module codeception test group' + required: true + default: 'fa_sitemap' + type: string + report_sonarcloud: + description: 'Trigger sonarcloud analize?' + required: true + default: true + type: boolean + +env: + PACKAGE_NAME: 'fresh-advance/sitemap' + MODULE_IDS: 'fa_sitemap' + SONARCLOUD_ORGANIZATION: 'fresh-advance' + SONARCLOUD_PROJECT_KEY: 'Fresh-Advance_Sitemap' + +jobs: + install_shop_with_module: + runs-on: ubuntu-latest + steps: + - name: Clone testing environment + run: git clone https://github.com/OXID-eSales/docker-eshop-sdk.git . + + - name: Clone the shop + run: git clone --depth 1 https://github.com/OXID-eSales/oxideshop_ce.git --branch b-7.0.x --single-branch source + + - name: Cache current installation + uses: actions/cache@v3 + with: + path: | + ./* + key: installation-${{ join(inputs.*, '-') }}-${{ github.run_number }}-${{ github.run_attempt }} + + - name: Prepare container configuration + run: | + make setup + make addbasicservices + make file=services/selenium-chrome.yml addservice + perl -pi\ + -e 's#PHP_VERSION=.*#PHP_VERSION=${{ inputs.php }}#g;'\ + -e "s#MYSQL_VERSION=.*#MYSQL_VERSION=${{ inputs.mysql }}#g;"\ + .env + perl -pi\ + -e 's#display_errors =.*#display_errors = false#g;'\ + -e 's#error_reporting = .*#error_reporting = E_ALL ^ E_WARNING ^ E_DEPRECATED#g;'\ + -e 'print "xdebug.max_nesting_level=1000\nxdebug.mode=coverage\n\n"'\ + containers/php/custom.ini + perl -pi\ + -e 's#/var/www/#/var/www/source/#g;'\ + containers/httpd/project.conf + + - name: Prepare shop configuration + run: | + cp source/source/config.inc.php.dist source/source/config.inc.php + sed -i "1s+^+SetEnvIf Authorization "\(.*\)" HTTP_AUTHORIZATION=\$1\n\n+" source/source/.htaccess + sed -i -e 's//mysql/'\ + -e 's//root/'\ + -e 's//example/'\ + -e 's//root/'\ + -e 's//3306/'\ + -e 's//http:\/\/localhost.local\//'\ + -e 's//\/var\/www\/source\//'\ + -e 's//\/var\/www\/source\/tmp\//'\ + source/source/config.inc.php + + - name: Checkout current module + uses: actions/checkout@v4 + with: + path: source/test-module + + - name: Start containers + run: | + make up + sleep 2 + + - name: Install module + run: | + docker-compose exec -T \ + php composer config repositories.${{ env.PACKAGE_NAME }} \ + --json '{"type":"path", "url":"./test-module", "options": {"symlink": true}}' + docker-compose exec -T \ + php composer require ${{ env.PACKAGE_NAME }}:* --no-interaction --no-update + + - name: Install dependencies and reset shop + run: | + docker-compose exec -T php composer update --no-interaction + docker-compose exec -T php bin/oe-console oe:database:reset \ + --db-host=mysql --db-port=3306 --db-name=example --db-user=root --db-password=root --force + docker-compose exec -T php bin/oe-console oe:module:activate fa_sitemap + + - name: Stop containers + run: | + docker-compose down + sleep 2 + + - name: Show docker log + if: always() + run: | + docker-compose logs + + - name: Upload configuration artifacts + if: always() + uses: actions/upload-artifact@v3 + with: + name: Configs-${{ inputs.php }}-${{ inputs.mysql }}-${{ inputs.template_engine }} + path: | + docker-compose.yml + source/composer.json + source/composer.lock + source/source/config.inc.php + + styles: + needs: [ install_shop_with_module ] + runs-on: ubuntu-latest + steps: + - name: Load current installation from cache + uses: actions/cache@v3 + with: + path: | + ./* + key: installation-${{ join(inputs.*, '-') }}-${{ github.run_number }}-${{ github.run_attempt }} + restore-keys: | + installation-${{ join(inputs.*, '-') }}-${{ github.run_number }}-${{ github.run_attempt }} + + - name: Start containers + run: | + make up + sleep 2 + + - name: Install module dependencies + run: | + docker-compose exec -T \ + --workdir=/var/www/test-module \ + php composer install + + - name: Run phpcs + if: always() + run: | + docker-compose exec -T \ + --workdir=/var/www/test-module \ + php composer phpcs + + - name: Run phpstan scan and show results + id: phpstan + if: always() + run: | + docker-compose exec -T \ + --workdir=/var/www/test-module \ + php composer phpstan + + - name: Run phpstan scan and generate report for further processing + if: always() + run: | + docker-compose exec -T \ + --workdir=/var/www/test-module \ + php composer phpstan-report + + - name: Stop containers + if: always() + run: | + make down + sleep 2 + + - name: Upload log artifact + if: always() + uses: actions/upload-artifact@v3 + with: + name: StylesLog-${{ inputs.php }} + path: | + source/test-module/phpstan.report.json + source/test-module/phpmd.report.json + + integration_tests: + needs: [ install_shop_with_module ] + runs-on: ubuntu-latest + steps: + - name: Load current installation from cache + uses: actions/cache@v3 + with: + path: | + ./* + key: installation-${{ join(inputs.*, '-') }}-${{ github.run_number }}-${{ github.run_attempt }} + restore-keys: | + installation-${{ join(inputs.*, '-') }}-${{ github.run_number }}-${{ github.run_attempt }} + + - name: Start containers + run: | + make up + sleep 2 + + - name: Run tests + run: | + docker-compose exec -T \ + -e XDEBUG_MODE=coverage \ + php php vendor/bin/phpunit \ + -c /var/www/vendor/${{ env.PACKAGE_NAME }}/tests/phpunit.xml \ + --testsuite=Integration \ + --bootstrap=/var/www/source/bootstrap.php \ + --coverage-text \ + --coverage-php=/var/www/integration.cov + + - name: Upload log artifact + if: always() + uses: actions/upload-artifact@v3 + with: + name: ModuleIntegrationTestsLog-${{ inputs.php }}-${{ inputs.mysql }}-${{ inputs.template_engine }} + path: | + source/integration.cov + source/source/log/oxideshop.log + data/php/logs/error_log.txt + + - name: Stop containers + if: always() + run: | + docker-compose down + sleep 2 + + unit_tests: + needs: [ install_shop_with_module ] + runs-on: ubuntu-latest + steps: + - name: Load current installation from cache + uses: actions/cache@v3 + with: + path: | + ./* + key: installation-${{ join(inputs.*, '-') }}-${{ github.run_number }}-${{ github.run_attempt }} + restore-keys: | + installation-${{ join(inputs.*, '-') }}-${{ github.run_number }}-${{ github.run_attempt }} + + - name: Start containers + run: | + make up + sleep 2 + + - name: Run tests + run: | + docker-compose exec -T \ + -e XDEBUG_MODE=coverage \ + php php vendor/bin/phpunit \ + -c /var/www/vendor/${{ env.PACKAGE_NAME }}/tests/phpunit.xml \ + --testsuite=Unit \ + --coverage-text \ + --coverage-php=/var/www/unit.cov + + - name: Upload log artifact + if: always() + uses: actions/upload-artifact@v3 + with: + name: ModuleUnitTestsLog-${{ inputs.php }}-${{ inputs.mysql }}-${{ inputs.template_engine }} + path: | + source/unit.cov + source/source/log/oxideshop.log + data/php/logs/error_log.txt + + - name: Stop containers + if: always() + run: | + docker-compose down + sleep 2 + + codeception_twig: + needs: [ install_shop_with_module ] + if: ${{ inputs.template_engine == 'both' || inputs.template_engine == 'twig' }} + runs-on: ubuntu-latest + steps: + - name: Load current installation from cache + uses: actions/cache@v3 + with: + path: | + ./* + key: installation-${{ join(inputs.*, '-') }}-${{ github.run_number }}-${{ github.run_attempt }} + restore-keys: | + installation-${{ join(inputs.*, '-') }}-${{ github.run_number }}-${{ github.run_attempt }} + + - name: Start containers + run: | + make up + sleep 2 + + - name: Install twig template engine and twig theme + run: | + docker-compose exec -T php composer require oxid-esales/twig-component:dev-b-7.0.x --no-update + docker-compose exec -T php composer require oxid-esales/twig-admin-theme:dev-b-7.0.x --no-update + docker-compose exec -T php composer require oxid-esales/twig-theme:dev-b-7.0.x --no-update + docker-compose exec -T php composer update --no-interaction + + - name: Run tests + run: | + docker-compose exec -T \ + -e SELENIUM_SERVER_HOST=selenium \ + -e BROWSER_NAME=chrome \ + -e THEME_ID=twig \ + -e MODULE_IDS=${{ env.MODULE_IDS }} \ + php vendor/bin/codecept run acceptance \ + -c /var/www/vendor/${{ env.PACKAGE_NAME }}/tests/codeception.yml -g ${{ inputs.module_codecept_test_group }} + + - name: Upload log artifact + if: always() + uses: actions/upload-artifact@v3 + with: + name: ModuleCodeceptionTestsLog-${{ inputs.php }}-${{ inputs.mysql }}-${{ inputs.template_engine }} + path: | + docker-compose.yml + source/composer.json + source/composer.lock + source/source/config.inc.php + source/source/log/oxideshop.log + data/php/logs/error_log.txt + source/tests/Codeception/_output + + - name: Stop containers + if: always() + run: | + make down + sleep 2 + + codeception_smarty: + needs: [ install_shop_with_module ] + if: ${{ inputs.template_engine == 'both' || inputs.template_engine == 'smarty' }} + runs-on: ubuntu-latest + steps: + - name: Load current installation from cache + uses: actions/cache@v3 + with: + path: | + ./* + key: installation-${{ join(inputs.*, '-') }}-${{ github.run_number }}-${{ github.run_attempt }} + restore-keys: | + installation-${{ join(inputs.*, '-') }}-${{ github.run_number }}-${{ github.run_attempt }} + + - name: Reconfigure codeception for smarty themes + run: | + perl -pi \ + -e 's#admin_twig#admin_smarty#g;' \ + -e 's#views/twig#views/flow/translations#g;' \ + -e 's#theme_id:\s?twig#theme_id: flow#g;' \ + source/test-module/tests/Codeception/acceptance.suite.yml + + - name: Start containers + run: | + make up + sleep 2 + - name: Install smarty template engine and flow theme + run: | + docker-compose exec -T php composer require oxid-esales/smarty-component:dev-b-7.0.x --no-update + docker-compose exec -T php composer require oxid-esales/smarty-admin-theme:dev-b-7.0.x --no-update + docker-compose exec -T php composer require oxid-esales/flow-theme:dev-b-7.0.x --no-update + docker-compose exec -T php composer update --no-interaction + + - name: Install codeception-page-objects for flow theme + run: | + docker-compose exec -T php composer require oxid-esales/codeception-page-objects:dev-b-7.0.x-SMARTY --no-update + docker-compose exec -T php composer require oxid-esales/codeception-modules:dev-b-7.0.x --no-update + docker-compose exec -T php composer update --no-interaction + + - name: Run tests + run: | + docker-compose exec -T \ + -e SELENIUM_SERVER_HOST=selenium \ + -e BROWSER_NAME=chrome \ + -e THEME_ID=flow \ + -e MODULE_IDS=${{ env.MODULE_IDS }} \ + php vendor/bin/codecept run acceptance \ + -c /var/www/vendor/${{ env.PACKAGE_NAME }}/tests/codeception.yml -g ${{ inputs.module_codecept_test_group }} + + - name: Upload log artifact + if: always() + uses: actions/upload-artifact@v3 + with: + name: sModuleCodeceptionTestsLog-${{ inputs.php }}-${{ inputs.mysql }}-${{ inputs.template_engine }} + path: | + docker-compose.yml + source/composer.json + source/composer.lock + source/source/config.inc.php + source/source/log/oxideshop.log + data/php/logs/error_log.txt + source/tests/Codeception/_output + + - name: Stop containers + if: always() + run: | + make down + sleep 2 + + prepare_coverage_results: + needs: [ unit_tests, integration_tests ] + if: ${{ always() && inputs.report_sonarcloud }} + runs-on: ubuntu-latest + steps: + - name: Load current installation from cache + uses: actions/cache@v3 + with: + path: | + ./* + key: installation-${{ join(inputs.*, '-') }}-${{ github.run_number }}-${{ github.run_attempt }} + restore-keys: | + installation-${{ join(inputs.*, '-') }}-${{ github.run_number }}-${{ github.run_attempt }} + + - name: Download unit artifacts + uses: actions/download-artifact@v3 + with: + name: ModuleUnitTestsLog-${{ inputs.php }}-${{ inputs.mysql }}-${{ inputs.template_engine }} + path: ./source/coverage/ + + - name: Download integration artifacts + uses: actions/download-artifact@v3 + with: + name: ModuleIntegrationTestsLog-${{ inputs.php }}-${{ inputs.mysql }}-${{ inputs.template_engine }} + path: ./source/coverage/ + + - name: Start containers + run: | + make up + sleep 2 + + - name: Collect and merge coverage reports + continue-on-error: true + run: | + ls -alh source/coverage/source + wget https://phar.phpunit.de/phpcov-8.2.1.phar + mv phpcov-8.2.1.phar source/phpcov.phar + docker-compose exec -T php php phpcov.phar merge --clover coverage.xml ./coverage/source + sed -i 's+/var/www/test-module/+./+' source/coverage.xml + + - name: Upload log artifact + uses: actions/upload-artifact@v3 + with: + name: TestsLog-${{ inputs.php }}-${{ inputs.mysql }} + path: source/coverage.xml + + sonarcloud: + needs: [ prepare_coverage_results ] + if: ${{ always() && inputs.report_sonarcloud }} + runs-on: ubuntu-latest + steps: + - name: Checkout current module + uses: actions/checkout@v4 + + - name: Download TestsLog artifacts + continue-on-error: true + uses: actions/download-artifact@v3 + with: + name: TestsLog-${{ inputs.php }}-${{ inputs.mysql }} + path: ./tests/ + + - name: SonarCloud Scan + uses: sonarsource/sonarcloud-github-action@master + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + args: > + -Dsonar.organization=${{ env.SONARCLOUD_ORGANIZATION }} + -Dsonar.projectKey=${{ env.SONARCLOUD_PROJECT_KEY }} + -Dsonar.sources=src + -Dsonar.tests=tests + -Dsonar.sourceEncoding=UTF-8 + -Dsonar.php.coverage.reportPaths=tests/coverage.xml + -Dsonar.cpd.php.minimumTokens=25 + -Dsonar.cpd.php.minimumLines=5 diff --git a/.github/workflows/trigger.yml b/.github/workflows/trigger.yml new file mode 100644 index 0000000..559a8c8 --- /dev/null +++ b/.github/workflows/trigger.yml @@ -0,0 +1,15 @@ +name: Trigger + +on: + pull_request: + push: + +jobs: + p80m57both: + name: 'Php-8.0-Mysql-5.7' + uses: ./.github/workflows/development.yml + secrets: inherit + with: + php: '8.0' + mysql: '5.7.37' + report_sonarcloud: true