Mautic tests and validations #301
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Mautic tests and validations | |
on: | |
push: | |
branches: | |
- '[0-9].*' | |
pull_request: | |
merge_group: | |
schedule: | |
# Run every day at 10:45 AM UTC to discover potential issues with dependencies like PHP updates etc. | |
- cron: '45 10 * * *' | |
permissions: | |
contents: read # to fetch code (actions/checkout) | |
jobs: | |
phpunit: | |
# We don't want the scheduled jobs to run on forks of Mautic | |
if: (github.event_name == 'schedule' && (github.repository == 'mautic/mautic' || github.repository == 'mautic/api-library') ) || (github.event_name != 'schedule') | |
runs-on: ubuntu-latest | |
strategy: | |
matrix: | |
php-versions: ['8.1', '8.2', '8.3'] | |
db-types: ['mysql', 'mariadb'] | |
name: PHPUnit ${{ matrix.php-versions }} ${{ matrix.db-types }} | |
services: | |
database: | |
image: ${{ matrix.db-types == 'mysql' && 'mysql:5.7' || 'mariadb:10.3' }} | |
env: | |
MYSQL_ALLOW_EMPTY_PASSWORD: yes | |
MYSQL_DATABASE: mautictest | |
ports: | |
- 3306 | |
options: >- | |
--shm-size=2gb | |
--name=${{ matrix.db-types }} | |
--tmpfs=/var/lib/mysql | |
--health-cmd="mysqladmin ping" | |
--health-interval=10s | |
--health-timeout=5s | |
--health-retries=3 | |
steps: | |
- uses: actions/checkout@v4 | |
# Codecov needs access to previous commits, so we add fetch-depth: 0 | |
with: | |
fetch-depth: 0 | |
- name: PHPUnit cache | |
if: ${{matrix.php-versions == '8.1' && matrix.db-types == 'mariadb'}} | |
uses: actions/cache@v4 | |
with: | |
path: ./var/cache/phpunit | |
key: ${{ runner.os }}-phpunit-${{ hashFiles('**/composer.lock') }}-${{ github.run_id }} | |
restore-keys: | | |
${{ runner.os }}-phpunit-${{ hashFiles('**/composer.lock') }} | |
${{ runner.os }}-phpunit- | |
- name: Setup PHP, with composer and extensions | |
uses: shivammathur/setup-php@v2 | |
with: | |
php-version: ${{ matrix.php-versions }} | |
extensions: mbstring, xml, ctype, iconv, intl, pdo_sqlite, mysql, pdo_mysql | |
coverage: pcov | |
ini-values: pcov.enabled=0, pcov.directory=., pcov.exclude="~tests|themes|vendor~" | |
- name: add MySQL config file | |
run: | | |
mysqldump --version | |
mysqldump --print-defaults | |
cp .github/ci-files/.my.cnf ~/.my.cnf | |
mysqldump --print-defaults | |
- name: Set SYMFONY_ENV to test | |
run: | | |
echo "SYMFONY_ENV=test" >> $GITHUB_ENV | |
echo "MAUTIC_ENV=test" >> $GITHUB_ENV | |
- name: Install dependencies | |
# composer install cache - https://github.com/ramsey/composer-install | |
uses: "ramsey/composer-install@v3" | |
- name: Run tests - database = ${{ matrix.db-types }} | |
run: | | |
rm -rf var/cache | |
export DB_PORT="${{ job.services.database.ports[3306] }}" | |
if [[ "${{ matrix.php-versions }}" == "8.1" ]] && [[ "${{ matrix.db-types }}" == "mariadb" ]]; then | |
php -d zend.assertions=1 -d pcov.enabled=1 bin/phpunit -d memory_limit=2G --bootstrap vendor/autoload.php --configuration app/phpunit.xml.dist --coverage-clover=coverage.xml --log-junit=junit.xml | |
else | |
php -d zend.assertions=1 bin/phpunit -d memory_limit=1G --bootstrap vendor/autoload.php --configuration app/phpunit.xml.dist | |
fi | |
- name: Upload coverage report | |
if: ${{ matrix.php-versions == '8.1' && matrix.db-types == 'mariadb' && github.repository == 'mautic/mautic' }} | |
uses: codecov/codecov-action@v4 | |
with: | |
files: ./coverage.xml | |
fail_ci_if_error: true | |
env: | |
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | |
- name: Save test results for future steps | |
if: ${{ matrix.php-versions == '8.1' && matrix.db-types == 'mariadb' && github.repository == 'mautic/mautic' }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: test-results | |
path: | | |
./junit.xml | |
./coverage.xml | |
- name: Slack Notification if tests fail | |
uses: rtCamp/action-slack-notify@v2 | |
if: ${{ failure() && github.event_name == 'schedule' }} | |
env: | |
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} | |
SLACK_MESSAGE: 'The daily GitHub Actions tests in mautic/mautic have failed. Most likely something external has changed, like a PHP version update.' | |
- name: Store log artifacts | |
if: ${{ always() }} | |
uses: actions/upload-artifact@v4 | |
with: | |
name: logs-${{ matrix.php-versions }}-${{ matrix.db-types }} | |
path: ./var/logs/* | |
e2e-tests: | |
runs-on: ubuntu-latest | |
steps: | |
- name: Checkout | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Setup DDEV | |
uses: ddev/github-action-setup-ddev@v1 | |
- name: Set up environment variables for test mode | |
run: echo -e "APP_ENV=test\nAPP_DEBUG=1" > .env.local | |
- name: Run E2E tests | |
run: ddev exec bin/codecept run acceptance | |
- name: Upload test artifacts | |
if: failure() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: e2e-test-screenshots | |
path: tests/_output | |
if-no-files-found: ignore | |
misc: | |
# We don't want the scheduled jobs to run on forks of Mautic | |
if: (github.event_name == 'schedule' && (github.repository == 'mautic/mautic' || github.repository == 'mautic/api-library') ) || (github.event_name != 'schedule') | |
runs-on: ubuntu-latest | |
strategy: | |
fail-fast: false | |
matrix: | |
commands: ['PHPSTAN', 'CS Fixer', 'Rector', 'Twig Lint', 'scaffolded files mismatch', 'PHPStan baseline changes', 'composer install', 'composer lock check'] | |
php-versions: ['8.1'] | |
name: ${{ matrix.commands }} - ${{ matrix.php-versions }} | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 0 | |
- name: Rector Cache | |
if: ${{matrix.commands == 'Rector'}} | |
uses: actions/cache@v4 | |
with: | |
path: ./var/cache/rector | |
key: ${{ runner.os }}-rector-${{ hashFiles('**/composer.lock') }}-${{ github.run_id }} | |
restore-keys: | | |
${{ runner.os }}-rector-${{ hashFiles('**/composer.lock') }} | |
${{ runner.os }}-rector- | |
- name: PHPStan Cache | |
if: ${{matrix.commands == 'PHPSTAN'}} | |
uses: actions/cache@v4 | |
with: | |
path: ./var/phpstan-cache | |
key: ${{ runner.os }}-phpstan-${{ hashFiles('**/composer.lock') }}-${{ github.run_id }} | |
restore-keys: | | |
${{ runner.os }}-phpstan-${{ hashFiles('**/composer.lock') }} | |
${{ runner.os }}-phpstan- | |
- name: NPM Cache | |
uses: actions/cache@v4 | |
with: | |
path: ./var/cache/js | |
key: ${{ runner.os }}-js-${{ hashFiles('**/package-lock.json', 'webpack.config.js') }}-${{ github.run_id }} | |
restore-keys: | | |
${{ runner.os }}-js-${{ hashFiles('**/package-lock.json', 'webpack.config.js') }} | |
${{ runner.os }}-js- | |
- name: Get changed files | |
id: changed-files | |
uses: tj-actions/changed-files@v42 | |
- name: Setup PHP, with composer and extensions | |
uses: shivammathur/setup-php@v2 | |
with: | |
php-version: ${{ matrix.php-versions }} | |
extensions: mbstring, xml, ctype, iconv, intl, pdo_sqlite, mysql, pdo_mysql | |
- name: Install dependencies | |
# composer install cache - https://github.com/ramsey/composer-install | |
uses: "ramsey/composer-install@v3" | |
env: | |
NPM_CONFIG_CACHE: ./var/cache/js/npm | |
- name: Run ${{ matrix.commands }} | |
run: | | |
if [[ "${{ matrix.commands }}" == "PHPSTAN" ]]; then | |
export SYMFONY_ENV=dev | |
export APP_ENV=dev | |
export APP_DEBUG=1 | |
composer phpstan -- --no-progress | |
elif [[ "${{ matrix.commands }}" == "Rector" ]]; then | |
export SYMFONY_ENV=test | |
bin/console cache:warmup | |
bin/rector --dry-run --ansi | |
elif [[ "${{ matrix.commands }}" == "Twig Lint" ]]; then | |
bin/console lint:twig app plugins | |
elif [[ "${{ matrix.commands }}" == "CS Fixer" ]]; then | |
for file in ${{ steps.changed-files.outputs.all_changed_files }}; do | |
if [[ $file == *.php ]]; then | |
cs_fix_files="${cs_fix_files} $file" | |
fi | |
done | |
if [[ $cs_fix_files ]]; then | |
bin/php-cs-fixer fix --config=.php-cs-fixer.php --dry-run --using-cache=no --show-progress=dots --diff $cs_fix_files | |
fi | |
elif [[ "${{ matrix.commands }}" == "scaffolded files mismatch" ]]; then | |
wget -q -O /tmp/jq https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 && chmod 755 /tmp/jq | |
/tmp/jq -r '.extra["mautic-scaffold"]["file-mapping"] | to_entries[] | "diff -q \(.key | sub("\\[(project|web)-root\\]";".")) app/\(.value)"' app/composer.json > diff_commands.sh | |
/tmp/jq -r '.extra["mautic-scaffold"]["file-mapping"] | to_entries[] | "diff -rui \(.key | sub("\\[(project|web)-root\\]";".")) app/\(.value)"' app/composer.json > diff_commands_verbose.sh | |
bash diff_commands.sh 2>&1 | tee /tmp/diff_command_output.txt | |
rm diff_commands.sh | |
if [[ $(wc -l </tmp/diff_command_output.txt) -ge 1 ]]; then | |
echo "some scaffolded files were not updated or deleted" | |
echo "Please apply the same changes in the files mentioned above" | |
echo "verbose diff:" | |
bash diff_commands_verbose.sh | |
exit 1 | |
fi | |
elif [[ "${{ matrix.commands }}" == "PHPStan baseline changes" ]]; then | |
if [[ "${{ steps.changed-files.outputs.modified_files }}" == *"phpstan-baseline.neon"* ]]; then | |
stat=$(git diff --shortstat "origin/${{ github.base_ref }}" ${{ github.sha }} -- phpstan-baseline.neon) | |
echo $stat | |
regex="[0-9]+[[:space:]]insertion" | |
if [[ $stat =~ $regex ]]; then | |
echo "There are modifications (added or changed lines) to the phpstan-baseline.neon" | |
echo "Please fix the PHPStan errors instead of altering the baseline file" | |
exit 1 | |
fi | |
fi | |
elif [[ "${{ matrix.commands }}" == "composer install" ]]; then | |
# create a temp dir and mimic a composer install via mautic/recommended-project | |
mkdir test_composer | |
cd test_composer | |
cp ../.github/ci-files/composer.json ./ | |
composer install | |
# test if media/css and media/js folder contain the same files as the tarball releases | |
test -z "$(comm -23 <(ls ../media/js | sort) <(ls docroot/media/js | sort))" | |
test -z "$(comm -23 <(ls ../media/css | sort) <(ls docroot/media/css | sort))" | |
# test if console is executable | |
./bin/console cache:clear | |
elif [[ "${{ matrix.commands }}" == "composer lock check" ]]; then | |
composer validate --ansi | |
else | |
echo "Invalid command" | |
exit 1 | |
fi | |
- name: Slack Notification if tests fail | |
uses: rtCamp/action-slack-notify@v2 | |
if: ${{ failure() && github.event_name == 'schedule' }} | |
env: | |
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} | |
SLACK_MESSAGE: 'The daily GitHub Actions tests in mautic/mautic have failed. Most likely something external has changed, like a PHP version update.' |