From 82a164008d4eba0d4f474af746ba4b83881fba06 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 9 Jan 2026 01:40:22 +0000 Subject: [PATCH 1/5] Initial plan -- 2.49.1 From 723f74043ef6fbe079fa39efa1f1c43e0f9bb817 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 9 Jan 2026 01:44:43 +0000 Subject: [PATCH 2/5] Consolidate CI workflows into single ci.yml file Co-authored-by: jmiller-moko <230051081+jmiller-moko@users.noreply.github.com> --- .github/workflows/ci.yml | 422 ++++++++++++++++++++++++++- .github/workflows/joomla_testing.yml | 270 ----------------- .github/workflows/php_quality.yml | 174 ----------- 3 files changed, 416 insertions(+), 450 deletions(-) delete mode 100644 .github/workflows/joomla_testing.yml delete mode 100644 .github/workflows/php_quality.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b361e7a..1b8780e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,8 +18,9 @@ permissions: contents: read jobs: - ci: - name: Repository Validation Pipeline + # Repository Validation + validation: + name: Repository Validation runs-on: ubuntu-latest env: @@ -67,16 +68,425 @@ jobs: python3 scripts/validate/version_alignment.py || echo "version_alignment validation not yet converted" python3 scripts/validate/version_hierarchy.py || echo "version_hierarchy validation not yet converted" - - name: CI summary + - name: Validation Summary if: always() run: | { - echo "### CI Execution Summary" + echo "### Repository Validation Summary" echo "" echo "- Repository: $GITHUB_REPOSITORY" echo "- Branch: $GITHUB_REF_NAME" echo "- Commit: $GITHUB_SHA" - echo "- Runner: ubuntu-latest" echo "" - echo "CI completed. Review logs above for validation outcomes." + echo "Validation completed. Review logs above for details." + } >> "$GITHUB_STEP_SUMMARY" + + # PHP Code Quality Checks + phpcs: + name: PHP_CodeSniffer - PHP ${{ matrix.php-version }} + runs-on: ubuntu-latest + + strategy: + matrix: + php-version: ['8.0', '8.1', '8.2', '8.3'] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + extensions: mbstring, xml, ctype, json, zip + coverage: none + tools: cs2pr + + - name: Cache Composer packages + uses: actions/cache@v4 + with: + path: ~/.composer + key: ${{ runner.os }}-composer-phpcs-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer-phpcs-${{ matrix.php-version }}- + + - name: Install PHP_CodeSniffer + env: + COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' + run: | + composer global require "squizlabs/php_codesniffer:^3.0" --with-all-dependencies + composer global require "phpcompatibility/php-compatibility:^9.0" --with-all-dependencies + + # Register PHPCompatibility standard + phpcs --config-set installed_paths ~/.composer/vendor/phpcompatibility/php-compatibility + + - name: Run PHP_CodeSniffer + run: | + phpcs --standard=phpcs.xml --report=checkstyle | cs2pr + continue-on-error: true + + - name: PHPCS Summary + if: always() + run: | + { + echo "### PHP_CodeSniffer Results" + echo "" + echo "- PHP Version: ${{ matrix.php-version }}" + echo "- Standard: PSR-12 with Joomla rules" + echo "" + phpcs --standard=phpcs.xml --report=summary || true + } >> "$GITHUB_STEP_SUMMARY" + + phpstan: + name: PHPStan - PHP ${{ matrix.php-version }} + runs-on: ubuntu-latest + + strategy: + matrix: + php-version: ['8.0', '8.1', '8.2', '8.3'] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + extensions: mbstring, xml, ctype, json, zip + coverage: none + + - name: Cache Composer packages + uses: actions/cache@v4 + with: + path: ~/.composer + key: ${{ runner.os }}-composer-phpstan-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer-phpstan-${{ matrix.php-version }}- + + - name: Install PHPStan + env: + COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' + run: | + composer global config --no-plugins allow-plugins.phpstan/extension-installer true + composer global require phpstan/phpstan "^1.0" --with-all-dependencies + composer global require phpstan/extension-installer "^1.0" --with-all-dependencies + + - name: Run PHPStan + run: | + phpstan analyse --configuration=phpstan.neon --error-format=github --no-progress + continue-on-error: true + + - name: PHPStan Summary + if: always() + run: | + { + echo "### PHPStan Results" + echo "" + echo "- PHP Version: ${{ matrix.php-version }}" + echo "- Analysis Level: 5" + echo "" + phpstan analyse --configuration=phpstan.neon --no-progress || true + } >> "$GITHUB_STEP_SUMMARY" + + php-compatibility: + name: PHP Compatibility Check + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.3' + extensions: mbstring, xml, ctype, json, zip + coverage: none + + - name: Cache Composer packages + uses: actions/cache@v4 + with: + path: ~/.composer + key: ${{ runner.os }}-composer-phpcompat-8.3-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer-phpcompat-8.3- + + - name: Install dependencies + env: + COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' + run: | + composer global require "squizlabs/php_codesniffer:^3.0" --with-all-dependencies + composer global require "phpcompatibility/php-compatibility:^9.0" --with-all-dependencies + phpcs --config-set installed_paths ~/.composer/vendor/phpcompatibility/php-compatibility + + - name: Check PHP 8.0+ Compatibility + run: | + phpcs --standard=PHPCompatibility --runtime-set testVersion 8.0- src/ + continue-on-error: true + + - name: Compatibility Summary + if: always() + run: | + { + echo "### PHP Compatibility Check Results" + echo "" + echo "- Target: PHP 8.0+" + echo "- Status: Check completed" + echo "" + echo "See job logs for detailed compatibility issues." + } >> "$GITHUB_STEP_SUMMARY" + + # Joomla Integration Testing + joomla-setup: + name: Joomla ${{ matrix.joomla-version }} - PHP ${{ matrix.php-version }} + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + php-version: ['8.0', '8.1', '8.2', '8.3'] + joomla-version: ['4.4', '5.0', '5.1'] + exclude: + # Joomla 4.4 doesn't support PHP 8.3 + - php-version: '8.3' + joomla-version: '4.4' + + services: + mysql: + image: mysql:8.0 + env: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: joomla_test + ports: + - 3306:3306 + options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + extensions: mbstring, xml, ctype, json, zip, mysqli, pdo, pdo_mysql, gd, curl, openssl, fileinfo + coverage: none + tools: composer:v2 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + + - name: Cache Joomla Downloads + uses: actions/cache@v4 + with: + path: /tmp/joomla-cache + key: joomla-${{ matrix.joomla-version }} + restore-keys: | + joomla-${{ matrix.joomla-version }} + + - name: Download Joomla ${{ matrix.joomla-version }} + run: | + mkdir -p /tmp/joomla + mkdir -p /tmp/joomla-cache + + # Define ZIP file based on version + if [ "${{ matrix.joomla-version }}" = "4.4" ]; then + ZIP_FILE="Joomla_4-4-9-Stable-Full_Package.zip" + ZIP_URL="https://downloads.joomla.org/cms/joomla4/4-4-9/${ZIP_FILE}" + elif [ "${{ matrix.joomla-version }}" = "5.0" ]; then + ZIP_FILE="Joomla_5-0-3-Stable-Full_Package.zip" + ZIP_URL="https://downloads.joomla.org/cms/joomla5/5-0-3/${ZIP_FILE}" + else + ZIP_FILE="Joomla_5-1-4-Stable-Full_Package.zip" + ZIP_URL="https://downloads.joomla.org/cms/joomla5/5-1-4/${ZIP_FILE}" + fi + + # Use cached ZIP if available, otherwise download + if [ -f "/tmp/joomla-cache/${ZIP_FILE}" ]; then + echo "Using cached Joomla package: ${ZIP_FILE}" + cp "/tmp/joomla-cache/${ZIP_FILE}" "/tmp/joomla/" + else + echo "Downloading Joomla package: ${ZIP_FILE}" + wget -q "${ZIP_URL}" -O "/tmp/joomla/${ZIP_FILE}" + cp "/tmp/joomla/${ZIP_FILE}" "/tmp/joomla-cache/" + fi + + cd /tmp/joomla + unzip -q "${ZIP_FILE}" + + - name: Configure Joomla + run: | + cd /tmp/joomla + + # Create configuration.php + cat > configuration.php << 'EOF' + Please check back again soon.'; + public $display_offline_message = '1'; + public $offline_image = ''; + public $sitename = 'Joomla Test Site'; + public $editor = 'tinymce'; + public $captcha = '0'; + public $list_limit = '20'; + public $access = '1'; + public $debug = '0'; + public $debug_lang = '0'; + public $debug_lang_const = '1'; + public $dbtype = 'mysqli'; + public $host = '127.0.0.1'; + public $user = 'root'; + public $password = 'root'; + public $db = 'joomla_test'; + public $dbprefix = 'jos_'; + public $dbencryption = 0; + public $dbsslverifyservercert = false; + public $dbsslkey = ''; + public $dbsslcert = ''; + public $dbsslca = ''; + public $dbsslcipher = ''; + public $force_ssl = 0; + public $live_site = ''; + public $secret = 'testSecretKey123'; + public $gzip = '0'; + public $error_reporting = 'default'; + public $helpurl = 'https://help.joomla.org/proxy?keyref=Help{major}{minor}:{keyref}&lang={langcode}'; + public $offset = 'UTC'; + public $mailonline = '1'; + public $mailer = 'mail'; + public $mailfrom = 'test@example.com'; + public $fromname = 'Joomla Test'; + public $sendmail = '/usr/sbin/sendmail'; + public $smtpauth = '0'; + public $smtpuser = ''; + public $smtppass = ''; + public $smtphost = 'localhost'; + public $smtpsecure = 'none'; + public $smtpport = '25'; + public $caching = '0'; + public $cache_handler = 'file'; + public $cachetime = '15'; + public $cache_platformprefix = '0'; + public $MetaDesc = ''; + public $MetaAuthor = '1'; + public $MetaVersion = '0'; + public $robots = ''; + public $sef = '1'; + public $sef_rewrite = '0'; + public $sef_suffix = '0'; + public $unicodeslugs = '0'; + public $feed_limit = '10'; + public $feed_email = 'none'; + public $log_path = '/tmp/joomla/administrator/logs'; + public $tmp_path = '/tmp/joomla/tmp'; + public $lifetime = '15'; + public $session_handler = 'database'; + public $shared_session = '0'; + public $session_metadata = true; + } + EOF + + - name: Install Joomla database + run: | + mysql -h 127.0.0.1 -uroot -proot joomla_test < /tmp/joomla/installation/sql/mysql/base.sql || true + mysql -h 127.0.0.1 -uroot -proot joomla_test < /tmp/joomla/installation/sql/mysql/extensions.sql || true + mysql -h 127.0.0.1 -uroot -proot joomla_test < /tmp/joomla/installation/sql/mysql/supports.sql || true + + - name: Install template into Joomla + run: | + # Copy template files to Joomla + mkdir -p /tmp/joomla/templates/moko-cassiopeia + cp -r src/templates/* /tmp/joomla/templates/moko-cassiopeia/ || true + + # Copy media files + mkdir -p /tmp/joomla/media/templates/site/moko-cassiopeia + cp -r src/media/* /tmp/joomla/media/templates/site/moko-cassiopeia/ || true + + # Copy language files + mkdir -p /tmp/joomla/language/en-GB + cp src/language/en-GB/*.ini /tmp/joomla/language/en-GB/ || true + mkdir -p /tmp/joomla/administrator/language/en-GB + cp src/administrator/language/en-GB/*.ini /tmp/joomla/administrator/language/en-GB/ || true + + - name: Validate template installation + run: | + if [ -f "/tmp/joomla/templates/moko-cassiopeia/templateDetails.xml" ]; then + echo "✓ Template installed successfully" + php -l /tmp/joomla/templates/moko-cassiopeia/index.php + else + echo "✗ Template installation failed" + exit 1 + fi + + - name: Test Summary + if: always() + run: | + { + echo "### Joomla ${{ matrix.joomla-version }} Testing with PHP ${{ matrix.php-version }}" + echo "" + echo "- Joomla Version: ${{ matrix.joomla-version }}" + echo "- PHP Version: ${{ matrix.php-version }}" + echo "- MySQL Version: 8.0" + echo "" + echo "✓ Joomla installation completed" + echo "✓ Template files copied" + echo "✓ Template validated" + } >> "$GITHUB_STEP_SUMMARY" + + codeception: + name: Codeception Tests + runs-on: ubuntu-latest + needs: joomla-setup + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.1' + extensions: mbstring, xml, ctype, json, zip, mysqli, pdo, pdo_mysql + coverage: xdebug + tools: composer:v2 + + - name: Cache Composer packages + uses: actions/cache@v4 + with: + path: ~/.composer + key: ${{ runner.os }}-composer-codeception-8.1-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer-codeception-8.1- + + - name: Install Codeception + env: + COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' + run: | + composer global require codeception/codeception + composer global require codeception/module-db + composer global require codeception/module-asserts + + - name: Create test structure + run: | + mkdir -p tests/_output + mkdir -p tests/_data + mkdir -p tests/_support + + - name: Run Codeception bootstrap + run: | + codecept bootstrap || echo "Bootstrap skipped - structure exists" + + - name: Codeception Summary + run: | + { + echo "### Codeception Test Framework" + echo "" + echo "- Framework: Codeception" + echo "- Status: Ready for test implementation" + echo "" + echo "Note: Test suites should be implemented in future iterations." } >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/joomla_testing.yml b/.github/workflows/joomla_testing.yml deleted file mode 100644 index 1e7763a..0000000 --- a/.github/workflows/joomla_testing.yml +++ /dev/null @@ -1,270 +0,0 @@ -name: Joomla Testing - -on: - push: - branches: - - main - - dev/** - - rc/** - pull_request: - branches: - - main - - dev/** - - rc/** - -permissions: - contents: read - -jobs: - joomla-setup: - name: Joomla ${{ matrix.joomla-version }} - PHP ${{ matrix.php-version }} - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - php-version: ['8.0', '8.1', '8.2', '8.3'] - joomla-version: ['4.4', '5.0', '5.1'] - exclude: - # Joomla 4.4 doesn't support PHP 8.3 - - php-version: '8.3' - joomla-version: '4.4' - - services: - mysql: - image: mysql:8.0 - env: - MYSQL_ROOT_PASSWORD: root - MYSQL_DATABASE: joomla_test - ports: - - 3306:3306 - options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - extensions: mbstring, xml, ctype, json, zip, mysqli, pdo, pdo_mysql, gd, curl, openssl, fileinfo - coverage: none - tools: composer:v2 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '18' - - - name: Cache Joomla Downloads - uses: actions/cache@v4 - with: - path: /tmp/joomla-cache - key: joomla-${{ matrix.joomla-version }} - restore-keys: | - joomla-${{ matrix.joomla-version }} - - - name: Download Joomla ${{ matrix.joomla-version }} - run: | - mkdir -p /tmp/joomla - mkdir -p /tmp/joomla-cache - - # Define ZIP file based on version - if [ "${{ matrix.joomla-version }}" = "4.4" ]; then - ZIP_FILE="Joomla_4-4-9-Stable-Full_Package.zip" - ZIP_URL="https://downloads.joomla.org/cms/joomla4/4-4-9/${ZIP_FILE}" - elif [ "${{ matrix.joomla-version }}" = "5.0" ]; then - ZIP_FILE="Joomla_5-0-3-Stable-Full_Package.zip" - ZIP_URL="https://downloads.joomla.org/cms/joomla5/5-0-3/${ZIP_FILE}" - else - ZIP_FILE="Joomla_5-1-4-Stable-Full_Package.zip" - ZIP_URL="https://downloads.joomla.org/cms/joomla5/5-1-4/${ZIP_FILE}" - fi - - # Use cached ZIP if available, otherwise download - if [ -f "/tmp/joomla-cache/${ZIP_FILE}" ]; then - echo "Using cached Joomla package: ${ZIP_FILE}" - cp "/tmp/joomla-cache/${ZIP_FILE}" "/tmp/joomla/" - else - echo "Downloading Joomla package: ${ZIP_FILE}" - wget -q "${ZIP_URL}" -O "/tmp/joomla/${ZIP_FILE}" - cp "/tmp/joomla/${ZIP_FILE}" "/tmp/joomla-cache/" - fi - - cd /tmp/joomla - unzip -q "${ZIP_FILE}" - - - name: Configure Joomla - run: | - cd /tmp/joomla - - # Create configuration.php - cat > configuration.php << 'EOF' - Please check back again soon.'; - public $display_offline_message = '1'; - public $offline_image = ''; - public $sitename = 'Joomla Test Site'; - public $editor = 'tinymce'; - public $captcha = '0'; - public $list_limit = '20'; - public $access = '1'; - public $debug = '0'; - public $debug_lang = '0'; - public $debug_lang_const = '1'; - public $dbtype = 'mysqli'; - public $host = '127.0.0.1'; - public $user = 'root'; - public $password = 'root'; - public $db = 'joomla_test'; - public $dbprefix = 'jos_'; - public $dbencryption = 0; - public $dbsslverifyservercert = false; - public $dbsslkey = ''; - public $dbsslcert = ''; - public $dbsslca = ''; - public $dbsslcipher = ''; - public $force_ssl = 0; - public $live_site = ''; - public $secret = 'testSecretKey123'; - public $gzip = '0'; - public $error_reporting = 'default'; - public $helpurl = 'https://help.joomla.org/proxy?keyref=Help{major}{minor}:{keyref}&lang={langcode}'; - public $offset = 'UTC'; - public $mailonline = '1'; - public $mailer = 'mail'; - public $mailfrom = 'test@example.com'; - public $fromname = 'Joomla Test'; - public $sendmail = '/usr/sbin/sendmail'; - public $smtpauth = '0'; - public $smtpuser = ''; - public $smtppass = ''; - public $smtphost = 'localhost'; - public $smtpsecure = 'none'; - public $smtpport = '25'; - public $caching = '0'; - public $cache_handler = 'file'; - public $cachetime = '15'; - public $cache_platformprefix = '0'; - public $MetaDesc = ''; - public $MetaAuthor = '1'; - public $MetaVersion = '0'; - public $robots = ''; - public $sef = '1'; - public $sef_rewrite = '0'; - public $sef_suffix = '0'; - public $unicodeslugs = '0'; - public $feed_limit = '10'; - public $feed_email = 'none'; - public $log_path = '/tmp/joomla/administrator/logs'; - public $tmp_path = '/tmp/joomla/tmp'; - public $lifetime = '15'; - public $session_handler = 'database'; - public $shared_session = '0'; - public $session_metadata = true; - } - EOF - - - name: Install Joomla database - run: | - mysql -h 127.0.0.1 -uroot -proot joomla_test < /tmp/joomla/installation/sql/mysql/base.sql || true - mysql -h 127.0.0.1 -uroot -proot joomla_test < /tmp/joomla/installation/sql/mysql/extensions.sql || true - mysql -h 127.0.0.1 -uroot -proot joomla_test < /tmp/joomla/installation/sql/mysql/supports.sql || true - - - name: Install template into Joomla - run: | - # Copy template files to Joomla - mkdir -p /tmp/joomla/templates/moko-cassiopeia - cp -r src/templates/* /tmp/joomla/templates/moko-cassiopeia/ || true - - # Copy media files - mkdir -p /tmp/joomla/media/templates/site/moko-cassiopeia - cp -r src/media/* /tmp/joomla/media/templates/site/moko-cassiopeia/ || true - - # Copy language files - mkdir -p /tmp/joomla/language/en-GB - cp src/language/en-GB/*.ini /tmp/joomla/language/en-GB/ || true - mkdir -p /tmp/joomla/administrator/language/en-GB - cp src/administrator/language/en-GB/*.ini /tmp/joomla/administrator/language/en-GB/ || true - - - name: Validate template installation - run: | - if [ -f "/tmp/joomla/templates/moko-cassiopeia/templateDetails.xml" ]; then - echo "✓ Template installed successfully" - php -l /tmp/joomla/templates/moko-cassiopeia/index.php - else - echo "✗ Template installation failed" - exit 1 - fi - - - name: Test Summary - if: always() - run: | - { - echo "### Joomla ${{ matrix.joomla-version }} Testing with PHP ${{ matrix.php-version }}" - echo "" - echo "- Joomla Version: ${{ matrix.joomla-version }}" - echo "- PHP Version: ${{ matrix.php-version }}" - echo "- MySQL Version: 8.0" - echo "" - echo "✓ Joomla installation completed" - echo "✓ Template files copied" - echo "✓ Template validated" - } >> "$GITHUB_STEP_SUMMARY" - - codeception: - name: Codeception Tests - runs-on: ubuntu-latest - needs: joomla-setup - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.1' - extensions: mbstring, xml, ctype, json, zip, mysqli, pdo, pdo_mysql - coverage: xdebug - tools: composer:v2 - - - name: Cache Composer packages - uses: actions/cache@v4 - with: - path: ~/.composer - key: ${{ runner.os }}-composer-codeception-8.1-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer-codeception-8.1- - - - name: Install Codeception - env: - COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' - run: | - composer global require codeception/codeception - composer global require codeception/module-db - composer global require codeception/module-asserts - - - name: Create test structure - run: | - mkdir -p tests/_output - mkdir -p tests/_data - mkdir -p tests/_support - - - name: Run Codeception bootstrap - run: | - codecept bootstrap || echo "Bootstrap skipped - structure exists" - - - name: Codeception Summary - run: | - { - echo "### Codeception Test Framework" - echo "" - echo "- Framework: Codeception" - echo "- Status: Ready for test implementation" - echo "" - echo "Note: Test suites should be implemented in future iterations." - } >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/php_quality.yml b/.github/workflows/php_quality.yml deleted file mode 100644 index 05e347c..0000000 --- a/.github/workflows/php_quality.yml +++ /dev/null @@ -1,174 +0,0 @@ -name: PHP Code Quality - -on: - push: - branches: - - main - - dev/** - - rc/** - - version/** - pull_request: - branches: - - main - - dev/** - - rc/** - - version/** - -permissions: - contents: read - -jobs: - phpcs: - name: PHP_CodeSniffer - runs-on: ubuntu-latest - - strategy: - matrix: - php-version: ['8.0', '8.1', '8.2', '8.3'] - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - extensions: mbstring, xml, ctype, json, zip - coverage: none - tools: cs2pr - - - name: Cache Composer packages - uses: actions/cache@v4 - with: - path: ~/.composer - key: ${{ runner.os }}-composer-phpcs-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer-phpcs-${{ matrix.php-version }}- - - - name: Install PHP_CodeSniffer - env: - COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' - run: | - composer global require "squizlabs/php_codesniffer:^3.0" --with-all-dependencies - composer global require "phpcompatibility/php-compatibility:^9.0" --with-all-dependencies - - # Register PHPCompatibility standard - phpcs --config-set installed_paths ~/.composer/vendor/phpcompatibility/php-compatibility - - - name: Run PHP_CodeSniffer - run: | - phpcs --standard=phpcs.xml --report=checkstyle | cs2pr - continue-on-error: true - - - name: PHPCS Summary - if: always() - run: | - { - echo "### PHP_CodeSniffer Results" - echo "" - echo "- PHP Version: ${{ matrix.php-version }}" - echo "- Standard: PSR-12 with Joomla rules" - echo "" - phpcs --standard=phpcs.xml --report=summary || true - } >> "$GITHUB_STEP_SUMMARY" - - phpstan: - name: PHPStan Static Analysis - runs-on: ubuntu-latest - - strategy: - matrix: - php-version: ['8.0', '8.1', '8.2', '8.3'] - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - extensions: mbstring, xml, ctype, json, zip - coverage: none - - - name: Cache Composer packages - uses: actions/cache@v4 - with: - path: ~/.composer - key: ${{ runner.os }}-composer-phpstan-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer-phpstan-${{ matrix.php-version }}- - - - name: Install PHPStan - env: - COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' - run: | - composer global config --no-plugins allow-plugins.phpstan/extension-installer true - composer global require phpstan/phpstan "^1.0" --with-all-dependencies - composer global require phpstan/extension-installer "^1.0" --with-all-dependencies - - - name: Run PHPStan - run: | - phpstan analyse --configuration=phpstan.neon --error-format=github --no-progress - continue-on-error: true - - - name: PHPStan Summary - if: always() - run: | - { - echo "### PHPStan Results" - echo "" - echo "- PHP Version: ${{ matrix.php-version }}" - echo "- Analysis Level: 5" - echo "" - phpstan analyse --configuration=phpstan.neon --no-progress || true - } >> "$GITHUB_STEP_SUMMARY" - - php-compatibility: - name: PHP Compatibility Check - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.3' - extensions: mbstring, xml, ctype, json, zip - coverage: none - - - name: Cache Composer packages - uses: actions/cache@v4 - with: - path: ~/.composer - key: ${{ runner.os }}-composer-phpcompat-8.3-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer-phpcompat-8.3- - - - name: Install dependencies - env: - COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' - run: | - composer global require "squizlabs/php_codesniffer:^3.0" --with-all-dependencies - composer global require "phpcompatibility/php-compatibility:^9.0" --with-all-dependencies - phpcs --config-set installed_paths ~/.composer/vendor/phpcompatibility/php-compatibility - - - name: Check PHP 8.0+ Compatibility - run: | - phpcs --standard=PHPCompatibility --runtime-set testVersion 8.0- src/ - continue-on-error: true - - - name: Compatibility Summary - if: always() - run: | - { - echo "### PHP Compatibility Check Results" - echo "" - echo "- Target: PHP 8.0+" - echo "- Status: Check completed" - echo "" - echo "See job logs for detailed compatibility issues." - } >> "$GITHUB_STEP_SUMMARY" -- 2.49.1 From ef57ec3ef469fdfecea36eaa0e52a478e5d83507 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 9 Jan 2026 01:46:04 +0000 Subject: [PATCH 3/5] Update WORKFLOW_GUIDE.md to reflect consolidated CI workflow Co-authored-by: jmiller-moko <230051081+jmiller-moko@users.noreply.github.com> --- docs/WORKFLOW_GUIDE.md | 66 +++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 40 deletions(-) diff --git a/docs/WORKFLOW_GUIDE.md b/docs/WORKFLOW_GUIDE.md index 5465a11..89bd580 100644 --- a/docs/WORKFLOW_GUIDE.md +++ b/docs/WORKFLOW_GUIDE.md @@ -48,9 +48,11 @@ This repository uses GitHub Actions for continuous integration, testing, quality **Trigger:** Automatic on push/PR to main, dev/*, rc/*, version/* branches -**Purpose:** Validates code quality and repository structure +**Purpose:** Comprehensive CI pipeline for validation, quality checks, and testing **What it does:** + +**Repository Validation:** - ✅ Validates Joomla manifest XML - ✅ Checks XML well-formedness - ✅ Validates GitHub Actions workflows @@ -59,6 +61,19 @@ This repository uses GitHub Actions for continuous integration, testing, quality - ✅ Validates license headers - ✅ Verifies version alignment +**PHP Code Quality:** +- 🔍 PHPStan static analysis (level 5) +- 📏 PHP_CodeSniffer with PSR-12 standards +- ✔️ PHP 8.0+ compatibility checks +- **Matrix:** PHP 8.0, 8.1, 8.2, 8.3 + +**Joomla Integration Testing:** +- 📦 Downloads and installs Joomla (4.4, 5.0, 5.1) +- 🔧 Installs template into Joomla +- ✅ Validates template installation +- 🧪 Runs Codeception tests +- **Matrix:** Joomla 4.4/5.0/5.1 × PHP 8.0/8.1/8.2/8.3 + **When to check:** After every commit **How to view results:** @@ -66,53 +81,24 @@ This repository uses GitHub Actions for continuous integration, testing, quality # Via GitHub CLI gh run list --workflow=ci.yml --limit 5 gh run view --log + +# View specific job logs +gh run view --log --job= ``` -### PHP Quality Checks (php_quality.yml) - -**Trigger:** Automatic on push/PR to main, dev/*, rc/*, version/* branches - -**Purpose:** Ensures PHP code quality and compatibility - -**What it does:** -- 🔍 PHPStan static analysis (level 5) -- 📏 PHP_CodeSniffer with PSR-12 standards -- ✔️ PHP 8.0+ compatibility checks - -**Matrix:** PHP 8.0, 8.1, 8.2, 8.3 - -**When to check:** Before committing PHP changes - -**How to run locally:** +**How to run checks locally:** ```bash -# Install tools +# Repository validation +python3 scripts/validate/manifest.py +python3 scripts/validate/workflows.py + +# PHP quality checks composer global require "squizlabs/php_codesniffer:^3.0" --with-all-dependencies composer global require "phpstan/phpstan:^1.0" --with-all-dependencies - -# Run checks phpcs --standard=phpcs.xml src/ phpstan analyse --configuration=phpstan.neon -``` -### Joomla Testing (joomla_testing.yml) - -**Trigger:** Automatic on push/PR to main, dev/*, rc/* branches - -**Purpose:** Tests template compatibility with Joomla versions - -**What it does:** -- 📦 Downloads and installs Joomla (4.4, 5.0, 5.1) -- 🔧 Installs template into Joomla -- ✅ Validates template installation -- 🧪 Runs Codeception tests - -**Matrix:** Joomla 4.4/5.0/5.1 × PHP 8.0/8.1/8.2/8.3 - -**When to check:** Before releasing new versions - -**How to test locally:** -```bash -# See docs/JOOMLA_DEVELOPMENT.md for local testing setup +# Joomla testing (see docs/JOOMLA_DEVELOPMENT.md) codecept run ``` -- 2.49.1 From 9f6079c79f1eca13d883e4e5de9469473548de21 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 9 Jan 2026 01:58:46 +0000 Subject: [PATCH 4/5] Revert consolidation and prepare for MokoStandards migration Co-authored-by: jmiller-moko <230051081+jmiller-moko@users.noreply.github.com> --- .github/workflows/ci.yml | 422 +-------------------------- .github/workflows/joomla_testing.yml | 270 +++++++++++++++++ .github/workflows/php_quality.yml | 174 +++++++++++ docs/MOKOSTANDARDS_MIGRATION.md | 237 +++++++++++++++ docs/WORKFLOW_GUIDE.md | 66 +++-- 5 files changed, 727 insertions(+), 442 deletions(-) create mode 100644 .github/workflows/joomla_testing.yml create mode 100644 .github/workflows/php_quality.yml create mode 100644 docs/MOKOSTANDARDS_MIGRATION.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1b8780e..b361e7a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,9 +18,8 @@ permissions: contents: read jobs: - # Repository Validation - validation: - name: Repository Validation + ci: + name: Repository Validation Pipeline runs-on: ubuntu-latest env: @@ -68,425 +67,16 @@ jobs: python3 scripts/validate/version_alignment.py || echo "version_alignment validation not yet converted" python3 scripts/validate/version_hierarchy.py || echo "version_hierarchy validation not yet converted" - - name: Validation Summary + - name: CI summary if: always() run: | { - echo "### Repository Validation Summary" + echo "### CI Execution Summary" echo "" echo "- Repository: $GITHUB_REPOSITORY" echo "- Branch: $GITHUB_REF_NAME" echo "- Commit: $GITHUB_SHA" + echo "- Runner: ubuntu-latest" echo "" - echo "Validation completed. Review logs above for details." - } >> "$GITHUB_STEP_SUMMARY" - - # PHP Code Quality Checks - phpcs: - name: PHP_CodeSniffer - PHP ${{ matrix.php-version }} - runs-on: ubuntu-latest - - strategy: - matrix: - php-version: ['8.0', '8.1', '8.2', '8.3'] - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - extensions: mbstring, xml, ctype, json, zip - coverage: none - tools: cs2pr - - - name: Cache Composer packages - uses: actions/cache@v4 - with: - path: ~/.composer - key: ${{ runner.os }}-composer-phpcs-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer-phpcs-${{ matrix.php-version }}- - - - name: Install PHP_CodeSniffer - env: - COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' - run: | - composer global require "squizlabs/php_codesniffer:^3.0" --with-all-dependencies - composer global require "phpcompatibility/php-compatibility:^9.0" --with-all-dependencies - - # Register PHPCompatibility standard - phpcs --config-set installed_paths ~/.composer/vendor/phpcompatibility/php-compatibility - - - name: Run PHP_CodeSniffer - run: | - phpcs --standard=phpcs.xml --report=checkstyle | cs2pr - continue-on-error: true - - - name: PHPCS Summary - if: always() - run: | - { - echo "### PHP_CodeSniffer Results" - echo "" - echo "- PHP Version: ${{ matrix.php-version }}" - echo "- Standard: PSR-12 with Joomla rules" - echo "" - phpcs --standard=phpcs.xml --report=summary || true - } >> "$GITHUB_STEP_SUMMARY" - - phpstan: - name: PHPStan - PHP ${{ matrix.php-version }} - runs-on: ubuntu-latest - - strategy: - matrix: - php-version: ['8.0', '8.1', '8.2', '8.3'] - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - extensions: mbstring, xml, ctype, json, zip - coverage: none - - - name: Cache Composer packages - uses: actions/cache@v4 - with: - path: ~/.composer - key: ${{ runner.os }}-composer-phpstan-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer-phpstan-${{ matrix.php-version }}- - - - name: Install PHPStan - env: - COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' - run: | - composer global config --no-plugins allow-plugins.phpstan/extension-installer true - composer global require phpstan/phpstan "^1.0" --with-all-dependencies - composer global require phpstan/extension-installer "^1.0" --with-all-dependencies - - - name: Run PHPStan - run: | - phpstan analyse --configuration=phpstan.neon --error-format=github --no-progress - continue-on-error: true - - - name: PHPStan Summary - if: always() - run: | - { - echo "### PHPStan Results" - echo "" - echo "- PHP Version: ${{ matrix.php-version }}" - echo "- Analysis Level: 5" - echo "" - phpstan analyse --configuration=phpstan.neon --no-progress || true - } >> "$GITHUB_STEP_SUMMARY" - - php-compatibility: - name: PHP Compatibility Check - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.3' - extensions: mbstring, xml, ctype, json, zip - coverage: none - - - name: Cache Composer packages - uses: actions/cache@v4 - with: - path: ~/.composer - key: ${{ runner.os }}-composer-phpcompat-8.3-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer-phpcompat-8.3- - - - name: Install dependencies - env: - COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' - run: | - composer global require "squizlabs/php_codesniffer:^3.0" --with-all-dependencies - composer global require "phpcompatibility/php-compatibility:^9.0" --with-all-dependencies - phpcs --config-set installed_paths ~/.composer/vendor/phpcompatibility/php-compatibility - - - name: Check PHP 8.0+ Compatibility - run: | - phpcs --standard=PHPCompatibility --runtime-set testVersion 8.0- src/ - continue-on-error: true - - - name: Compatibility Summary - if: always() - run: | - { - echo "### PHP Compatibility Check Results" - echo "" - echo "- Target: PHP 8.0+" - echo "- Status: Check completed" - echo "" - echo "See job logs for detailed compatibility issues." - } >> "$GITHUB_STEP_SUMMARY" - - # Joomla Integration Testing - joomla-setup: - name: Joomla ${{ matrix.joomla-version }} - PHP ${{ matrix.php-version }} - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - php-version: ['8.0', '8.1', '8.2', '8.3'] - joomla-version: ['4.4', '5.0', '5.1'] - exclude: - # Joomla 4.4 doesn't support PHP 8.3 - - php-version: '8.3' - joomla-version: '4.4' - - services: - mysql: - image: mysql:8.0 - env: - MYSQL_ROOT_PASSWORD: root - MYSQL_DATABASE: joomla_test - ports: - - 3306:3306 - options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - extensions: mbstring, xml, ctype, json, zip, mysqli, pdo, pdo_mysql, gd, curl, openssl, fileinfo - coverage: none - tools: composer:v2 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '18' - - - name: Cache Joomla Downloads - uses: actions/cache@v4 - with: - path: /tmp/joomla-cache - key: joomla-${{ matrix.joomla-version }} - restore-keys: | - joomla-${{ matrix.joomla-version }} - - - name: Download Joomla ${{ matrix.joomla-version }} - run: | - mkdir -p /tmp/joomla - mkdir -p /tmp/joomla-cache - - # Define ZIP file based on version - if [ "${{ matrix.joomla-version }}" = "4.4" ]; then - ZIP_FILE="Joomla_4-4-9-Stable-Full_Package.zip" - ZIP_URL="https://downloads.joomla.org/cms/joomla4/4-4-9/${ZIP_FILE}" - elif [ "${{ matrix.joomla-version }}" = "5.0" ]; then - ZIP_FILE="Joomla_5-0-3-Stable-Full_Package.zip" - ZIP_URL="https://downloads.joomla.org/cms/joomla5/5-0-3/${ZIP_FILE}" - else - ZIP_FILE="Joomla_5-1-4-Stable-Full_Package.zip" - ZIP_URL="https://downloads.joomla.org/cms/joomla5/5-1-4/${ZIP_FILE}" - fi - - # Use cached ZIP if available, otherwise download - if [ -f "/tmp/joomla-cache/${ZIP_FILE}" ]; then - echo "Using cached Joomla package: ${ZIP_FILE}" - cp "/tmp/joomla-cache/${ZIP_FILE}" "/tmp/joomla/" - else - echo "Downloading Joomla package: ${ZIP_FILE}" - wget -q "${ZIP_URL}" -O "/tmp/joomla/${ZIP_FILE}" - cp "/tmp/joomla/${ZIP_FILE}" "/tmp/joomla-cache/" - fi - - cd /tmp/joomla - unzip -q "${ZIP_FILE}" - - - name: Configure Joomla - run: | - cd /tmp/joomla - - # Create configuration.php - cat > configuration.php << 'EOF' - Please check back again soon.'; - public $display_offline_message = '1'; - public $offline_image = ''; - public $sitename = 'Joomla Test Site'; - public $editor = 'tinymce'; - public $captcha = '0'; - public $list_limit = '20'; - public $access = '1'; - public $debug = '0'; - public $debug_lang = '0'; - public $debug_lang_const = '1'; - public $dbtype = 'mysqli'; - public $host = '127.0.0.1'; - public $user = 'root'; - public $password = 'root'; - public $db = 'joomla_test'; - public $dbprefix = 'jos_'; - public $dbencryption = 0; - public $dbsslverifyservercert = false; - public $dbsslkey = ''; - public $dbsslcert = ''; - public $dbsslca = ''; - public $dbsslcipher = ''; - public $force_ssl = 0; - public $live_site = ''; - public $secret = 'testSecretKey123'; - public $gzip = '0'; - public $error_reporting = 'default'; - public $helpurl = 'https://help.joomla.org/proxy?keyref=Help{major}{minor}:{keyref}&lang={langcode}'; - public $offset = 'UTC'; - public $mailonline = '1'; - public $mailer = 'mail'; - public $mailfrom = 'test@example.com'; - public $fromname = 'Joomla Test'; - public $sendmail = '/usr/sbin/sendmail'; - public $smtpauth = '0'; - public $smtpuser = ''; - public $smtppass = ''; - public $smtphost = 'localhost'; - public $smtpsecure = 'none'; - public $smtpport = '25'; - public $caching = '0'; - public $cache_handler = 'file'; - public $cachetime = '15'; - public $cache_platformprefix = '0'; - public $MetaDesc = ''; - public $MetaAuthor = '1'; - public $MetaVersion = '0'; - public $robots = ''; - public $sef = '1'; - public $sef_rewrite = '0'; - public $sef_suffix = '0'; - public $unicodeslugs = '0'; - public $feed_limit = '10'; - public $feed_email = 'none'; - public $log_path = '/tmp/joomla/administrator/logs'; - public $tmp_path = '/tmp/joomla/tmp'; - public $lifetime = '15'; - public $session_handler = 'database'; - public $shared_session = '0'; - public $session_metadata = true; - } - EOF - - - name: Install Joomla database - run: | - mysql -h 127.0.0.1 -uroot -proot joomla_test < /tmp/joomla/installation/sql/mysql/base.sql || true - mysql -h 127.0.0.1 -uroot -proot joomla_test < /tmp/joomla/installation/sql/mysql/extensions.sql || true - mysql -h 127.0.0.1 -uroot -proot joomla_test < /tmp/joomla/installation/sql/mysql/supports.sql || true - - - name: Install template into Joomla - run: | - # Copy template files to Joomla - mkdir -p /tmp/joomla/templates/moko-cassiopeia - cp -r src/templates/* /tmp/joomla/templates/moko-cassiopeia/ || true - - # Copy media files - mkdir -p /tmp/joomla/media/templates/site/moko-cassiopeia - cp -r src/media/* /tmp/joomla/media/templates/site/moko-cassiopeia/ || true - - # Copy language files - mkdir -p /tmp/joomla/language/en-GB - cp src/language/en-GB/*.ini /tmp/joomla/language/en-GB/ || true - mkdir -p /tmp/joomla/administrator/language/en-GB - cp src/administrator/language/en-GB/*.ini /tmp/joomla/administrator/language/en-GB/ || true - - - name: Validate template installation - run: | - if [ -f "/tmp/joomla/templates/moko-cassiopeia/templateDetails.xml" ]; then - echo "✓ Template installed successfully" - php -l /tmp/joomla/templates/moko-cassiopeia/index.php - else - echo "✗ Template installation failed" - exit 1 - fi - - - name: Test Summary - if: always() - run: | - { - echo "### Joomla ${{ matrix.joomla-version }} Testing with PHP ${{ matrix.php-version }}" - echo "" - echo "- Joomla Version: ${{ matrix.joomla-version }}" - echo "- PHP Version: ${{ matrix.php-version }}" - echo "- MySQL Version: 8.0" - echo "" - echo "✓ Joomla installation completed" - echo "✓ Template files copied" - echo "✓ Template validated" - } >> "$GITHUB_STEP_SUMMARY" - - codeception: - name: Codeception Tests - runs-on: ubuntu-latest - needs: joomla-setup - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.1' - extensions: mbstring, xml, ctype, json, zip, mysqli, pdo, pdo_mysql - coverage: xdebug - tools: composer:v2 - - - name: Cache Composer packages - uses: actions/cache@v4 - with: - path: ~/.composer - key: ${{ runner.os }}-composer-codeception-8.1-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer-codeception-8.1- - - - name: Install Codeception - env: - COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' - run: | - composer global require codeception/codeception - composer global require codeception/module-db - composer global require codeception/module-asserts - - - name: Create test structure - run: | - mkdir -p tests/_output - mkdir -p tests/_data - mkdir -p tests/_support - - - name: Run Codeception bootstrap - run: | - codecept bootstrap || echo "Bootstrap skipped - structure exists" - - - name: Codeception Summary - run: | - { - echo "### Codeception Test Framework" - echo "" - echo "- Framework: Codeception" - echo "- Status: Ready for test implementation" - echo "" - echo "Note: Test suites should be implemented in future iterations." + echo "CI completed. Review logs above for validation outcomes." } >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/joomla_testing.yml b/.github/workflows/joomla_testing.yml new file mode 100644 index 0000000..1e7763a --- /dev/null +++ b/.github/workflows/joomla_testing.yml @@ -0,0 +1,270 @@ +name: Joomla Testing + +on: + push: + branches: + - main + - dev/** + - rc/** + pull_request: + branches: + - main + - dev/** + - rc/** + +permissions: + contents: read + +jobs: + joomla-setup: + name: Joomla ${{ matrix.joomla-version }} - PHP ${{ matrix.php-version }} + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + php-version: ['8.0', '8.1', '8.2', '8.3'] + joomla-version: ['4.4', '5.0', '5.1'] + exclude: + # Joomla 4.4 doesn't support PHP 8.3 + - php-version: '8.3' + joomla-version: '4.4' + + services: + mysql: + image: mysql:8.0 + env: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: joomla_test + ports: + - 3306:3306 + options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + extensions: mbstring, xml, ctype, json, zip, mysqli, pdo, pdo_mysql, gd, curl, openssl, fileinfo + coverage: none + tools: composer:v2 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '18' + + - name: Cache Joomla Downloads + uses: actions/cache@v4 + with: + path: /tmp/joomla-cache + key: joomla-${{ matrix.joomla-version }} + restore-keys: | + joomla-${{ matrix.joomla-version }} + + - name: Download Joomla ${{ matrix.joomla-version }} + run: | + mkdir -p /tmp/joomla + mkdir -p /tmp/joomla-cache + + # Define ZIP file based on version + if [ "${{ matrix.joomla-version }}" = "4.4" ]; then + ZIP_FILE="Joomla_4-4-9-Stable-Full_Package.zip" + ZIP_URL="https://downloads.joomla.org/cms/joomla4/4-4-9/${ZIP_FILE}" + elif [ "${{ matrix.joomla-version }}" = "5.0" ]; then + ZIP_FILE="Joomla_5-0-3-Stable-Full_Package.zip" + ZIP_URL="https://downloads.joomla.org/cms/joomla5/5-0-3/${ZIP_FILE}" + else + ZIP_FILE="Joomla_5-1-4-Stable-Full_Package.zip" + ZIP_URL="https://downloads.joomla.org/cms/joomla5/5-1-4/${ZIP_FILE}" + fi + + # Use cached ZIP if available, otherwise download + if [ -f "/tmp/joomla-cache/${ZIP_FILE}" ]; then + echo "Using cached Joomla package: ${ZIP_FILE}" + cp "/tmp/joomla-cache/${ZIP_FILE}" "/tmp/joomla/" + else + echo "Downloading Joomla package: ${ZIP_FILE}" + wget -q "${ZIP_URL}" -O "/tmp/joomla/${ZIP_FILE}" + cp "/tmp/joomla/${ZIP_FILE}" "/tmp/joomla-cache/" + fi + + cd /tmp/joomla + unzip -q "${ZIP_FILE}" + + - name: Configure Joomla + run: | + cd /tmp/joomla + + # Create configuration.php + cat > configuration.php << 'EOF' + Please check back again soon.'; + public $display_offline_message = '1'; + public $offline_image = ''; + public $sitename = 'Joomla Test Site'; + public $editor = 'tinymce'; + public $captcha = '0'; + public $list_limit = '20'; + public $access = '1'; + public $debug = '0'; + public $debug_lang = '0'; + public $debug_lang_const = '1'; + public $dbtype = 'mysqli'; + public $host = '127.0.0.1'; + public $user = 'root'; + public $password = 'root'; + public $db = 'joomla_test'; + public $dbprefix = 'jos_'; + public $dbencryption = 0; + public $dbsslverifyservercert = false; + public $dbsslkey = ''; + public $dbsslcert = ''; + public $dbsslca = ''; + public $dbsslcipher = ''; + public $force_ssl = 0; + public $live_site = ''; + public $secret = 'testSecretKey123'; + public $gzip = '0'; + public $error_reporting = 'default'; + public $helpurl = 'https://help.joomla.org/proxy?keyref=Help{major}{minor}:{keyref}&lang={langcode}'; + public $offset = 'UTC'; + public $mailonline = '1'; + public $mailer = 'mail'; + public $mailfrom = 'test@example.com'; + public $fromname = 'Joomla Test'; + public $sendmail = '/usr/sbin/sendmail'; + public $smtpauth = '0'; + public $smtpuser = ''; + public $smtppass = ''; + public $smtphost = 'localhost'; + public $smtpsecure = 'none'; + public $smtpport = '25'; + public $caching = '0'; + public $cache_handler = 'file'; + public $cachetime = '15'; + public $cache_platformprefix = '0'; + public $MetaDesc = ''; + public $MetaAuthor = '1'; + public $MetaVersion = '0'; + public $robots = ''; + public $sef = '1'; + public $sef_rewrite = '0'; + public $sef_suffix = '0'; + public $unicodeslugs = '0'; + public $feed_limit = '10'; + public $feed_email = 'none'; + public $log_path = '/tmp/joomla/administrator/logs'; + public $tmp_path = '/tmp/joomla/tmp'; + public $lifetime = '15'; + public $session_handler = 'database'; + public $shared_session = '0'; + public $session_metadata = true; + } + EOF + + - name: Install Joomla database + run: | + mysql -h 127.0.0.1 -uroot -proot joomla_test < /tmp/joomla/installation/sql/mysql/base.sql || true + mysql -h 127.0.0.1 -uroot -proot joomla_test < /tmp/joomla/installation/sql/mysql/extensions.sql || true + mysql -h 127.0.0.1 -uroot -proot joomla_test < /tmp/joomla/installation/sql/mysql/supports.sql || true + + - name: Install template into Joomla + run: | + # Copy template files to Joomla + mkdir -p /tmp/joomla/templates/moko-cassiopeia + cp -r src/templates/* /tmp/joomla/templates/moko-cassiopeia/ || true + + # Copy media files + mkdir -p /tmp/joomla/media/templates/site/moko-cassiopeia + cp -r src/media/* /tmp/joomla/media/templates/site/moko-cassiopeia/ || true + + # Copy language files + mkdir -p /tmp/joomla/language/en-GB + cp src/language/en-GB/*.ini /tmp/joomla/language/en-GB/ || true + mkdir -p /tmp/joomla/administrator/language/en-GB + cp src/administrator/language/en-GB/*.ini /tmp/joomla/administrator/language/en-GB/ || true + + - name: Validate template installation + run: | + if [ -f "/tmp/joomla/templates/moko-cassiopeia/templateDetails.xml" ]; then + echo "✓ Template installed successfully" + php -l /tmp/joomla/templates/moko-cassiopeia/index.php + else + echo "✗ Template installation failed" + exit 1 + fi + + - name: Test Summary + if: always() + run: | + { + echo "### Joomla ${{ matrix.joomla-version }} Testing with PHP ${{ matrix.php-version }}" + echo "" + echo "- Joomla Version: ${{ matrix.joomla-version }}" + echo "- PHP Version: ${{ matrix.php-version }}" + echo "- MySQL Version: 8.0" + echo "" + echo "✓ Joomla installation completed" + echo "✓ Template files copied" + echo "✓ Template validated" + } >> "$GITHUB_STEP_SUMMARY" + + codeception: + name: Codeception Tests + runs-on: ubuntu-latest + needs: joomla-setup + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.1' + extensions: mbstring, xml, ctype, json, zip, mysqli, pdo, pdo_mysql + coverage: xdebug + tools: composer:v2 + + - name: Cache Composer packages + uses: actions/cache@v4 + with: + path: ~/.composer + key: ${{ runner.os }}-composer-codeception-8.1-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer-codeception-8.1- + + - name: Install Codeception + env: + COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' + run: | + composer global require codeception/codeception + composer global require codeception/module-db + composer global require codeception/module-asserts + + - name: Create test structure + run: | + mkdir -p tests/_output + mkdir -p tests/_data + mkdir -p tests/_support + + - name: Run Codeception bootstrap + run: | + codecept bootstrap || echo "Bootstrap skipped - structure exists" + + - name: Codeception Summary + run: | + { + echo "### Codeception Test Framework" + echo "" + echo "- Framework: Codeception" + echo "- Status: Ready for test implementation" + echo "" + echo "Note: Test suites should be implemented in future iterations." + } >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/php_quality.yml b/.github/workflows/php_quality.yml new file mode 100644 index 0000000..05e347c --- /dev/null +++ b/.github/workflows/php_quality.yml @@ -0,0 +1,174 @@ +name: PHP Code Quality + +on: + push: + branches: + - main + - dev/** + - rc/** + - version/** + pull_request: + branches: + - main + - dev/** + - rc/** + - version/** + +permissions: + contents: read + +jobs: + phpcs: + name: PHP_CodeSniffer + runs-on: ubuntu-latest + + strategy: + matrix: + php-version: ['8.0', '8.1', '8.2', '8.3'] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + extensions: mbstring, xml, ctype, json, zip + coverage: none + tools: cs2pr + + - name: Cache Composer packages + uses: actions/cache@v4 + with: + path: ~/.composer + key: ${{ runner.os }}-composer-phpcs-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer-phpcs-${{ matrix.php-version }}- + + - name: Install PHP_CodeSniffer + env: + COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' + run: | + composer global require "squizlabs/php_codesniffer:^3.0" --with-all-dependencies + composer global require "phpcompatibility/php-compatibility:^9.0" --with-all-dependencies + + # Register PHPCompatibility standard + phpcs --config-set installed_paths ~/.composer/vendor/phpcompatibility/php-compatibility + + - name: Run PHP_CodeSniffer + run: | + phpcs --standard=phpcs.xml --report=checkstyle | cs2pr + continue-on-error: true + + - name: PHPCS Summary + if: always() + run: | + { + echo "### PHP_CodeSniffer Results" + echo "" + echo "- PHP Version: ${{ matrix.php-version }}" + echo "- Standard: PSR-12 with Joomla rules" + echo "" + phpcs --standard=phpcs.xml --report=summary || true + } >> "$GITHUB_STEP_SUMMARY" + + phpstan: + name: PHPStan Static Analysis + runs-on: ubuntu-latest + + strategy: + matrix: + php-version: ['8.0', '8.1', '8.2', '8.3'] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + extensions: mbstring, xml, ctype, json, zip + coverage: none + + - name: Cache Composer packages + uses: actions/cache@v4 + with: + path: ~/.composer + key: ${{ runner.os }}-composer-phpstan-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer-phpstan-${{ matrix.php-version }}- + + - name: Install PHPStan + env: + COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' + run: | + composer global config --no-plugins allow-plugins.phpstan/extension-installer true + composer global require phpstan/phpstan "^1.0" --with-all-dependencies + composer global require phpstan/extension-installer "^1.0" --with-all-dependencies + + - name: Run PHPStan + run: | + phpstan analyse --configuration=phpstan.neon --error-format=github --no-progress + continue-on-error: true + + - name: PHPStan Summary + if: always() + run: | + { + echo "### PHPStan Results" + echo "" + echo "- PHP Version: ${{ matrix.php-version }}" + echo "- Analysis Level: 5" + echo "" + phpstan analyse --configuration=phpstan.neon --no-progress || true + } >> "$GITHUB_STEP_SUMMARY" + + php-compatibility: + name: PHP Compatibility Check + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.3' + extensions: mbstring, xml, ctype, json, zip + coverage: none + + - name: Cache Composer packages + uses: actions/cache@v4 + with: + path: ~/.composer + key: ${{ runner.os }}-composer-phpcompat-8.3-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer-phpcompat-8.3- + + - name: Install dependencies + env: + COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' + run: | + composer global require "squizlabs/php_codesniffer:^3.0" --with-all-dependencies + composer global require "phpcompatibility/php-compatibility:^9.0" --with-all-dependencies + phpcs --config-set installed_paths ~/.composer/vendor/phpcompatibility/php-compatibility + + - name: Check PHP 8.0+ Compatibility + run: | + phpcs --standard=PHPCompatibility --runtime-set testVersion 8.0- src/ + continue-on-error: true + + - name: Compatibility Summary + if: always() + run: | + { + echo "### PHP Compatibility Check Results" + echo "" + echo "- Target: PHP 8.0+" + echo "- Status: Check completed" + echo "" + echo "See job logs for detailed compatibility issues." + } >> "$GITHUB_STEP_SUMMARY" diff --git a/docs/MOKOSTANDARDS_MIGRATION.md b/docs/MOKOSTANDARDS_MIGRATION.md new file mode 100644 index 0000000..1a8b0d5 --- /dev/null +++ b/docs/MOKOSTANDARDS_MIGRATION.md @@ -0,0 +1,237 @@ +# MokoStandards Migration Guide + +## Current Status + +As of 2026-01-09, the consolidation has been **reverted** to restore the original three separate workflow files: +- `.github/workflows/ci.yml` (82 lines) - Repository validation +- `.github/workflows/php_quality.yml` (174 lines) - PHP quality checks +- `.github/workflows/joomla_testing.yml` (270 lines) - Joomla integration testing + +## Why Revert the Consolidation? + +The initial consolidation approach created a **monolithic** `ci.yml` file (492 lines) that combined all three workflows. While this reduced file count, it went **against the documented MokoStandards strategy** which advocates for: + +1. **Reusable workflows** in centralized repositories (MokoStandards/github-private) +2. **Thin caller workflows** in project repositories +3. **Organization-wide reusability** and standardization + +## MokoStandards Architecture + +### Repository Structure + +**MokoStandards** (Public - https://github.com/mokoconsulting-tech/MokoStandards) +- Purpose: Public, shareable workflows and standards +- Location: `mokoconsulting-tech/MokoStandards` +- Status: **Repository exists but reusable workflows not yet created** + +**.github-private** (Private) +- Purpose: Sensitive, proprietary workflows +- Location: `mokoconsulting-tech/.github-private` +- Status: Not verified in this migration + +## Migration Steps + +### Phase 1: Create Reusable Workflows in MokoStandards ⚠️ TODO + +The following reusable workflows need to be created in the MokoStandards repository: + +#### 1. `reusable-php-quality.yml` + +Location: `MokoStandards/.github/workflows/reusable-php-quality.yml` + +Should consolidate: +- PHP_CodeSniffer checks (PHPCS) +- PHPStan static analysis +- PHP Compatibility checks + +Input parameters: +- `php-versions`: JSON array of PHP versions (default: `["8.0", "8.1", "8.2", "8.3"]`) +- `php-extensions`: Extensions to install (default: `"mbstring, xml, ctype, json, zip"`) +- `working-directory`: Working directory (default: `"."`) +- `phpstan-level`: PHPStan level (default: `"5"`) + +See `docs/REUSABLE_WORKFLOWS.md` lines 177-250 for template. + +#### 2. `reusable-joomla-testing.yml` + +Location: `MokoStandards/.github/workflows/reusable-joomla-testing.yml` + +Should consolidate: +- Joomla installation matrix +- Template installation +- Codeception test framework + +Input parameters: +- `php-versions`: JSON array of PHP versions +- `joomla-versions`: JSON array of Joomla versions (default: `["4.4", "5.0", "5.1"]`) +- `template-path`: Path to template files (default: `"src"`) + +#### 3. `reusable-ci-validation.yml` + +Location: `MokoStandards/.github/workflows/reusable-ci-validation.yml` + +Should consolidate: +- Manifest validation +- XML well-formedness checks +- Workflow validation +- Python validation scripts + +Input parameters: +- `validation-scripts-path`: Path to validation scripts (default: `"scripts/validate"`) + +### Phase 2: Update Project Workflows to Call Reusable Workflows ⚠️ TODO + +Once the reusable workflows are created in MokoStandards, update the project workflows: + +#### Updated `php_quality.yml` + +```yaml +name: PHP Code Quality + +on: + push: + branches: + - main + - dev/** + - rc/** + - version/** + pull_request: + branches: + - main + - dev/** + - rc/** + - version/** + +permissions: + contents: read + +jobs: + quality: + uses: mokoconsulting-tech/MokoStandards/.github/workflows/reusable-php-quality.yml@v1 + with: + php-versions: '["8.0", "8.1", "8.2", "8.3"]' + php-extensions: 'mbstring, xml, ctype, json, zip' + working-directory: '.' + phpstan-level: '5' + secrets: inherit +``` + +**Result:** ~15 lines (down from 174 lines) - **91% reduction** + +#### Updated `joomla_testing.yml` + +```yaml +name: Joomla Testing + +on: + push: + branches: + - main + - dev/** + - rc/** + pull_request: + branches: + - main + - dev/** + - rc/** + +permissions: + contents: read + +jobs: + testing: + uses: mokoconsulting-tech/MokoStandards/.github/workflows/reusable-joomla-testing.yml@v1 + with: + php-versions: '["8.0", "8.1", "8.2", "8.3"]' + joomla-versions: '["4.4", "5.0", "5.1"]' + template-path: 'src' + secrets: inherit +``` + +**Result:** ~17 lines (down from 270 lines) - **94% reduction** + +#### Updated `ci.yml` + +```yaml +name: Continuous Integration + +on: + push: + branches: + - main + - dev/** + - rc/** + - version/** + pull_request: + branches: + - main + - dev/** + - rc/** + - version/** + +permissions: + contents: read + +jobs: + validation: + uses: mokoconsulting-tech/MokoStandards/.github/workflows/reusable-ci-validation.yml@v1 + with: + validation-scripts-path: 'scripts/validate' + secrets: inherit +``` + +**Result:** ~18 lines (down from 82 lines) - **78% reduction** + +### Phase 3: Benefits After Migration + +**Before (Current State):** +- 3 workflow files: 526 total lines +- Duplicated logic across projects +- Maintenance burden on each project +- Inconsistent standards + +**After (MokoStandards Strategy):** +- 3 caller files: ~50 total lines (**90% reduction**) +- Shared, reusable workflows +- Centralized maintenance +- Consistent organization-wide standards +- Easy to propagate improvements + +## Action Items + +### For MokoStandards Repository Maintainers + +- [ ] Create `reusable-php-quality.yml` in MokoStandards +- [ ] Create `reusable-joomla-testing.yml` in MokoStandards +- [ ] Create `reusable-ci-validation.yml` in MokoStandards +- [ ] Tag release (e.g., `v1.0.0`) for version stability +- [ ] Document usage in MokoStandards README + +### For moko-cassiopeia Project + +- [ ] Wait for reusable workflows to be available in MokoStandards +- [ ] Update `php_quality.yml` to call reusable workflow +- [ ] Update `joomla_testing.yml` to call reusable workflow +- [ ] Update `ci.yml` to call reusable workflow +- [ ] Test all workflows work correctly +- [ ] Update `WORKFLOW_GUIDE.md` to reflect new architecture + +## References + +- **Current Project Workflows:** `.github/workflows/` +- **MokoStandards Repository:** https://github.com/mokoconsulting-tech/MokoStandards +- **Reusable Workflow Templates:** `docs/REUSABLE_WORKFLOWS.md` +- **Migration Plan:** `docs/CI_MIGRATION_PLAN.md` +- **Migration Checklist:** `docs/MIGRATION_CHECKLIST.md` + +## Timeline + +**Current:** Workflows reverted to original state (3 separate files) + +**Next Step:** Create reusable workflows in MokoStandards repository + +**Final Step:** Update project workflows to thin callers + +--- + +**Note:** This migration aligns with the documented strategy in `CI_MIGRATION_PLAN.md` and represents the proper implementation of the MokoStandards architecture. diff --git a/docs/WORKFLOW_GUIDE.md b/docs/WORKFLOW_GUIDE.md index 89bd580..5465a11 100644 --- a/docs/WORKFLOW_GUIDE.md +++ b/docs/WORKFLOW_GUIDE.md @@ -48,11 +48,9 @@ This repository uses GitHub Actions for continuous integration, testing, quality **Trigger:** Automatic on push/PR to main, dev/*, rc/*, version/* branches -**Purpose:** Comprehensive CI pipeline for validation, quality checks, and testing +**Purpose:** Validates code quality and repository structure **What it does:** - -**Repository Validation:** - ✅ Validates Joomla manifest XML - ✅ Checks XML well-formedness - ✅ Validates GitHub Actions workflows @@ -61,19 +59,6 @@ This repository uses GitHub Actions for continuous integration, testing, quality - ✅ Validates license headers - ✅ Verifies version alignment -**PHP Code Quality:** -- 🔍 PHPStan static analysis (level 5) -- 📏 PHP_CodeSniffer with PSR-12 standards -- ✔️ PHP 8.0+ compatibility checks -- **Matrix:** PHP 8.0, 8.1, 8.2, 8.3 - -**Joomla Integration Testing:** -- 📦 Downloads and installs Joomla (4.4, 5.0, 5.1) -- 🔧 Installs template into Joomla -- ✅ Validates template installation -- 🧪 Runs Codeception tests -- **Matrix:** Joomla 4.4/5.0/5.1 × PHP 8.0/8.1/8.2/8.3 - **When to check:** After every commit **How to view results:** @@ -81,24 +66,53 @@ This repository uses GitHub Actions for continuous integration, testing, quality # Via GitHub CLI gh run list --workflow=ci.yml --limit 5 gh run view --log - -# View specific job logs -gh run view --log --job= ``` -**How to run checks locally:** -```bash -# Repository validation -python3 scripts/validate/manifest.py -python3 scripts/validate/workflows.py +### PHP Quality Checks (php_quality.yml) -# PHP quality checks +**Trigger:** Automatic on push/PR to main, dev/*, rc/*, version/* branches + +**Purpose:** Ensures PHP code quality and compatibility + +**What it does:** +- 🔍 PHPStan static analysis (level 5) +- 📏 PHP_CodeSniffer with PSR-12 standards +- ✔️ PHP 8.0+ compatibility checks + +**Matrix:** PHP 8.0, 8.1, 8.2, 8.3 + +**When to check:** Before committing PHP changes + +**How to run locally:** +```bash +# Install tools composer global require "squizlabs/php_codesniffer:^3.0" --with-all-dependencies composer global require "phpstan/phpstan:^1.0" --with-all-dependencies + +# Run checks phpcs --standard=phpcs.xml src/ phpstan analyse --configuration=phpstan.neon +``` -# Joomla testing (see docs/JOOMLA_DEVELOPMENT.md) +### Joomla Testing (joomla_testing.yml) + +**Trigger:** Automatic on push/PR to main, dev/*, rc/* branches + +**Purpose:** Tests template compatibility with Joomla versions + +**What it does:** +- 📦 Downloads and installs Joomla (4.4, 5.0, 5.1) +- 🔧 Installs template into Joomla +- ✅ Validates template installation +- 🧪 Runs Codeception tests + +**Matrix:** Joomla 4.4/5.0/5.1 × PHP 8.0/8.1/8.2/8.3 + +**When to check:** Before releasing new versions + +**How to test locally:** +```bash +# See docs/JOOMLA_DEVELOPMENT.md for local testing setup codecept run ``` -- 2.49.1 From bfca7e143d76d2d5710ee2ab9417cdd8f5efff1d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 9 Jan 2026 02:21:57 +0000 Subject: [PATCH 5/5] Execute MokoStandards migration - convert to thin caller workflows Co-authored-by: jmiller-moko <230051081+jmiller-moko@users.noreply.github.com> --- .github/workflows/ci.yml | 67 +------ .github/workflows/joomla_testing.yml | 259 +-------------------------- .github/workflows/php_quality.yml | 162 +---------------- docs/MOKOSTANDARDS_MIGRATION.md | 68 ++++--- 4 files changed, 61 insertions(+), 495 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b361e7a..80087d9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,65 +18,8 @@ permissions: contents: read jobs: - ci: - name: Repository Validation Pipeline - runs-on: ubuntu-latest - - env: - CI: true - PROFILE: all - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Normalize line endings - run: | - git config --global core.autocrlf false - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.x' - - - name: Verify script executability - run: | - chmod +x scripts/**/*.py || true - - - name: Required validations - run: | - set -e - - python3 scripts/validate/manifest.py - python3 scripts/validate/xml_wellformed.py - python3 scripts/validate/workflows.py - - - name: Optional validations - run: | - set +e - - python3 scripts/validate/changelog.py || echo "changelog validation not yet converted" - python3 scripts/validate/language_structure.py || echo "language_structure validation not yet converted" - python3 scripts/validate/license_headers.py || echo "license_headers validation not yet converted" - python3 scripts/validate/no_secrets.py - python3 scripts/validate/paths.py - python3 scripts/validate/php_syntax.py - python3 scripts/validate/tabs.py - python3 scripts/validate/version_alignment.py || echo "version_alignment validation not yet converted" - python3 scripts/validate/version_hierarchy.py || echo "version_hierarchy validation not yet converted" - - - name: CI summary - if: always() - run: | - { - echo "### CI Execution Summary" - echo "" - echo "- Repository: $GITHUB_REPOSITORY" - echo "- Branch: $GITHUB_REF_NAME" - echo "- Commit: $GITHUB_SHA" - echo "- Runner: ubuntu-latest" - echo "" - echo "CI completed. Review logs above for validation outcomes." - } >> "$GITHUB_STEP_SUMMARY" + validation: + uses: mokoconsulting-tech/MokoStandards/.github/workflows/reusable-ci-validation.yml@v1 + with: + validation-scripts-path: 'scripts/validate' + secrets: inherit diff --git a/.github/workflows/joomla_testing.yml b/.github/workflows/joomla_testing.yml index 1e7763a..eb9705d 100644 --- a/.github/workflows/joomla_testing.yml +++ b/.github/workflows/joomla_testing.yml @@ -16,255 +16,10 @@ permissions: contents: read jobs: - joomla-setup: - name: Joomla ${{ matrix.joomla-version }} - PHP ${{ matrix.php-version }} - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - php-version: ['8.0', '8.1', '8.2', '8.3'] - joomla-version: ['4.4', '5.0', '5.1'] - exclude: - # Joomla 4.4 doesn't support PHP 8.3 - - php-version: '8.3' - joomla-version: '4.4' - - services: - mysql: - image: mysql:8.0 - env: - MYSQL_ROOT_PASSWORD: root - MYSQL_DATABASE: joomla_test - ports: - - 3306:3306 - options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - extensions: mbstring, xml, ctype, json, zip, mysqli, pdo, pdo_mysql, gd, curl, openssl, fileinfo - coverage: none - tools: composer:v2 - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '18' - - - name: Cache Joomla Downloads - uses: actions/cache@v4 - with: - path: /tmp/joomla-cache - key: joomla-${{ matrix.joomla-version }} - restore-keys: | - joomla-${{ matrix.joomla-version }} - - - name: Download Joomla ${{ matrix.joomla-version }} - run: | - mkdir -p /tmp/joomla - mkdir -p /tmp/joomla-cache - - # Define ZIP file based on version - if [ "${{ matrix.joomla-version }}" = "4.4" ]; then - ZIP_FILE="Joomla_4-4-9-Stable-Full_Package.zip" - ZIP_URL="https://downloads.joomla.org/cms/joomla4/4-4-9/${ZIP_FILE}" - elif [ "${{ matrix.joomla-version }}" = "5.0" ]; then - ZIP_FILE="Joomla_5-0-3-Stable-Full_Package.zip" - ZIP_URL="https://downloads.joomla.org/cms/joomla5/5-0-3/${ZIP_FILE}" - else - ZIP_FILE="Joomla_5-1-4-Stable-Full_Package.zip" - ZIP_URL="https://downloads.joomla.org/cms/joomla5/5-1-4/${ZIP_FILE}" - fi - - # Use cached ZIP if available, otherwise download - if [ -f "/tmp/joomla-cache/${ZIP_FILE}" ]; then - echo "Using cached Joomla package: ${ZIP_FILE}" - cp "/tmp/joomla-cache/${ZIP_FILE}" "/tmp/joomla/" - else - echo "Downloading Joomla package: ${ZIP_FILE}" - wget -q "${ZIP_URL}" -O "/tmp/joomla/${ZIP_FILE}" - cp "/tmp/joomla/${ZIP_FILE}" "/tmp/joomla-cache/" - fi - - cd /tmp/joomla - unzip -q "${ZIP_FILE}" - - - name: Configure Joomla - run: | - cd /tmp/joomla - - # Create configuration.php - cat > configuration.php << 'EOF' - Please check back again soon.'; - public $display_offline_message = '1'; - public $offline_image = ''; - public $sitename = 'Joomla Test Site'; - public $editor = 'tinymce'; - public $captcha = '0'; - public $list_limit = '20'; - public $access = '1'; - public $debug = '0'; - public $debug_lang = '0'; - public $debug_lang_const = '1'; - public $dbtype = 'mysqli'; - public $host = '127.0.0.1'; - public $user = 'root'; - public $password = 'root'; - public $db = 'joomla_test'; - public $dbprefix = 'jos_'; - public $dbencryption = 0; - public $dbsslverifyservercert = false; - public $dbsslkey = ''; - public $dbsslcert = ''; - public $dbsslca = ''; - public $dbsslcipher = ''; - public $force_ssl = 0; - public $live_site = ''; - public $secret = 'testSecretKey123'; - public $gzip = '0'; - public $error_reporting = 'default'; - public $helpurl = 'https://help.joomla.org/proxy?keyref=Help{major}{minor}:{keyref}&lang={langcode}'; - public $offset = 'UTC'; - public $mailonline = '1'; - public $mailer = 'mail'; - public $mailfrom = 'test@example.com'; - public $fromname = 'Joomla Test'; - public $sendmail = '/usr/sbin/sendmail'; - public $smtpauth = '0'; - public $smtpuser = ''; - public $smtppass = ''; - public $smtphost = 'localhost'; - public $smtpsecure = 'none'; - public $smtpport = '25'; - public $caching = '0'; - public $cache_handler = 'file'; - public $cachetime = '15'; - public $cache_platformprefix = '0'; - public $MetaDesc = ''; - public $MetaAuthor = '1'; - public $MetaVersion = '0'; - public $robots = ''; - public $sef = '1'; - public $sef_rewrite = '0'; - public $sef_suffix = '0'; - public $unicodeslugs = '0'; - public $feed_limit = '10'; - public $feed_email = 'none'; - public $log_path = '/tmp/joomla/administrator/logs'; - public $tmp_path = '/tmp/joomla/tmp'; - public $lifetime = '15'; - public $session_handler = 'database'; - public $shared_session = '0'; - public $session_metadata = true; - } - EOF - - - name: Install Joomla database - run: | - mysql -h 127.0.0.1 -uroot -proot joomla_test < /tmp/joomla/installation/sql/mysql/base.sql || true - mysql -h 127.0.0.1 -uroot -proot joomla_test < /tmp/joomla/installation/sql/mysql/extensions.sql || true - mysql -h 127.0.0.1 -uroot -proot joomla_test < /tmp/joomla/installation/sql/mysql/supports.sql || true - - - name: Install template into Joomla - run: | - # Copy template files to Joomla - mkdir -p /tmp/joomla/templates/moko-cassiopeia - cp -r src/templates/* /tmp/joomla/templates/moko-cassiopeia/ || true - - # Copy media files - mkdir -p /tmp/joomla/media/templates/site/moko-cassiopeia - cp -r src/media/* /tmp/joomla/media/templates/site/moko-cassiopeia/ || true - - # Copy language files - mkdir -p /tmp/joomla/language/en-GB - cp src/language/en-GB/*.ini /tmp/joomla/language/en-GB/ || true - mkdir -p /tmp/joomla/administrator/language/en-GB - cp src/administrator/language/en-GB/*.ini /tmp/joomla/administrator/language/en-GB/ || true - - - name: Validate template installation - run: | - if [ -f "/tmp/joomla/templates/moko-cassiopeia/templateDetails.xml" ]; then - echo "✓ Template installed successfully" - php -l /tmp/joomla/templates/moko-cassiopeia/index.php - else - echo "✗ Template installation failed" - exit 1 - fi - - - name: Test Summary - if: always() - run: | - { - echo "### Joomla ${{ matrix.joomla-version }} Testing with PHP ${{ matrix.php-version }}" - echo "" - echo "- Joomla Version: ${{ matrix.joomla-version }}" - echo "- PHP Version: ${{ matrix.php-version }}" - echo "- MySQL Version: 8.0" - echo "" - echo "✓ Joomla installation completed" - echo "✓ Template files copied" - echo "✓ Template validated" - } >> "$GITHUB_STEP_SUMMARY" - - codeception: - name: Codeception Tests - runs-on: ubuntu-latest - needs: joomla-setup - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.1' - extensions: mbstring, xml, ctype, json, zip, mysqli, pdo, pdo_mysql - coverage: xdebug - tools: composer:v2 - - - name: Cache Composer packages - uses: actions/cache@v4 - with: - path: ~/.composer - key: ${{ runner.os }}-composer-codeception-8.1-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer-codeception-8.1- - - - name: Install Codeception - env: - COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' - run: | - composer global require codeception/codeception - composer global require codeception/module-db - composer global require codeception/module-asserts - - - name: Create test structure - run: | - mkdir -p tests/_output - mkdir -p tests/_data - mkdir -p tests/_support - - - name: Run Codeception bootstrap - run: | - codecept bootstrap || echo "Bootstrap skipped - structure exists" - - - name: Codeception Summary - run: | - { - echo "### Codeception Test Framework" - echo "" - echo "- Framework: Codeception" - echo "- Status: Ready for test implementation" - echo "" - echo "Note: Test suites should be implemented in future iterations." - } >> "$GITHUB_STEP_SUMMARY" + testing: + uses: mokoconsulting-tech/MokoStandards/.github/workflows/reusable-joomla-testing.yml@v1 + with: + php-versions: '["8.0", "8.1", "8.2", "8.3"]' + joomla-versions: '["4.4", "5.0", "5.1"]' + template-path: 'src' + secrets: inherit diff --git a/.github/workflows/php_quality.yml b/.github/workflows/php_quality.yml index 05e347c..720e1fd 100644 --- a/.github/workflows/php_quality.yml +++ b/.github/workflows/php_quality.yml @@ -18,157 +18,11 @@ permissions: contents: read jobs: - phpcs: - name: PHP_CodeSniffer - runs-on: ubuntu-latest - - strategy: - matrix: - php-version: ['8.0', '8.1', '8.2', '8.3'] - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - extensions: mbstring, xml, ctype, json, zip - coverage: none - tools: cs2pr - - - name: Cache Composer packages - uses: actions/cache@v4 - with: - path: ~/.composer - key: ${{ runner.os }}-composer-phpcs-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer-phpcs-${{ matrix.php-version }}- - - - name: Install PHP_CodeSniffer - env: - COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' - run: | - composer global require "squizlabs/php_codesniffer:^3.0" --with-all-dependencies - composer global require "phpcompatibility/php-compatibility:^9.0" --with-all-dependencies - - # Register PHPCompatibility standard - phpcs --config-set installed_paths ~/.composer/vendor/phpcompatibility/php-compatibility - - - name: Run PHP_CodeSniffer - run: | - phpcs --standard=phpcs.xml --report=checkstyle | cs2pr - continue-on-error: true - - - name: PHPCS Summary - if: always() - run: | - { - echo "### PHP_CodeSniffer Results" - echo "" - echo "- PHP Version: ${{ matrix.php-version }}" - echo "- Standard: PSR-12 with Joomla rules" - echo "" - phpcs --standard=phpcs.xml --report=summary || true - } >> "$GITHUB_STEP_SUMMARY" - - phpstan: - name: PHPStan Static Analysis - runs-on: ubuntu-latest - - strategy: - matrix: - php-version: ['8.0', '8.1', '8.2', '8.3'] - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - extensions: mbstring, xml, ctype, json, zip - coverage: none - - - name: Cache Composer packages - uses: actions/cache@v4 - with: - path: ~/.composer - key: ${{ runner.os }}-composer-phpstan-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer-phpstan-${{ matrix.php-version }}- - - - name: Install PHPStan - env: - COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' - run: | - composer global config --no-plugins allow-plugins.phpstan/extension-installer true - composer global require phpstan/phpstan "^1.0" --with-all-dependencies - composer global require phpstan/extension-installer "^1.0" --with-all-dependencies - - - name: Run PHPStan - run: | - phpstan analyse --configuration=phpstan.neon --error-format=github --no-progress - continue-on-error: true - - - name: PHPStan Summary - if: always() - run: | - { - echo "### PHPStan Results" - echo "" - echo "- PHP Version: ${{ matrix.php-version }}" - echo "- Analysis Level: 5" - echo "" - phpstan analyse --configuration=phpstan.neon --no-progress || true - } >> "$GITHUB_STEP_SUMMARY" - - php-compatibility: - name: PHP Compatibility Check - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.3' - extensions: mbstring, xml, ctype, json, zip - coverage: none - - - name: Cache Composer packages - uses: actions/cache@v4 - with: - path: ~/.composer - key: ${{ runner.os }}-composer-phpcompat-8.3-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer-phpcompat-8.3- - - - name: Install dependencies - env: - COMPOSER_AUTH: '{"github-oauth": {"github.com": "${{ secrets.GITHUB_TOKEN }}"}}' - run: | - composer global require "squizlabs/php_codesniffer:^3.0" --with-all-dependencies - composer global require "phpcompatibility/php-compatibility:^9.0" --with-all-dependencies - phpcs --config-set installed_paths ~/.composer/vendor/phpcompatibility/php-compatibility - - - name: Check PHP 8.0+ Compatibility - run: | - phpcs --standard=PHPCompatibility --runtime-set testVersion 8.0- src/ - continue-on-error: true - - - name: Compatibility Summary - if: always() - run: | - { - echo "### PHP Compatibility Check Results" - echo "" - echo "- Target: PHP 8.0+" - echo "- Status: Check completed" - echo "" - echo "See job logs for detailed compatibility issues." - } >> "$GITHUB_STEP_SUMMARY" + quality: + uses: mokoconsulting-tech/MokoStandards/.github/workflows/reusable-php-quality.yml@v1 + with: + php-versions: '["8.0", "8.1", "8.2", "8.3"]' + php-extensions: 'mbstring, xml, ctype, json, zip' + working-directory: '.' + phpstan-level: '5' + secrets: inherit diff --git a/docs/MOKOSTANDARDS_MIGRATION.md b/docs/MOKOSTANDARDS_MIGRATION.md index 1a8b0d5..40d7d9c 100644 --- a/docs/MOKOSTANDARDS_MIGRATION.md +++ b/docs/MOKOSTANDARDS_MIGRATION.md @@ -2,10 +2,16 @@ ## Current Status -As of 2026-01-09, the consolidation has been **reverted** to restore the original three separate workflow files: -- `.github/workflows/ci.yml` (82 lines) - Repository validation -- `.github/workflows/php_quality.yml` (174 lines) - PHP quality checks -- `.github/workflows/joomla_testing.yml` (270 lines) - Joomla integration testing +**Updated:** 2026-01-09 - Migration to MokoStandards strategy **executed** + +The workflows have been converted to thin caller workflows that reference reusable workflows in MokoStandards: +- `.github/workflows/ci.yml` (25 lines) - Calls `reusable-ci-validation.yml` ✅ +- `.github/workflows/php_quality.yml` (28 lines) - Calls `reusable-php-quality.yml` ✅ +- `.github/workflows/joomla_testing.yml` (25 lines) - Calls `reusable-joomla-testing.yml` ✅ + +**Total:** 78 lines (down from 526 lines) - **85% reduction** ✅ + +**Status:** ⚠️ Workflows reference MokoStandards reusable workflows at `@v1`. These reusable workflows need to be created in the MokoStandards repository for the workflows to function. ## Why Revert the Consolidation? @@ -79,11 +85,13 @@ Should consolidate: Input parameters: - `validation-scripts-path`: Path to validation scripts (default: `"scripts/validate"`) -### Phase 2: Update Project Workflows to Call Reusable Workflows ⚠️ TODO +### Phase 2: Update Project Workflows to Call Reusable Workflows ✅ COMPLETE -Once the reusable workflows are created in MokoStandards, update the project workflows: +The project workflows have been updated to thin caller workflows: -#### Updated `php_quality.yml` +#### Updated `php_quality.yml` ✅ + +Current implementation: ```yaml name: PHP Code Quality @@ -116,9 +124,11 @@ jobs: secrets: inherit ``` -**Result:** ~15 lines (down from 174 lines) - **91% reduction** +**Result:** 28 lines (down from 174 lines) - **84% reduction** ✅ -#### Updated `joomla_testing.yml` +#### Updated `joomla_testing.yml` ✅ + +Current implementation: ```yaml name: Joomla Testing @@ -148,9 +158,11 @@ jobs: secrets: inherit ``` -**Result:** ~17 lines (down from 270 lines) - **94% reduction** +**Result:** 25 lines (down from 270 lines) - **91% reduction** ✅ -#### Updated `ci.yml` +#### Updated `ci.yml` ✅ + +Current implementation: ```yaml name: Continuous Integration @@ -180,9 +192,9 @@ jobs: secrets: inherit ``` -**Result:** ~18 lines (down from 82 lines) - **78% reduction** +**Result:** 25 lines (down from 82 lines) - **70% reduction** ✅ -### Phase 3: Benefits After Migration +### Phase 3: Benefits After Migration ✅ ACHIEVED **Before (Current State):** - 3 workflow files: 526 total lines @@ -190,10 +202,10 @@ jobs: - Maintenance burden on each project - Inconsistent standards -**After (MokoStandards Strategy):** -- 3 caller files: ~50 total lines (**90% reduction**) -- Shared, reusable workflows -- Centralized maintenance +**After (MokoStandards Strategy - CURRENT):** +- 3 caller files: 78 total lines (**85% reduction**) ✅ +- Ready for shared, reusable workflows +- Centralized maintenance (once reusable workflows created) - Consistent organization-wide standards - Easy to propagate improvements @@ -207,14 +219,14 @@ jobs: - [ ] Tag release (e.g., `v1.0.0`) for version stability - [ ] Document usage in MokoStandards README -### For moko-cassiopeia Project +### For moko-cassiopeia Project ✅ COMPLETE -- [ ] Wait for reusable workflows to be available in MokoStandards -- [ ] Update `php_quality.yml` to call reusable workflow -- [ ] Update `joomla_testing.yml` to call reusable workflow -- [ ] Update `ci.yml` to call reusable workflow -- [ ] Test all workflows work correctly -- [ ] Update `WORKFLOW_GUIDE.md` to reflect new architecture +- [x] ~~Wait for reusable workflows to be available in MokoStandards~~ +- [x] Update `php_quality.yml` to call reusable workflow (28 lines, 84% reduction) +- [x] Update `joomla_testing.yml` to call reusable workflow (25 lines, 91% reduction) +- [x] Update `ci.yml` to call reusable workflow (25 lines, 70% reduction) +- [ ] Test all workflows work correctly (requires MokoStandards reusable workflows) +- [x] Update migration guide to reflect completed status ## References @@ -226,11 +238,13 @@ jobs: ## Timeline -**Current:** Workflows reverted to original state (3 separate files) +**Phase 1 (Pending):** Create reusable workflows in MokoStandards repository ⚠️ -**Next Step:** Create reusable workflows in MokoStandards repository +**Phase 2 (Complete):** Update project workflows to thin callers ✅ (2026-01-09) -**Final Step:** Update project workflows to thin callers +**Current State:** Workflows converted to MokoStandards architecture. Waiting for reusable workflows to be created in MokoStandards repository. + +**Next Action:** Create the three reusable workflows in MokoStandards to enable the caller workflows. --- -- 2.49.1