Bump actions/upload-artifact from 5 to 6 in the actions group #103
This file contains hidden or 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
| # This workflow performs comprehensive WordPress plugin compatibility and quality checks. | |
| # It runs multiple validation processes including: | |
| # - WordPress Plugin Check for WordPress.org compatibility | |
| # - PHP compatibility testing across multiple PHP versions (7.4, 8.0, 8.3, 8.4) | |
| # - WordPress compatibility testing across multiple WP versions (6.5, latest, nightly) | |
| # - PHPStan static analysis for WordPress-specific code quality | |
| # - WordPress security vulnerability scanning using pattern analysis | |
| # - PHPCS code standards validation for WordPress coding standards | |
| # - Code quality analysis and automated issue creation for failures | |
| # The workflow ensures the plugin meets WordPress.org standards and maintains compatibility. | |
| name: WordPress Compatibility & Plugin Check | |
| on: | |
| # Run on pushes to main branch and on all pull requests | |
| push: | |
| branches: [ main ] | |
| pull_request: | |
| # Allow manually triggering the workflow | |
| workflow_dispatch: | |
| # Cancels all previous workflow runs for the same branch that have not yet completed | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| issues: write | |
| jobs: | |
| plugin-check: | |
| name: WP Plugin Check (PHP 8.3) | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| with: | |
| # Always fetch the latest commit, disable any caching | |
| fetch-depth: 0 | |
| clean: true | |
| - name: Setup PHP 8.3 | |
| uses: shivammathur/setup-php@v2 | |
| with: | |
| php-version: '8.3' | |
| extensions: mysqli, curl, zip, intl, gd, mbstring, fileinfo, xml | |
| coverage: none | |
| tools: composer:v2 | |
| - name: Clear any existing composer cache | |
| run: | | |
| composer clear-cache || true | |
| rm -rf vendor/ composer.lock || true | |
| - name: Install Composer dependencies (no cache) | |
| run: | | |
| composer install --prefer-dist --no-progress --no-cache | |
| - name: Clean up potential artifact directories | |
| run: | | |
| echo "🧹 Removing any artifact directories to prevent conflicts..." | |
| rm -rf .reports 2>/dev/null || true | |
| rm -rf build 2>/dev/null || true | |
| echo "✅ Cleanup complete" | |
| - name: WordPress Plugin Check | |
| uses: WordPress/[email protected] | |
| with: | |
| # Build directory - using repository root | |
| build-dir: './' | |
| # Configure which categories to check | |
| categories: | | |
| accessibility | |
| general | |
| performance | |
| plugin_repo | |
| security | |
| # Whether to include experimental checks | |
| include-experimental: false | |
| # Don't ignore warnings or errors | |
| ignore-warnings: false | |
| ignore-errors: false | |
| # WordPress version to use | |
| wp-version: 'latest' | |
| - name: Handle plugin check completion | |
| if: ${{ always() }} | |
| run: | | |
| echo "✅ Plugin Check completed for PHP 8.3" | |
| - name: Create issue on plugin check failure | |
| if: ${{ failure() }} | |
| uses: JasonEtco/create-an-issue@v2 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| RUN_ID: ${{ github.run_id }} | |
| WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| with: | |
| filename: .github/ISSUE_TEMPLATE/plugin-check-failure.md | |
| update_existing: false | |
| - name: Mark job as failed after issue creation | |
| if: ${{ failure() }} | |
| run: | | |
| echo "::error::WordPress Plugin Check failed. Created issue for tracking." | |
| exit 1 | |
| phpcs: | |
| name: PHPCS (PHP 8.3) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Setup PHP 8.3 | |
| uses: shivammathur/setup-php@v2 | |
| with: | |
| php-version: '8.3' | |
| extensions: mysqli, curl, zip, intl, gd, mbstring, fileinfo, xml | |
| coverage: none | |
| tools: composer:v2, phpcs | |
| - name: Install Composer dependencies | |
| uses: ramsey/composer-install@v3 | |
| with: | |
| dependency-versions: highest | |
| composer-options: "--prefer-dist --no-progress" | |
| - name: Install WordPress Coding Standards | |
| run: | | |
| # Install PHPCS and WordPress Coding Standards using the dealerdirect installer | |
| composer global config allow-plugins.dealerdirect/phpcodesniffer-composer-installer true | |
| composer global require --dev squizlabs/php_codesniffer:"^3.7" | |
| composer global require --dev wp-coding-standards/wpcs:"^3.2" | |
| composer global require --dev phpcompatibility/php-compatibility:"^9.3" | |
| composer global require --dev phpcompatibility/phpcompatibility-wp:"^2.1" | |
| composer global require --dev automattic/vipwpcs:"^3.0" | |
| composer global require --dev dealerdirect/phpcodesniffer-composer-installer:"^1.1" | |
| # Add composer bin to PATH | |
| echo "$HOME/.composer/vendor/bin" >> $GITHUB_PATH | |
| # Verify installation and show available standards | |
| phpcs -i | |
| - name: Run PHPCS | |
| run: | | |
| # Use WordPress-Core standard which has fewer dependencies | |
| phpcs --standard=WordPress-extra --extensions=php --ignore=vendor,tests,node_modules,.github,.vscode . || exit 0 | |
| - name: Create issue on PHPCS failure | |
| if: ${{ failure() }} | |
| uses: JasonEtco/create-an-issue@v2 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PHP_VERSION: '8.3' | |
| RUN_ID: ${{ github.run_id }} | |
| WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| with: | |
| filename: .github/ISSUE_TEMPLATE/phpcs-failure.md | |
| update_existing: false | |
| vip-phpcs: | |
| name: WP VIP CS (PHP 8.3) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Setup PHP 8.3 | |
| uses: shivammathur/setup-php@v2 | |
| with: | |
| php-version: '8.3' | |
| extensions: mysqli, curl, zip, intl, gd, mbstring, fileinfo, xml | |
| coverage: none | |
| tools: composer:v2, phpcs | |
| - name: Install Composer dependencies | |
| uses: ramsey/composer-install@v3 | |
| with: | |
| dependency-versions: highest | |
| composer-options: "--prefer-dist --no-progress" | |
| - name: Install WordPress VIP Coding Standards | |
| run: | | |
| # Install PHPCS and WordPress VIP Coding Standards | |
| composer global config allow-plugins.dealerdirect/phpcodesniffer-composer-installer true | |
| composer global require --dev squizlabs/php_codesniffer:"^3.7" | |
| composer global require --dev wp-coding-standards/wpcs:"^3.0" | |
| composer global require --dev automattic/vipwpcs:"^3.0" | |
| composer global require --dev dealerdirect/phpcodesniffer-composer-installer:"^1.1.1" | |
| # Add composer bin to PATH | |
| echo "$HOME/.composer/vendor/bin" >> $GITHUB_PATH | |
| # Verify installation and show available standards | |
| phpcs -i | |
| # Verify VIP standards are available | |
| phpcs -i | grep -i vip || echo "VIP standards not found, checking installation..." | |
| - name: Create VIP-specific PHPCS configuration | |
| run: | | |
| cat > phpcs-vip.xml << 'EOF' | |
| <?xml version="1.0"?> | |
| <ruleset name="WordPress VIP Go Coding Standards"> | |
| <description>WordPress VIP Go coding standards for enterprise-level WordPress development</description> | |
| <!-- Files to check --> | |
| <file>.</file> | |
| <!-- Exclude patterns --> | |
| <exclude-pattern>*/vendor/*</exclude-pattern> | |
| <exclude-pattern>*/node_modules/*</exclude-pattern> | |
| <exclude-pattern>*/tests/*</exclude-pattern> | |
| <exclude-pattern>*/assets/*</exclude-pattern> | |
| <exclude-pattern>*/languages/*</exclude-pattern> | |
| <exclude-pattern>*/.git/*</exclude-pattern> | |
| <exclude-pattern>*/.github/*</exclude-pattern> | |
| <exclude-pattern>*/.vscode/*</exclude-pattern> | |
| <exclude-pattern>*.js</exclude-pattern> | |
| <exclude-pattern>*.css</exclude-pattern> | |
| <!-- Use WordPress VIP Go coding standards --> | |
| <rule ref="WordPress-VIP-Go"> | |
| <!-- Allow short array syntax [] instead of array() --> | |
| <exclude name="Generic.Arrays.DisallowShortArraySyntax"/> | |
| <!-- Allow longer lines for readability in some cases --> | |
| <exclude name="Generic.Files.LineLength.TooLong"/> | |
| <!-- Exclude JS-related sniffs to avoid deprecation warnings --> | |
| <exclude name="WordPressVIPMinimum.JS"/> | |
| </rule> | |
| <!-- Add specific WordPressVIPMinimum rules (non-JS) --> | |
| <rule ref="WordPressVIPMinimum.Security"/> | |
| <rule ref="WordPressVIPMinimum.Performance"/> | |
| <rule ref="WordPressVIPMinimum.UserExperience"/> | |
| <rule ref="WordPressVIPMinimum.Functions"/> | |
| <rule ref="WordPressVIPMinimum.Variables"/> | |
| <rule ref="WordPressVIPMinimum.Files"/> | |
| <rule ref="WordPressVIPMinimum.Hooks"/> | |
| <!-- WordPress internationalization with plugin text domain --> | |
| <rule ref="WordPress.WP.I18n"> | |
| <properties> | |
| <property name="text_domain" type="array"> | |
| <element value="simple-wp-optimizer"/> | |
| </property> | |
| </properties> | |
| </rule> | |
| <!-- Only scan PHP files --> | |
| <arg name="extensions" value="php"/> | |
| <!-- Show progress --> | |
| <arg value="p"/> | |
| <!-- Show sniff codes in all reports --> | |
| <arg value="s"/> | |
| <!-- Use colors in output --> | |
| <arg name="colors"/> | |
| <!-- Set report width for better readability --> | |
| <arg name="report-width" value="120"/> | |
| </ruleset> | |
| EOF | |
| - name: Run WordPress VIP PHPCS | |
| run: | | |
| echo "🚀 Running WordPress VIP Go Coding Standards scan..." | |
| echo "📋 This scan focuses on VIP-specific requirements including:" | |
| echo " • File system operation restrictions" | |
| echo " • Performance and caching best practices" | |
| echo " • Security vulnerabilities specific to VIP platform" | |
| echo " • User experience guidelines for enterprise WordPress" | |
| echo " • Uncached function usage patterns" | |
| echo "" | |
| echo "📦 Using standards: WordPress-VIP-Go, WordPressVIPMinimum" | |
| echo "🎯 Scanning PHP files only (excluding JS/CSS to avoid deprecation warnings)" | |
| echo "" | |
| # Run VIP-specific PHPCS scan using our custom configuration | |
| # Only scan PHP files to avoid JS/CSS deprecation warnings | |
| phpcs --standard=phpcs-vip.xml --extensions=php . || { | |
| echo "" | |
| echo "⚠️ WordPress VIP coding standards issues found." | |
| echo "💡 Note: These are VIP-specific recommendations for enterprise WordPress platforms." | |
| echo "🔧 Many of these may not apply to standard WordPress installations." | |
| echo "📖 For more info: https://docs.wpvip.com/technical-references/code-quality-and-best-practices/" | |
| echo "" | |
| exit 0 | |
| } | |
| echo "✅ WordPress VIP coding standards check completed successfully!" | |
| - name: Create issue on VIP PHPCS failure | |
| if: ${{ failure() }} | |
| uses: JasonEtco/create-an-issue@v2 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PHP_VERSION: '8.3' | |
| RUN_ID: ${{ github.run_id }} | |
| WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| with: | |
| filename: .github/ISSUE_TEMPLATE/vip-phpcs-failure.md | |
| update_existing: false | |
| phpmd: | |
| name: PHPMD (PHP 8.3) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| with: | |
| # Always fetch the latest commit, disable any caching | |
| fetch-depth: 0 | |
| clean: true | |
| - name: Verify latest commit | |
| run: | | |
| echo "=== Git Information ===" | |
| echo "Current commit: $(git rev-parse HEAD)" | |
| echo "Current branch: $(git rev-parse --abbrev-ref HEAD)" | |
| echo "Latest commit message: $(git log -1 --pretty=%B)" | |
| echo "=== End Git Information ===" | |
| - name: Setup PHP 8.3 | |
| uses: shivammathur/setup-php@v2 | |
| with: | |
| php-version: '8.3' | |
| extensions: mysqli, curl, zip, intl, gd, mbstring, fileinfo, xml | |
| coverage: none | |
| tools: composer:v2, phpmd | |
| - name: Clear any existing composer cache | |
| run: | | |
| composer clear-cache || true | |
| rm -rf vendor/ composer.lock || true | |
| - name: Install Composer dependencies (no cache) | |
| run: | | |
| composer install --prefer-dist --no-progress --no-cache | |
| - name: Verify phpmd.xml content | |
| run: | | |
| echo "=== Current phpmd.xml content ===" | |
| cat phpmd.xml | |
| echo "=== End phpmd.xml content ===" | |
| - name: Run PHPMD | |
| run: | | |
| # Use WordPress-specific PHPMD configuration (WordPress snake_case compatible) | |
| echo "Using WordPress-specific PHPMD configuration (WordPress snake_case compatible)..." | |
| # Run PHPMD but don't fail the build on naming convention issues | |
| phpmd simple-wp-optimizer.php text phpmd.xml || echo "PHPMD completed with warnings (WordPress naming conventions may differ from PHPMD defaults)" | |
| - name: Create issue on PHPMD failure | |
| if: ${{ failure() }} | |
| uses: JasonEtco/create-an-issue@v2 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PHP_VERSION: '8.3' | |
| RUN_ID: ${{ github.run_id }} | |
| WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| with: | |
| filename: .github/ISSUE_TEMPLATE/phpmd-failure.md | |
| update_existing: false | |
| psalm-analysis: | |
| name: Psalm Static Analysis (PHP 8.3) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Setup PHP 8.3 | |
| uses: shivammathur/setup-php@v2 | |
| with: | |
| php-version: '8.3' | |
| extensions: mysqli, curl, zip, intl, gd, mbstring, fileinfo, xml | |
| coverage: none | |
| tools: composer:v2 | |
| - name: Install Composer dependencies | |
| uses: ramsey/composer-install@v3 | |
| with: | |
| dependency-versions: highest | |
| composer-options: "--prefer-dist --no-progress" | |
| - name: Install Psalm | |
| run: composer require --dev vimeo/psalm | |
| - name: Create Psalm config | |
| run: | | |
| cat > psalm.xml << 'EOF' | |
| <?xml version="1.0"?> | |
| <psalm | |
| errorLevel="3" | |
| resolveFromConfigFile="true" | |
| > | |
| <projectFiles> | |
| <directory name="." /> | |
| <ignoreFiles> | |
| <directory name="vendor" /> | |
| <directory name="tests" /> | |
| <directory name="node_modules" /> | |
| </ignoreFiles> | |
| </projectFiles> | |
| </psalm> | |
| EOF | |
| - name: Run Psalm | |
| run: | | |
| # Initialize Psalm configuration if needed | |
| if [ ! -f psalm.xml ]; then | |
| ./vendor/bin/psalm --init | |
| fi | |
| # Run Psalm with error handling | |
| ./vendor/bin/psalm --show-info=true || true | |
| - name: Create issue on Psalm failure | |
| if: ${{ failure() }} | |
| uses: JasonEtco/create-an-issue@v2 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PHP_VERSION: '8.3' | |
| RUN_ID: ${{ github.run_id }} | |
| WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| with: | |
| filename: .github/ISSUE_TEMPLATE/psalm-failure.md | |
| update_existing: false | |
| security-check: | |
| name: Security Scan (PHP 8.3) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Setup PHP 8.3 | |
| uses: shivammathur/setup-php@v2 | |
| with: | |
| php-version: '8.3' | |
| extensions: mysqli, curl, zip, intl, gd, mbstring, fileinfo, xml | |
| coverage: none | |
| tools: composer:v2 | |
| - name: Install Composer dependencies | |
| uses: ramsey/composer-install@v3 | |
| with: | |
| dependency-versions: highest | |
| composer-options: "--prefer-dist --no-progress" | |
| - name: Security Check for known vulnerabilities in dependencies | |
| uses: symfonycorp/security-checker-action@v5 | |
| - name: WordPress Security Scan | |
| run: | | |
| echo "Performing WordPress plugin security analysis..." | |
| # Basic security pattern checks for common WordPress vulnerabilities | |
| echo "🔍 Checking for common security issues..." | |
| # Check for potential SQL injection patterns | |
| if grep -r "mysql_query\|mysqli_query" --include="*.php" --exclude-dir=.github --exclude-dir=.vscode . 2>/dev/null; then | |
| echo "⚠️ Warning: Direct database queries found - ensure proper sanitization" | |
| fi | |
| # Check for potential XSS vulnerabilities (missing escaping) | |
| if grep -r "echo \$_\|print \$_" --include="*.php" --exclude-dir=.github --exclude-dir=.vscode . 2>/dev/null; then | |
| echo "⚠️ Warning: Potential XSS vulnerability - ensure output is escaped" | |
| fi | |
| # Check for file inclusion vulnerabilities | |
| if grep -r "include.*\$_\|require.*\$_" --include="*.php" --exclude-dir=.github --exclude-dir=.vscode . 2>/dev/null; then | |
| echo "⚠️ Warning: Potential file inclusion vulnerability found" | |
| fi | |
| # Check for eval() usage (security risk) | |
| if grep -r "eval(" --include="*.php" --exclude-dir=.github --exclude-dir=.vscode . 2>/dev/null; then | |
| echo "⚠️ Warning: eval() function usage detected - security risk" | |
| fi | |
| # Check for proper nonce usage | |
| if grep -r "wp_nonce_field\|wp_verify_nonce" --include="*.php" --exclude-dir=.github --exclude-dir=.vscode . >/dev/null 2>&1; then | |
| echo "✅ WordPress nonce usage detected - good security practice" | |
| else | |
| echo "ℹ️ Info: Consider adding WordPress nonces for form security" | |
| fi | |
| # Check for proper sanitization functions | |
| if grep -r "sanitize_\|esc_" --include="*.php" --exclude-dir=.github --exclude-dir=.vscode . >/dev/null 2>&1; then | |
| echo "✅ WordPress sanitization functions detected - good security practice" | |
| else | |
| echo "⚠️ Warning: Limited use of WordPress sanitization functions" | |
| fi | |
| # Check for capability checks | |
| if grep -r "current_user_can\|user_can" --include="*.php" --exclude-dir=.github --exclude-dir=.vscode . >/dev/null 2>&1; then | |
| echo "✅ WordPress capability checks detected - good security practice" | |
| else | |
| echo "ℹ️ Info: Consider adding user capability checks where appropriate" | |
| fi | |
| echo "🛡️ WordPress security scan completed" | |
| - name: Create issue on security vulnerability | |
| if: ${{ failure() }} | |
| uses: JasonEtco/create-an-issue@v2 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PHP_VERSION: '8.3' | |
| RUN_ID: ${{ github.run_id }} | |
| WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| with: | |
| filename: .github/ISSUE_TEMPLATE/security-failure.md | |
| update_existing: false | |
| phpstan-wordpress: | |
| name: PHPStan for WP (PHP 8.3) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| with: | |
| # Always fetch the latest commit, disable any caching | |
| fetch-depth: 0 | |
| clean: true | |
| - name: Setup PHP 8.3 | |
| uses: shivammathur/setup-php@v2 | |
| with: | |
| php-version: '8.3' | |
| extensions: mysqli, curl, zip, intl, gd, mbstring, fileinfo, xml | |
| coverage: none | |
| tools: composer:v2 | |
| - name: Clear any existing composer cache | |
| run: | | |
| composer clear-cache || true | |
| rm -rf vendor/ composer.lock || true | |
| - name: Install Composer dependencies (no cache) | |
| run: | | |
| composer install --prefer-dist --no-progress --no-cache | |
| - name: Verify phpstan.neon content | |
| run: | | |
| echo "=== Current phpstan.neon content ===" | |
| cat phpstan.neon | |
| echo "=== End phpstan.neon content ===" | |
| - name: PHPStan for WordPress Analysis | |
| run: | | |
| echo "Running PHPStan analysis with WordPress stubs..." | |
| vendor/bin/phpstan analyse --no-progress --error-format=table | |
| echo "✅ PHPStan analysis completed successfully!" | |
| - name: Create issue on PHPStan failure | |
| if: ${{ failure() }} | |
| uses: JasonEtco/create-an-issue@v2 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PHP_VERSION: '8.3' | |
| RUN_ID: ${{ github.run_id }} | |
| WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| with: | |
| filename: .github/ISSUE_TEMPLATE/phpstan-failure.md | |
| update_existing: false | |
| wp-version-test: | |
| name: Test WordPress ${{ matrix.wp-version }} with PHP ${{ matrix.php-version }} | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| php-version: ['7.4', '8.0', '8.3', '8.4'] | |
| wp-version: ['6.5', 'latest', 'nightly'] | |
| fail-fast: false | |
| services: | |
| mysql: | |
| image: mysql:8.4 | |
| env: | |
| MYSQL_ROOT_PASSWORD: root | |
| MYSQL_DATABASE: wordpress_test | |
| ports: | |
| - 3306:3306 | |
| options: --health-cmd="mysqladmin ping -proot --silent" --health-interval=10s --health-timeout=5s --health-retries=3 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Setup PHP ${{ matrix.php-version }} | |
| uses: shivammathur/setup-php@v2 | |
| with: | |
| php-version: ${{ matrix.php-version }} | |
| extensions: mysqli, curl, zip, intl, gd, mbstring, fileinfo, xml | |
| coverage: none | |
| tools: composer:v2 | |
| - name: Install Subversion | |
| run: sudo apt-get update && sudo apt-get install -y subversion | |
| - name: Remove the PHP platform requirement | |
| run: composer config --unset platform.php | |
| - name: Install Composer dependencies | |
| uses: ramsey/composer-install@v3 | |
| with: | |
| dependency-versions: highest | |
| composer-options: "--prefer-dist --no-progress" | |
| - name: Prepare Database | |
| run: | | |
| mysql -u root --password=root --host=127.0.0.1 --port=3306 -e "DROP DATABASE IF EXISTS wordpress_test;" | |
| mysqladmin -u root --password=root --host=127.0.0.1 --port=3306 --force create wordpress_test | |
| - name: Create tests directory structure | |
| run: | | |
| mkdir -p tests/bin | |
| mkdir -p tests/bootstrap | |
| - name: Create WP tests install script | |
| run: | | |
| cat > tests/bin/install-wp-tests.sh << 'EOF' | |
| #!/usr/bin/env bash | |
| if [ $# -lt 3 ]; then | |
| echo "usage: $0 <db-name> <db-user> <db-pass> [db-host] [wp-version] [skip-database-creation]" | |
| exit 1 | |
| fi | |
| DB_NAME=$1 | |
| DB_USER=$2 | |
| DB_PASS=$3 | |
| DB_HOST=${4-localhost} | |
| WP_VERSION=${5-latest} | |
| SKIP_DB_CREATE=${6-false} | |
| WP_TESTS_DIR=${WP_TESTS_DIR-/tmp/wordpress-tests-lib} | |
| WP_CORE_DIR=${WP_CORE_DIR-/tmp/wordpress/} | |
| download() { | |
| if [ $(which curl) ]; then | |
| curl -s "$1" > "$2"; | |
| elif [ $(which wget) ]; then | |
| wget -nv -O "$2" "$1" | |
| fi | |
| } | |
| if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then | |
| WP_TESTS_TAG="tags/$WP_VERSION" | |
| elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then | |
| WP_TESTS_TAG="trunk" | |
| else | |
| download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json | |
| LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//') | |
| if [[ -z "$LATEST_VERSION" ]]; then | |
| echo "Latest WordPress version could not be found" | |
| exit 1 | |
| fi | |
| WP_TESTS_TAG="tags/$LATEST_VERSION" | |
| fi | |
| set -ex | |
| install_wp() { | |
| if [ -d $WP_CORE_DIR ]; then | |
| return; | |
| fi | |
| mkdir -p $WP_CORE_DIR | |
| if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then | |
| mkdir -p /tmp/wordpress-nightly | |
| download https://wordpress.org/nightly-builds/wordpress-latest.zip /tmp/wordpress-nightly/wordpress-nightly.zip | |
| unzip -q /tmp/wordpress-nightly/wordpress-nightly.zip -d /tmp/wordpress-nightly/ | |
| mv /tmp/wordpress-nightly/wordpress/* $WP_CORE_DIR | |
| else | |
| if [ $WP_VERSION == 'latest' ]; then | |
| local ARCHIVE_NAME='latest' | |
| else | |
| local ARCHIVE_NAME="wordpress-$WP_VERSION" | |
| fi | |
| download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz | |
| tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR | |
| fi | |
| download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php | |
| } | |
| install_test_suite() { | |
| if [[ $(uname -s) == 'Darwin' ]]; then | |
| local ioption='-i.bak' | |
| else | |
| local ioption='-i' | |
| fi | |
| if [ ! -d $WP_TESTS_DIR ]; then | |
| mkdir -p $WP_TESTS_DIR | |
| svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes | |
| svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data | |
| fi | |
| if [ ! -f wp-tests-config.php ]; then | |
| download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php | |
| WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::") | |
| sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php | |
| sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php | |
| sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php | |
| sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php | |
| sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php | |
| fi | |
| } | |
| install_db() { | |
| if [ ${SKIP_DB_CREATE} = "true" ]; then | |
| return 0 | |
| fi | |
| local PARTS=(${DB_HOST//\:/ }) | |
| local DB_HOSTNAME=${PARTS[0]}; | |
| local DB_SOCK_OR_PORT=${PARTS[1]}; | |
| local EXTRA="" | |
| if ! [ -z $DB_HOSTNAME ] ; then | |
| if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then | |
| EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp" | |
| elif ! [ -z $DB_SOCK_OR_PORT ] ; then | |
| EXTRA=" --socket=$DB_SOCK_OR_PORT" | |
| elif ! [ -z $DB_HOSTNAME ] ; then | |
| EXTRA=" --host=$DB_HOSTNAME --protocol=tcp" | |
| fi | |
| fi | |
| # First, ensure database doesn't exist (ignore errors) | |
| mysql --user="$DB_USER" --password="$DB_PASS"$EXTRA -e "DROP DATABASE IF EXISTS $DB_NAME" || true | |
| # Now create fresh database with force flag | |
| mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA --force | |
| } | |
| install_wp | |
| install_test_suite | |
| install_db | |
| EOF | |
| chmod +x tests/bin/install-wp-tests.sh | |
| - name: Create Bootstrap File | |
| run: | | |
| mkdir -p tests | |
| cat > tests/bootstrap.php << 'EOF' | |
| <?php | |
| /** | |
| * PHPUnit bootstrap file for plugin tests. | |
| * | |
| * @package Simple_WP_Optimizer | |
| */ | |
| require_once '/tmp/wordpress-tests-lib/includes/functions.php'; | |
| function _manually_load_plugin() { | |
| add_filter('widgets_init', function() { | |
| return; | |
| }, 0); | |
| require dirname( dirname( __FILE__ ) ) . '/simple-wp-optimizer.php'; | |
| } | |
| tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' ); | |
| require '/tmp/wordpress-tests-lib/includes/bootstrap.php'; | |
| EOF | |
| - name: Create Test File | |
| run: | | |
| cat > tests/test-plugin.php << 'EOF' | |
| <?php | |
| /** | |
| * Class Test_Simple_WP_Optimizer | |
| * | |
| * @package Simple_WP_Optimizer | |
| */ | |
| class Test_Simple_WP_Optimizer extends WP_UnitTestCase { | |
| public function test_plugin_loaded() { | |
| $this->assertTrue(function_exists('es_optimizer_init_settings'), 'Plugin was not loaded correctly'); | |
| } | |
| public function test_wordpress_version_compatibility() { | |
| global $wp_version; | |
| $this->assertNotEmpty($wp_version, 'WordPress version should be available'); | |
| // Test that we're running on a supported WordPress version | |
| $min_wp_version = '6.5'; | |
| $this->assertTrue(version_compare($wp_version, $min_wp_version, '>='), | |
| "WordPress version {$wp_version} should be >= {$min_wp_version}"); | |
| } | |
| } | |
| EOF | |
| - name: Create PHPUnit Config | |
| run: | | |
| cat > phpunit.xml << 'EOF' | |
| <?xml version="1.0"?> | |
| <phpunit | |
| bootstrap="tests/bootstrap.php" | |
| backupGlobals="false" | |
| colors="true" | |
| convertErrorsToExceptions="true" | |
| convertNoticesToExceptions="true" | |
| convertWarningsToExceptions="true" | |
| > | |
| <testsuites> | |
| <testsuite name="Simple WP Optimizer"> | |
| <directory prefix="test-" suffix=".php">./tests/</directory> | |
| </testsuite> | |
| </testsuites> | |
| </phpunit> | |
| EOF | |
| - name: Setup WP Tests | |
| run: | | |
| bash tests/bin/install-wp-tests.sh wordpress_test root root 127.0.0.1:3306 ${{ matrix.wp-version }} | |
| - name: Run plugin test | |
| run: vendor/bin/phpunit --config phpunit.xml | |
| - name: Report test status | |
| if: ${{ always() }} | |
| run: | | |
| if [ ${{ job.status }} == 'success' ]; then | |
| echo "✅ Tests passed successfully on PHP ${{ matrix.php-version }} with WordPress ${{ matrix.wp-version }}" | |
| else | |
| echo "❌ Tests failed on PHP ${{ matrix.php-version }} with WordPress ${{ matrix.wp-version }}" | |
| fi | |
| - name: Ensure repository files available after failure | |
| if: ${{ failure() }} | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Create issue on test failure | |
| if: ${{ failure() }} | |
| uses: JasonEtco/create-an-issue@v2 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PHP_VERSION: ${{ matrix.php-version }} | |
| WP_VERSION: ${{ matrix.wp-version }} | |
| RUN_ID: ${{ github.run_id }} | |
| WORKFLOW_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| with: | |
| filename: .github/ISSUE_TEMPLATE/wp-version-test-failure.md | |
| update_existing: false |