Skip to content

Restyle Pinakes and complete mobile collections and catalogue fixes #719

Restyle Pinakes and complete mobile collections and catalogue fixes

Restyle Pinakes and complete mobile collections and catalogue fixes #719

name: Deep Regression Gate
on:
pull_request:
branches: [main]
push:
branches: [main]
schedule:
- cron: '17 2 * * *'
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
regression:
name: Browser regression shard ${{ matrix.shard }}/4
runs-on: ubuntu-latest
timeout-minutes: 120
strategy:
fail-fast: false
matrix:
shard: [1, 2, 3, 4]
services:
mysql:
image: mysql:8.0@sha256:7dcddc01f13bab2f15cde676d44d01f61fc9f99fe7785e86196dfc07d358ae2b
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: pinakes_test
ports:
- 3306:3306
options: >-
--health-cmd="mysqladmin ping -h 127.0.0.1"
--health-interval=10s
--health-timeout=5s
--health-retries=10
mailpit:
image: axllent/mailpit:v1.21@sha256:81370195cd4a0eab9604d17c2617a7525b0486f9365555253b6c5376c6350f1a
ports:
- 1025:1025
- 8025:8025
env:
E2E_BASE_URL: http://localhost:8081
APP_URL: http://localhost:8081
E2E_ADMIN_EMAIL: admin@pinakes.test
E2E_ADMIN_PASS: Test1234!
E2E_DB_HOST: 127.0.0.1
E2E_DB_PORT: 3306
E2E_DB_USER: root
E2E_DB_PASS: root
E2E_DB_NAME: pinakes_test
E2E_INSTALL_ROOT: ${{ github.workspace }}
MAILPIT_API: http://127.0.0.1:8025/api/v1
E2E_PHP_UPLOAD_MAX_BYTES: 8388608
E2E_PHP_POST_MAX_BYTES: 10485760
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
with:
persist-credentials: false
- name: Install Apache, PHP module, MySQL client and mail transport
run: |
# This job never installs Google Chrome. Remove its hosted-runner
# apt source before the first refresh so mirror syncs cannot break CI.
sudo rm -f /etc/apt/sources.list.d/google-chrome.list
sudo apt-get update -q
# php-apcu: the app's page cache must run on its production backend
# (APCu shared memory) under Apache/mod_php, not the file fallback.
sudo apt-get install -y apache2 libapache2-mod-php php-apcu default-mysql-client msmtp-mta
sudo a2enmod rewrite headers env
php_module="$(find /etc/apache2/mods-available -maxdepth 1 -name 'php*.load' -printf '%f\n' | sed 's/\.load$//' | sort -V | tail -n1)"
[ -z "${php_module}" ] || sudo a2enmod "${php_module}"
sudo a2dissite 000-default || true
sudo tee /etc/msmtprc >/dev/null <<'EOF'
defaults
account default
host 127.0.0.1
port 1025
tls off
from pinakes-ci@localhost
EOF
sudo chmod 644 /etc/msmtprc
while IFS= read -r conf_dir; do
sudo tee "${conf_dir}/99-pinakes-ci.ini" >/dev/null <<'EOF'
sendmail_path = "/usr/bin/msmtp -t"
upload_max_filesize = 8M
post_max_size = 10M
apc.enable=1
apc.enable_cli=1
EOF
done < <(find /etc/php -type d -path '*/conf.d' | sort -u)
- name: Setup PHP 8.2
uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2
with:
php-version: '8.2'
extensions: mysqli, mbstring, json, curl, openssl, zip, gd, intl, xml, apcu
ini-values: apc.enable=1, apc.enable_cli=1
coverage: none
- name: Setup Node 22
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
with:
node-version: '22'
cache: npm
- name: Install locked dependencies and Chromium
run: |
composer install --no-interaction --prefer-dist --no-dev --optimize-autoloader
npm ci --silent
npx playwright install chromium --with-deps
- name: Route legacy MySQL test clients to the service container
run: echo "${GITHUB_WORKSPACE}/scripts/ci-bin" >> "${GITHUB_PATH}"
- name: Verify test coverage policy
run: npm run test:ci-policy
- name: Configure Apache on port 8081
env:
WORKSPACE: ${{ github.workspace }}
run: |
sudo tee /etc/apache2/sites-available/pinakes.conf >/dev/null <<EOF
Listen 8081
<VirtualHost *:8081>
ServerName localhost
DocumentRoot ${WORKSPACE}/public
SetEnv PINAKES_E2E_BYPASS_RATE_LIMIT 1
SetEnv PINAKES_E2E_SCRAPER_STUB 1
# E2E only — arms GET /_e2e/flush-cache so specs that write to the
# DB directly can invalidate the page cache; 404s when unset.
SetEnv PINAKES_E2E_CACHE_FLUSH 1
<Directory "${WORKSPACE}/public">
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog \${APACHE_LOG_DIR}/pinakes-error.log
CustomLog \${APACHE_LOG_DIR}/pinakes-access.log combined
</VirtualHost>
EOF
sudo a2ensite pinakes
sudo apachectl configtest
- name: Grant runtime permissions and start Apache
env:
WORKSPACE: ${{ github.workspace }}
run: |
path="${WORKSPACE}"
while [ "${path}" != "/" ]; do
sudo chmod o+x "${path}"
path="$(dirname "${path}")"
done
sudo chmod 777 "${WORKSPACE}"
sudo chmod -R 777 "${WORKSPACE}/storage"
sudo mkdir -p "${WORKSPACE}/public/uploads"
sudo chmod -R 777 "${WORKSPACE}/public/uploads"
sudo systemctl start apache2
for _ in $(seq 1 30); do
curl -sf -o /dev/null http://localhost:8081/installer/ && exit 0
sleep 1
done
sudo cat /var/log/apache2/pinakes-error.log || true
exit 1
- name: Bootstrap a complete fresh installation
env:
PLAYWRIGHT_JSON_OUTPUT_FILE: test-results/bootstrap-${{ matrix.shard }}.json
PLAYWRIGHT_HTML_OUTPUT_DIR: playwright-report-bootstrap-${{ matrix.shard }}
run: npx playwright test tests/full-test.spec.js --config=tests/playwright.ci.config.js --workers=1
- name: Audit bootstrap failures, flakes and suspicious skips
if: always()
env:
RESULT_FILE: test-results/bootstrap-${{ matrix.shard }}.json
run: node scripts/ci-audit-playwright-results.js "$RESULT_FILE"
- name: Seed deterministic cross-suite fixtures
env:
E2E_RUN_SEED: '1'
E2E_OFFLINE_SEED: '1'
PLAYWRIGHT_JSON_OUTPUT_FILE: test-results/setup-${{ matrix.shard }}.json
PLAYWRIGHT_HTML_OUTPUT_DIR: playwright-report-setup-${{ matrix.shard }}
run: |
npx playwright test \
tests/interop-00-activate-plugins.spec.js \
tests/archives-seed-50.spec.js \
tests/seed-catalog.spec.js \
tests/persistent-seed-crud.spec.js \
--config=tests/playwright.ci.config.js \
--workers=1
# Apache/PHP may recreate runtime subdirectories with its own umask
# while seeding. The later CLI cron tests need the same shared tree.
sudo chmod -R 777 "${GITHUB_WORKSPACE}/storage"
sudo chmod -R 777 "${GITHUB_WORKSPACE}/public/uploads"
# Installer deliberately protects .env from Apache users. CLI-level
# integration harnesses run as the ephemeral GitHub runner and need
# to read the same throwaway CI credentials.
sudo chmod 640 "${GITHUB_WORKSPACE}/.env"
sudo chgrp "$(id -gn)" "${GITHUB_WORKSPACE}/.env"
- name: Audit setup fixtures
if: always()
env:
RESULT_FILE: test-results/setup-${{ matrix.shard }}.json
run: node scripts/ci-audit-playwright-results.js "$RESULT_FILE"
- name: Run every deep-regression spec in shard ${{ matrix.shard }}
id: deep-regression
env:
SHARD: ${{ matrix.shard }}
PLAYWRIGHT_JSON_OUTPUT_FILE: test-results/shard-${{ matrix.shard }}.json
PLAYWRIGHT_HTML_OUTPUT_DIR: playwright-report-shard-${{ matrix.shard }}
run: |
mapfile -t spec_files < <(node scripts/ci-playwright-policy.js shard "$SHARD" 4)
[ "${#spec_files[@]}" -gt 0 ] || { echo "No specs selected for shard"; exit 1; }
printf 'Running %s deep specs in shard %s/4\n' "${#spec_files[@]}" "$SHARD"
npx playwright test "${spec_files[@]}" \
--config=tests/playwright.ci.config.js \
--workers=1
- name: Audit failures, flakes and suspicious skips
if: always() && steps.deep-regression.outcome != 'skipped'
env:
RESULT_FILE: test-results/shard-${{ matrix.shard }}.json
run: node scripts/ci-audit-playwright-results.js "$RESULT_FILE"
- name: Upload browser evidence
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
if: always()
with:
name: deep-regression-shard-${{ matrix.shard }}-${{ github.run_id }}
path: |
playwright-report-shard-${{ matrix.shard }}/
playwright-report-bootstrap-${{ matrix.shard }}/
playwright-report-setup-${{ matrix.shard }}/
test-results/
storage/logs/app.log
/var/log/apache2/pinakes-error.log
/var/log/apache2/pinakes-access.log
retention-days: 14
if-no-files-found: warn
installer-locales:
name: Fresh installer (${{ matrix.locale }})
runs-on: ubuntu-latest
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
locale: [it_IT, en_US, de_DE, fr_FR, da_DK]
services:
mysql:
image: mysql:8.0@sha256:7dcddc01f13bab2f15cde676d44d01f61fc9f99fe7785e86196dfc07d358ae2b
env:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: pinakes_locale_test
ports:
- 3306:3306
options: >-
--health-cmd="mysqladmin ping -h 127.0.0.1"
--health-interval=10s
--health-timeout=5s
--health-retries=10
env:
E2E_BASE_URL: http://localhost:8081
E2E_ADMIN_EMAIL: locale-admin@pinakes.test
E2E_ADMIN_PASS: Test1234!
E2E_DB_HOST: 127.0.0.1
E2E_DB_PORT: 3306
E2E_DB_USER: root
E2E_DB_PASS: root
E2E_DB_NAME: pinakes_locale_test
E2E_INSTALL_ROOT: ${{ github.workspace }}
E2E_RUN_INSTALLER_SPECS: '1'
E2E_LOCALE: ${{ matrix.locale }}
steps:
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
with:
persist-credentials: false
- name: Install Apache and PHP module
run: |
# This job never installs Google Chrome. Remove its hosted-runner
# apt source before the first refresh so mirror syncs cannot break CI.
sudo rm -f /etc/apt/sources.list.d/google-chrome.list
sudo apt-get update -q
sudo apt-get install -y apache2 libapache2-mod-php default-mysql-client
sudo a2enmod rewrite headers env
php_module="$(find /etc/apache2/mods-available -maxdepth 1 -name 'php*.load' -printf '%f\n' | sed 's/\.load$//' | sort -V | tail -n1)"
[ -z "${php_module}" ] || sudo a2enmod "${php_module}"
sudo a2dissite 000-default || true
- name: Setup PHP and Node
uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2
with:
php-version: '8.2'
extensions: mysqli, mbstring, curl, zip, gd, intl, xml
coverage: none
- uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5
with:
node-version: '22'
cache: npm
- name: Install locked dependencies and Chromium
run: |
composer install --no-interaction --prefer-dist --no-dev --optimize-autoloader
npm ci --silent
npx playwright install chromium --with-deps
- name: Configure and start isolated application
env:
WORKSPACE: ${{ github.workspace }}
run: |
sudo tee /etc/apache2/sites-available/pinakes.conf >/dev/null <<EOF
Listen 8081
<VirtualHost *:8081>
ServerName localhost
DocumentRoot ${WORKSPACE}/public
SetEnv PINAKES_E2E_BYPASS_RATE_LIMIT 1
<Directory "${WORKSPACE}/public">
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog \${APACHE_LOG_DIR}/pinakes-error.log
</VirtualHost>
EOF
sudo a2ensite pinakes
path="${WORKSPACE}"
while [ "${path}" != "/" ]; do sudo chmod o+x "${path}"; path="$(dirname "${path}")"; done
sudo chmod 777 "${WORKSPACE}"
sudo chmod -R 777 "${WORKSPACE}/storage"
sudo mkdir -p "${WORKSPACE}/public/uploads"
sudo chmod -R 777 "${WORKSPACE}/public/uploads"
sudo apachectl configtest
sudo systemctl start apache2
for _ in $(seq 1 30); do
curl -sf -o /dev/null http://localhost:8081/installer/ && exit 0
sleep 1
done
exit 1
- name: Install and verify locale ${{ matrix.locale }}
env:
PLAYWRIGHT_JSON_OUTPUT_FILE: test-results/installer-${{ matrix.locale }}.json
PLAYWRIGHT_HTML_OUTPUT_DIR: playwright-report-installer-${{ matrix.locale }}
run: |
npx playwright test tests/multilang-install-i18n.spec.js \
--config=tests/playwright.ci.config.js \
--workers=1
- name: Audit installer result
if: always()
env:
RESULT_FILE: test-results/installer-${{ matrix.locale }}.json
run: node scripts/ci-audit-playwright-results.js "$RESULT_FILE"
- name: Upload installer evidence
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
if: always()
with:
name: installer-${{ matrix.locale }}-${{ github.run_id }}
path: |
playwright-report-installer-${{ matrix.locale }}/
test-results/
/var/log/apache2/pinakes-error.log
retention-days: 14
if-no-files-found: warn