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/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__( 'Add your content here.', 'hello-elementor' ) . '