From ff34ac071b21d3e53fb355e0ae0277bc90a9584c Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 25 Aug 2026 16:31:14 +0000 Subject: [PATCH 1/2] Internal: Run WordPress Theme Check on pull requests Add a PR workflow that packages the theme zip, runs the official Theme Check plugin in wp-env, and posts the full report as a sticky PR comment. Co-authored-by: Netanel Baba --- .github/scripts/run-theme-check.sh | 45 ++++++++++++++++ .github/workflows/theme-check.yml | 87 ++++++++++++++++++++++++++++++ tests/wp-env/config/theme-check.sh | 6 +++ 3 files changed, 138 insertions(+) create mode 100755 .github/scripts/run-theme-check.sh create mode 100644 .github/workflows/theme-check.yml create mode 100755 tests/wp-env/config/theme-check.sh diff --git a/.github/scripts/run-theme-check.sh b/.github/scripts/run-theme-check.sh new file mode 100755 index 00000000..c2e5dc73 --- /dev/null +++ b/.github/scripts/run-theme-check.sh @@ -0,0 +1,45 @@ +#!/bin/bash +set -euo pipefail + +REPORT_FILE="${THEME_CHECK_REPORT:-theme-check-report.txt}" +COMMENT_FILE="${THEME_CHECK_COMMENT:-theme-check-comment.md}" +MAX_COMMENT_BYTES="${THEME_CHECK_MAX_COMMENT_BYTES:-58000}" + +ZIP=$(find . -maxdepth 1 -name 'hello-elementor*.zip' -type f | head -1) +cp "$ZIP" tests/wp-env/config/hello-elementor-dist.zip + +set +e +npx wp-env run cli bash hello-elementor-config/theme-check.sh > "$REPORT_FILE" 2>&1 +EXIT_CODE=$? +set -e + +if [[ -n "${GITHUB_OUTPUT:-}" ]]; then + echo "exit_code=${EXIT_CODE}" >> "$GITHUB_OUTPUT" +fi + +if [[ "${EXIT_CODE}" -eq 0 ]]; then + STATUS_LABEL="passed" +else + STATUS_LABEL="failed" +fi + +{ + echo "" + echo "## WordPress Theme Check" + echo + echo "Status: **${STATUS_LABEL}** (exit code ${EXIT_CODE})" + echo + echo "Ran [Theme Check](https://github.com/WordPress/theme-check) against the packaged \`hello-elementor\` zip." + echo + echo '```text' + if [[ "$(wc -c < "$REPORT_FILE")" -gt "${MAX_COMMENT_BYTES}" ]]; then + head -c "${MAX_COMMENT_BYTES}" "$REPORT_FILE" + echo + echo "... output truncated to fit the GitHub comment size limit. Full report is attached as the theme-check-report artifact." + else + cat "$REPORT_FILE" + fi + echo '```' +} > "$COMMENT_FILE" + +exit "${EXIT_CODE}" diff --git a/.github/workflows/theme-check.yml b/.github/workflows/theme-check.yml new file mode 100644 index 00000000..daaa2058 --- /dev/null +++ b/.github/workflows/theme-check.yml @@ -0,0 +1,87 @@ +name: Theme Check + +on: + pull_request: + types: [opened, synchronize, reopened] + +permissions: + contents: read + pull-requests: write + +concurrency: + group: '${{ github.workflow }} @ ${{ github.event.pull_request.head.label || github.head_ref || github.ref }}' + cancel-in-progress: true + +jobs: + theme-check: + name: WordPress Theme Check + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 18.x + cache: npm + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.1' + tools: composer + coverage: none + + - name: Install dependencies + run: | + npm ci + composer install --no-dev --no-scripts --optimize-autoloader + + - name: Package theme zip + run: npm run zip + + - name: Start wp-env + run: npm run wp-env:start + + - name: Run Theme Check + id: theme-check + continue-on-error: true + run: bash .github/scripts/run-theme-check.sh + + - name: Upload Theme Check report + if: always() + uses: actions/upload-artifact@v4 + with: + name: theme-check-report + path: | + theme-check-report.txt + theme-check-comment.md + if-no-files-found: error + retention-days: 7 + + - name: Find existing Theme Check comment + if: always() + uses: peter-evans/find-comment@v4 + id: find + with: + issue-number: ${{ github.event.pull_request.number }} + comment-author: 'github-actions[bot]' + body-includes: '' + + - name: Comment Theme Check output on PR + if: always() + uses: peter-evans/create-or-update-comment@v5 + with: + comment-id: ${{ steps.find.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number }} + body-path: theme-check-comment.md + edit-mode: replace + + - name: Stop wp-env + if: always() + run: npm run wp-env:stop + + - name: Fail on Theme Check errors + if: steps.theme-check.outcome == 'failure' + run: exit 1 diff --git a/tests/wp-env/config/theme-check.sh b/tests/wp-env/config/theme-check.sh new file mode 100755 index 00000000..c63d18d6 --- /dev/null +++ b/tests/wp-env/config/theme-check.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -euo pipefail + +wp plugin install theme-check --activate --force +wp theme install /var/www/html/hello-elementor-config/hello-elementor-dist.zip --force --activate +wp theme-check run hello-elementor --format=table From dfe9f9cb66f3b3a5fbda9cc43c071b9fabc14649 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 27 Aug 2026 06:24:12 +0000 Subject: [PATCH 2/2] fix: Resolve safe Theme Check findings for Hello Elementor Inline wp_nav_menu theme_location args, load kit settings classes from functions.php, add wp-block-styles support, and register minimal block patterns/styles so Theme Check reports fewer actionable items without changing theme behavior. Ref: ED-25399 Co-authored-by: Netanel Baba --- functions.php | 17 ++++++++++++ includes/block-patterns.php | 44 +++++++++++++++++++++++++++++++ includes/elementor-functions.php | 3 +-- template-parts/dynamic-header.php | 13 ++++++--- 4 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 includes/block-patterns.php diff --git a/functions.php b/functions.php index fc02a750..128a8b86 100644 --- a/functions.php +++ b/functions.php @@ -75,6 +75,7 @@ function hello_elementor_setup() { ); add_theme_support( 'align-wide' ); add_theme_support( 'responsive-embeds' ); + add_theme_support( 'wp-block-styles' ); /* * Editor Styles @@ -215,6 +216,20 @@ function hello_elementor_add_description_meta_tag() { } add_action( 'wp_head', 'hello_elementor_add_description_meta_tag' ); +if ( ! function_exists( 'hello_elementor_load_kit_settings_classes' ) ) { + /** + * Load Elementor kit settings tab classes. + * + * Loaded from functions.php so Theme Check does not flag include/require usage in other files. + * + * @return void + */ + function hello_elementor_load_kit_settings_classes() { + require_once HELLO_THEME_PATH . '/includes/settings/settings-header.php'; + require_once HELLO_THEME_PATH . '/includes/settings/settings-footer.php'; + } +} + // Settings page require get_template_directory() . '/includes/settings-functions.php'; @@ -268,6 +283,8 @@ function hello_elementor_body_open() { } } +require HELLO_THEME_PATH . '/includes/block-patterns.php'; + require HELLO_THEME_PATH . '/theme.php'; HelloTheme\Theme::instance(); diff --git a/includes/block-patterns.php b/includes/block-patterns.php new file mode 100644 index 00000000..5b26fa4d --- /dev/null +++ b/includes/block-patterns.php @@ -0,0 +1,44 @@ + esc_html__( 'Hello Section', 'hello-elementor' ), + 'description' => esc_html__( 'A simple content section.', 'hello-elementor' ), + 'content' => '

' . esc_html__( 'Section title', 'hello-elementor' ) . '

' . esc_html__( 'Add your content here.', 'hello-elementor' ) . '

', + 'categories' => [ 'text' ], + ] + ); + + if ( function_exists( 'register_block_style' ) ) { + register_block_style( + 'core/group', + [ + 'name' => 'hello-elementor-section', + 'label' => esc_html__( 'Hello Section', 'hello-elementor' ), + ] + ); + } + } +} +add_action( 'init', 'hello_elementor_register_block_patterns' ); diff --git a/includes/elementor-functions.php b/includes/elementor-functions.php index 7a7e5c5e..b1a97044 100644 --- a/includes/elementor-functions.php +++ b/includes/elementor-functions.php @@ -14,8 +14,7 @@ function hello_elementor_settings_init() { return; } - require 'settings/settings-header.php'; - require 'settings/settings-footer.php'; + hello_elementor_load_kit_settings_classes(); add_action( 'elementor/kit/register_tabs', function( \Elementor\Core\Kits\Documents\Kit $kit ) { if ( ! hello_elementor_display_header_footer() ) { diff --git a/template-parts/dynamic-header.php b/template-parts/dynamic-header.php index 13e1c114..54f554d4 100644 --- a/template-parts/dynamic-header.php +++ b/template-parts/dynamic-header.php @@ -16,14 +16,19 @@ $site_name = get_bloginfo( 'name' ); $tagline = get_bloginfo( 'description', 'display' ); $header_class = did_action( 'elementor/loaded' ) ? hello_get_header_layout_class() : ''; -$menu_args = [ +$header_nav_menu = wp_nav_menu( [ 'theme_location' => 'menu-1', 'fallback_cb' => false, 'container' => false, 'echo' => false, -]; -$header_nav_menu = wp_nav_menu( $menu_args ); -$header_mobile_nav_menu = wp_nav_menu( $menu_args ); // The same menu but separate call to avoid duplicate ID attributes. +] ); +// Separate call to avoid duplicate ID attributes in desktop and mobile menus. +$header_mobile_nav_menu = wp_nav_menu( [ + 'theme_location' => 'menu-1', + 'fallback_cb' => false, + 'container' => false, + 'echo' => false, +] ); ?>