diff --git a/.distignore b/.distignore index 654ec1e06..6dff08655 100644 --- a/.distignore +++ b/.distignore @@ -9,6 +9,8 @@ Gruntfile.js webpack.config.js tests/ node_modules/ +playwright-report/ +test-results/ none package-lock.json package.json diff --git a/.github/workflows/copilot-review-on-comment.yml b/.github/workflows/copilot-review-on-comment.yml index 742642f96..e1a3accde 100644 --- a/.github/workflows/copilot-review-on-comment.yml +++ b/.github/workflows/copilot-review-on-comment.yml @@ -1,11 +1,13 @@ name: Copilot review on comment on: + pull_request_target: + types: [opened] issue_comment: types: [created] jobs: review: - uses: wpeverest/.github/.github/workflows/copilot-review-on-comment.yml@master + uses: themegrill/.github/.github/workflows/copilot-review-on-comment.yml@master secrets: BOT_TOKEN: ${{ secrets.BOT_TOKEN }} diff --git a/.github/workflows/evf-PR-test.yml b/.github/workflows/evf-PR-test.yml index 5f73fa9bf..4652471a7 100644 --- a/.github/workflows/evf-PR-test.yml +++ b/.github/workflows/evf-PR-test.yml @@ -31,10 +31,16 @@ jobs: git config --global user.email "$MY_EMAIL" git config --global user.name "$MY_USERNAME" - - name: Use Node.js 12.x + # Node 20, not 12: @playwright/test (a devDependency since the E2E suite + # landed) declares `engines.node >= 20`, and package.json now declares the + # same minimum. npm 6 only WARNs on an engine mismatch rather than failing, + # so Node 12 installed fine — but it left CI running a Node the project no + # longer claims to support. 20.x is what .github/workflows/pr-build-zip.yml + # already uses. + - name: Use Node.js 20.x uses: actions/setup-node@v2 with: - node-version: 12.x + node-version: 20.x - name: Setup PHP v7.4 uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/pr-build-zip.yml b/.github/workflows/pr-build-zip.yml new file mode 100644 index 000000000..a37e08c06 --- /dev/null +++ b/.github/workflows/pr-build-zip.yml @@ -0,0 +1,42 @@ +name: Build Testable ZIP + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + branches: [develop] + workflow_dispatch: + +jobs: + zip: + uses: themegrill/.github/.github/workflows/pr-build-zip.yml@master + with: + node-version: '20.x' + php-version: '8.2' + package-manager: npm + # `npm run build` runs this repo's own bin/build-zip.sh, which is a + # fully self-contained release script: it does its own + # `npm install --legacy-peer-deps`, its own `composer install` (with a + # PHP-version fix pending in a separate PR to that script), its own JS + # build, and its own rsync+zip -- producing everest-forms.zip at the + # repo root already. This workflow's own install/composer steps would + # just be redundant, wasted work duplicating what the script already + # does, so they're skipped/no-op'd here rather than fighting it. + # Can't skip this like composer-install: `npm run build` is literally + # `cross-env ./bin/build-zip.sh`, and cross-env has to already be + # resolvable from node_modules/.bin before that command can even + # start -- build-zip.sh's own internal npm install happens too late + # to help with that (confirmed for real: skipping this outright hit + # "cross-env: not found"). --legacy-peer-deps for the same reason as + # documented on the build-zip.sh fix -- @ajna/pagination's peer + # dependency conflict blocks a plain `npm ci` here too. + install-command: npm ci --legacy-peer-deps + composer-install: false + build-command: npm run build + zip-glob: 'everest-forms.zip' + artifacts-bucket: themegrill-pr-artifacts + public-base-url: https://themegrill-pr-artifacts.s3.amazonaws.com + s3-region: us-east-1 + secrets: + BOT_TOKEN: ${{ secrets.BOT_TOKEN }} + ARTIFACTS_KEY: ${{ secrets.ARTIFACTS_KEY }} + ARTIFACTS_SECRET: ${{ secrets.ARTIFACTS_SECRET }} diff --git a/.github/workflows/qa-suite.yml b/.github/workflows/qa-suite.yml new file mode 100644 index 000000000..4efd78cd8 --- /dev/null +++ b/.github/workflows/qa-suite.yml @@ -0,0 +1,39 @@ +# Written by `/claudegrill:setup`. Safe to edit — it is a plain caller. +# +# THIS IS THE ONLY PR CHECK MOST PRODUCTS NEED. No ANTHROPIC_API_KEY, no agent, +# runner minutes only. +# +# It works without AI because the developer already wrote the spec: they ran +# /claudegrill:verify-fix locally, write-spec added a @fresh spec to their +# branch, and they committed it with the fix. By the time CI sees the PR the +# regression is already a deterministic assertion. +# +# ONE job, on pull requests only. Nothing runs on a schedule: the team's model is +# a local /claudegrill:verify-fix while the fix is being written, and the e2e +# suite on the PR. No cron, no nightly, no WordPress-core watcher. +# +# `scope: changed` narrows a run to the areas the diff maps to. That is safe by +# construction — a changed file matching no `area_paths` pattern in +# .themegrill-qa/suite.json falls back to the full tier, so an unmapped change +# costs runner time, never coverage. +# +# Worth knowing, since nothing else runs the suite now: a spec whose area is +# never touched by any PR will not execute. Set `scope: full` below if you would +# rather every PR run the whole @fresh tier. + +name: QA suite + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + workflow_dispatch: + +jobs: + # The only check. Scoped, fast, runs on every PR including drafts. + pr: + uses: ThemeGrill/claudegrill/.github/workflows/suite.yml@main + with: + product_slug: everest-forms + product_type: plugin + scope: changed + diff --git a/.gitignore b/.gitignore index 6c0fc0cfd..00ac87e10 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,10 @@ phpunit-watcher.yml /release/ /.idea/ + +# claudegrill local credentials +.themegrill-qa/.env.local + +# playwright run artefacts +playwright-report/ +test-results/ diff --git a/.themegrill-qa/.docs-cache/_wp-json_wp_v2_doc_category_per_page_100__fields_id_name_slug_count_parent.txt b/.themegrill-qa/.docs-cache/_wp-json_wp_v2_doc_category_per_page_100__fields_id_name_slug_count_parent.txt new file mode 100644 index 000000000..cc9830263 --- /dev/null +++ b/.themegrill-qa/.docs-cache/_wp-json_wp_v2_doc_category_per_page_100__fields_id_name_slug_count_parent.txt @@ -0,0 +1 @@ +[{"id":2,"count":7,"name":"Account Management","slug":"account-management","parent":0},{"id":48,"count":14,"name":"Advanced","slug":"advanced","parent":0},{"id":47,"count":4,"name":"Anti-Spam and Security","slug":"anti-spam-and-security","parent":0},{"id":35,"count":0,"name":"Basic Debugging Steps","slug":"basic-debugging-steps","parent":0},{"id":44,"count":6,"name":"CRMs","slug":"crms","parent":0},{"id":43,"count":2,"name":"Design","slug":"design","parent":0},{"id":26,"count":4,"name":"Developer's Doc","slug":"developers-doc","parent":0},{"id":3,"count":0,"name":"Everest Forms Add-ons","slug":"everest-forms-add-ons","parent":0},{"id":4,"count":10,"name":"Everest Forms Pro","slug":"everest-forms-pro","parent":0},{"id":56,"count":6,"name":"Form Customization and User Experience","slug":"form-customization-and-user-experience","parent":0},{"id":5,"count":19,"name":"Form Fields","slug":"form-fields","parent":0},{"id":17,"count":13,"name":"Frequently Asked Questions","slug":"faq","parent":0},{"id":6,"count":6,"name":"Getting Started with Form","slug":"getting-started-with-form","parent":0},{"id":7,"count":4,"name":"Getting Started with Plugin","slug":"getting-started","parent":0},{"id":8,"count":4,"name":"Global Settings","slug":"global-settings","parent":0},{"id":9,"count":43,"name":"How To?","slug":"tutorials","parent":0},{"id":10,"count":6,"name":"Individual Form Settings","slug":"individual-form-settings","parent":0},{"id":57,"count":5,"name":"Integrations","slug":"integrations","parent":0},{"id":51,"count":17,"name":"Marketing","slug":"marketing","parent":0},{"id":61,"count":7,"name":"New Payment Gateways","slug":"new-payment-gateways","parent":0},{"id":42,"count":5,"name":"Page Builder Compatibility","slug":"page-builder-compatibility","parent":0},{"id":45,"count":6,"name":"Payment Gateways ( Old )","slug":"payment-gateways","parent":0},{"id":59,"count":3,"name":"Tools","slug":"tools","parent":0},{"id":11,"count":2,"name":"Translation","slug":"translation","parent":0},{"id":12,"count":6,"name":"Troubleshooting","slug":"troubleshooting","parent":0}] \ No newline at end of file diff --git a/.themegrill-qa/.docs-cache/_wp-json_wp_v2_docs_per_page_100_page_1__fields_id_slug_link_title_content_doc_category.txt b/.themegrill-qa/.docs-cache/_wp-json_wp_v2_docs_per_page_100_page_1__fields_id_slug_link_title_content_doc_category.txt new file mode 100644 index 000000000..12fb74cd5 --- /dev/null +++ b/.themegrill-qa/.docs-cache/_wp-json_wp_v2_docs_per_page_100_page_1__fields_id_slug_link_title_content_doc_category.txt @@ -0,0 +1 @@ +[{"id":5955,"slug":"style-customizer","link":"https:\/\/docs.everestforms.net\/docs\/style-customizer\/","title":{"rendered":"Style Customizer"},"content":{"rendered":"

The Style Customizer lets you change how your form looks \u2014 colors, fonts, spacing, borders, and button style \u2014 without writing any CSS. It’s built directly into the form builder’s Style<\/strong> tab, with a live preview that updates as you make changes.<\/p>\n

This article covers the current Style Customizer. If you styled a form before this update, don’t worry \u2014 your existing look carries over automatically the first time you open the Style tab. See Migrating an Older Form<\/strong> below.<\/p>\n

Where to Find It<\/h2>\n
    \n
  1. Go to Everest Forms \u2192 All Forms<\/strong> and edit the form you want to style.<\/li>\n
  2. Click the Style<\/strong> tab at the top of the builder.<\/li>\n<\/ol>\n
    \"Everest<\/figure>\n
    \"Everest<\/figure>\n

    The Style Tab Layout<\/h2>\n

    The Style tab is split into two panes:<\/p>\n