Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .githooks/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash

# Commit message hook for enforcing conventional commit format
# This hook validates commit message format

commit_regex='^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\(.+\))?: .{1,50}'

error_msg="Aborting commit. Your commit message is missing either a type of change or the description of changes."

if ! grep -qE "$commit_regex" "$1"; then
echo "$error_msg" >&2
echo "" >&2
echo "Valid format: <type>(<scope>): <subject>" >&2
echo "Example: feat(auth): add login functionality" >&2
echo "" >&2
echo "Valid types: feat, fix, docs, style, refactor, test, chore, perf, ci, build, revert" >&2
echo "" >&2
echo "To bypass this check, use: git commit --no-verify" >&2
exit 1
fi
Comment on lines +1 to +20
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Allow Merge/Revert defaults and breaking-change !; relax subject length to 72.

Current hook blocks default “Merge …” and “Revert …” messages and doesn’t allow Conventional Commits’ breaking-change !. Also 50 chars is tight; 72 is common. Update regex and permit Merge/Revert early-exit.

 #!/bin/bash

 # Commit message hook for enforcing conventional commit format
 # This hook validates commit message format

-commit_regex='^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\(.+\))?: .{1,50}'
+commit_regex='^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\([^)]+\))?(!)?: .{1,72}$'

 error_msg="Aborting commit. Your commit message is missing either a type of change or the description of changes."

+# Allow default merge/revert commits to pass
+if grep -qE '^Merge ' "$1"; then
+  exit 0
+fi
+if grep -qE '^Revert "' "$1"; then
+  exit 0
+fi
+
 if ! grep -qE "$commit_regex" "$1"; then
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
#!/bin/bash
# Commit message hook for enforcing conventional commit format
# This hook validates commit message format
commit_regex='^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\(.+\))?: .{1,50}'
error_msg="Aborting commit. Your commit message is missing either a type of change or the description of changes."
if ! grep -qE "$commit_regex" "$1"; then
echo "$error_msg" >&2
echo "" >&2
echo "Valid format: <type>(<scope>): <subject>" >&2
echo "Example: feat(auth): add login functionality" >&2
echo "" >&2
echo "Valid types: feat, fix, docs, style, refactor, test, chore, perf, ci, build, revert" >&2
echo "" >&2
echo "To bypass this check, use: git commit --no-verify" >&2
exit 1
fi
#!/bin/bash
# Commit message hook for enforcing conventional commit format
# This hook validates commit message format
commit_regex='^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\([^)]+\))?(!)?: .{1,72}$'
error_msg="Aborting commit. Your commit message is missing either a type of change or the description of changes."
# Allow default merge/revert commits to pass
if grep -qE '^Merge ' "$1"; then
exit 0
fi
if grep -qE '^Revert "' "$1"; then
exit 0
fi
if ! grep -qE "$commit_regex" "$1"; then
echo "$error_msg" >&2
echo "" >&2
echo "Valid format: <type>(<scope>): <subject>" >&2
echo "Example: feat(auth): add login functionality" >&2
echo "" >&2
echo "Valid types: feat, fix, docs, style, refactor, test, chore, perf, ci, build, revert" >&2
echo "" >&2
echo "To bypass this check, use: git commit --no-verify" >&2
exit 1
fi
🤖 Prompt for AI Agents
.githooks/commit-msg lines 1-20: the hook currently rejects "Merge ..." and
"Revert ..." defaults, doesn't allow the Conventional Commits breaking-change
"!" after type/scope, and limits the subject to 50 chars; update the script to
(1) early-exit success for commit messages beginning with "Merge " or "Revert "
so default git messages pass, (2) relax the main commit_regex to accept an
optional "!" after the type/scope (e.g. feat!: or feat(scope)!:) and increase
the subject max length to 72 characters, and (3) keep the explanatory error
output intact; implement these changes by adding a pre-check that returns 0 for
^(Merge|Revert)\b and modifying the regex to include the optional ! and .{1,72}
for the subject.

64 changes: 64 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/bin/bash

# Pre-commit hook for running phpcs and phpstan on changed files
# This hook runs PHPCS and PHPStan on staged PHP files

set -e

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

echo -e "${GREEN}Running pre-commit checks...${NC}"

# Get list of staged PHP files
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep '\.php$' | grep -v '^vendor/' | grep -v '^tests/' || true)

if [ -z "$STAGED_FILES" ]; then
echo -e "${GREEN}No PHP files to check.${NC}"
exit 0
fi

echo -e "${YELLOW}Checking PHP files:${NC}"
echo "$STAGED_FILES"

# Check if composer dependencies are installed
if [ ! -f "vendor/bin/phpcs" ] || [ ! -f "vendor/bin/phpstan" ]; then
echo -e "${RED}Error: Please run 'composer install' to install development dependencies.${NC}"
exit 1
fi

# Run PHPCS on staged files
echo -e "${YELLOW}Running PHPCS...${NC}"
HAS_PHPCS_ERRORS=0
for FILE in $STAGED_FILES; do
if [ -f "$FILE" ]; then
vendor/bin/phpcs --colors "$FILE" || HAS_PHPCS_ERRORS=1
fi
done

# Run PHPStan on staged files
echo -e "${YELLOW}Running PHPStan...${NC}"
HAS_PHPSTAN_ERRORS=0
PHPSTAN_FILES=""
for FILE in $STAGED_FILES; do
if [ -f "$FILE" ] && [[ "$FILE" =~ ^inc/ ]]; then
PHPSTAN_FILES="$PHPSTAN_FILES $FILE"
fi
done

if [ -n "$PHPSTAN_FILES" ]; then
vendor/bin/phpstan analyse --no-progress --error-format=table $PHPSTAN_FILES || HAS_PHPSTAN_ERRORS=1
fi

# Exit with error if any checks failed
if [ $HAS_PHPCS_ERRORS -ne 0 ] || [ $HAS_PHPSTAN_ERRORS -ne 0 ]; then
echo -e "${RED}Pre-commit checks failed!${NC}"
echo -e "${YELLOW}To bypass these checks, use: git commit --no-verify${NC}"
exit 1
fi

echo -e "${GREEN}All pre-commit checks passed!${NC}"
exit 0
57 changes: 57 additions & 0 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Code Quality

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
code-quality:
name: Code Quality Checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
extensions: mysqli, gd, bcmath
tools: composer

- name: Install PHP Dependencies
run: composer install --no-interaction --prefer-dist

- name: Get changed PHP files
id: changed-files
uses: tj-actions/changed-files@v44
with:
files: |
**/*.php

- name: Run PHP CodeSniffer
if: steps.changed-files.outputs.any_changed == 'true'
run: |
echo "Changed files: ${{ steps.changed-files.outputs.all_changed_files }}"
vendor/bin/phpcs --report=checkstyle --report-file=phpcs-report.xml ${{ steps.changed-files.outputs.all_changed_files }} || true

- name: Run PHPStan
if: steps.changed-files.outputs.any_changed == 'true'
run: |
echo "Running PHPStan on changed files: ${{ steps.changed-files.outputs.all_changed_files }}"
vendor/bin/phpstan analyse --error-format=checkstyle --no-progress ${{ steps.changed-files.outputs.all_changed_files }} > phpstan-report.xml || true

- name: Annotate PR with PHPCS results
uses: staabm/annotate-pull-request-from-checkstyle-action@v1
if: github.event_name == 'pull_request'
with:
files: phpcs-report.xml
notices-as-failures: false

- name: Annotate PR with PHPStan results
uses: staabm/annotate-pull-request-from-checkstyle-action@v1
if: github.event_name == 'pull_request'
with:
files: phpstan-report.xml
notices-as-failures: false
14 changes: 12 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,15 @@ jobs:
rm -rf /tmp/wordpress-tests-lib /tmp/wordpress/
bash bin/install-wp-tests.sh wordpress_test root root mysql latest

- name: Run PHPUnit Tests
run: vendor/bin/phpunit
- name: Run PHPUnit Tests with Coverage
run: vendor/bin/phpunit --coverage-clover=coverage.xml

Comment on lines +70 to +72
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Coverage will likely fail without a driver (xdebug/pcov/phpdbg).

Running PHPUnit with coverage requires a coverage driver; otherwise you get “No code coverage driver available” and no coverage.xml is produced. Prefer enabling Xdebug via env, or run under phpdbg. (about.codecov.io)

Apply this minimal change (uses Xdebug if present):

-      - name: Run PHPUnit Tests with Coverage
-        run: vendor/bin/phpunit --coverage-clover=coverage.xml
+      - name: Run PHPUnit Tests with Coverage
+        run: XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-clover=coverage.xml

If you’d rather avoid Xdebug, run via phpdbg:

-        run: vendor/bin/phpunit --coverage-clover=coverage.xml
+        run: phpdbg -qrr vendor/bin/phpunit --coverage-clover=coverage.xml

You can confirm driver availability in CI by adding:


🏁 Script executed:

#!/bin/bash
php -v
php -m | grep -Ei 'xdebug|pcov'
command -v phpdbg || echo "phpdbg not found"

Length of output: 217


Enable a code‐coverage driver in CI
CI’s PHP 8.2.29 image has neither Xdebug/PCOV nor phpdbg (verified via php -m and phpdbg not found), so --coverage-clover will error with “No code coverage driver available.” Add one of the following critical changes:

  • Use Xdebug via the official setup action and enable coverage mode:

    -      - name: Run PHPUnit Tests with Coverage
    -        run: vendor/bin/phpunit --coverage-clover=coverage.xml
    +      - name: Setup PHP with Xdebug
    +        uses: shivammathur/setup-php@v2
    +        with:
    +          php-version: '8.2'
    +          coverage: xdebug
    +      - name: Run PHPUnit Tests with Coverage
    +        run: XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-clover=coverage.xml
  • Or install phpdbg in the CI image and invoke PHPUnit under phpdbg:

    -        run: vendor/bin/phpunit --coverage-clover=coverage.xml
    +        run: phpdbg -qrr vendor/bin/phpunit --coverage-clover=coverage.xml
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Run PHPUnit Tests with Coverage
run: vendor/bin/phpunit --coverage-clover=coverage.xml
- name: Setup PHP with Xdebug
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
coverage: xdebug
- name: Run PHPUnit Tests with Coverage
run: XDEBUG_MODE=coverage vendor/bin/phpunit --coverage-clover=coverage.xml
🤖 Prompt for AI Agents
.github/workflows/tests.yml around lines 70 to 72: the CI job runs PHPUnit with
--coverage-clover but the runner image lacks a code-coverage driver, causing “No
code coverage driver available.” Fix by either enabling Xdebug using the
official setup action and exporting XDEBUG_MODE=coverage before running
vendor/bin/phpunit, or install phpdbg into the image and invoke PHPUnit through
phpdbg (phpdbg -qrr vendor/bin/phpunit --coverage-clover=coverage.xml); update
the workflow step accordingly to install/configure the chosen driver and run
PHPUnit under that driver.

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
with:
file: ./coverage.xml
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
Comment on lines +73 to +81
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Codecov input key should be “files”, not “file”; consider OIDC.

The action expects with: files: ./coverage.xml (plural). Using file will be ignored. Also, v4 supports token via env or OIDC; consider use_oidc: true to avoid secrets on PRs from forks. (github.com)

Apply:

       - name: Upload coverage reports to Codecov
         uses: codecov/codecov-action@v4
         with:
-          file: ./coverage.xml
+          files: ./coverage.xml
           flags: unittests
           name: codecov-umbrella
           fail_ci_if_error: false
-        env:
-          CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
+          # Optional: differentiate matrices
+          # flags: unittests,php-${{ matrix.php-version }}
+          # Optional (public repos): prefer OIDC over token
+          # use_oidc: true
+        # If not using OIDC, keep the token env:
+        # env:
+        #   CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

Optionally restrict upload to one PHP to reduce noise:

-      - name: Upload coverage reports to Codecov
+      - name: Upload coverage reports to Codecov
+        if: matrix.php-version == '8.3'

Docs for inputs and OIDC usage: see Codecov Action README. (github.com)


🌐 Web query:

What inputs does the codecov/codecov-action@v4 GitHub Action accept? Does it use “files” instead of “file”?

💡 Result:

Short answer: The v4 action accepts a range of inputs (token, codecov_yml_path, commit_parent, directory, disable_search, disable_file_fixes, dry_run, env_vars, exclude, fail_ci_if_error, files, flags, name, os, verbose, etc.). The README/Action docs show both file and files historically, but the repository warns that the singular input file was deprecated in favor of files (use files). [1][2]

References:

  • codecov/codecov-action README (usage + inputs list). [1]
  • codecov/codecov-action repository top-level note: "file (this has been deprecated in favor of files)". [2]

🌐 Web query:

Does codecov/codecov-action@v4 support OIDC authentication via “use_oidc: true” instead of a CODECOV_TOKEN secret?

💡 Result:

Yes. codecov/codecov-action@v4 supports OIDC — set with with: use_oidc: true and any token will be ignored. [1][2]

Note: for GitHub Actions you must give the action permission to mint an ID token (id-token: write). [2]

Sources: [1] README (v4) codecov/codecov-action, [2] README (v5) codecov/codecov-action (OIDC permissions note).


Replace deprecated file input with files and enable OIDC
.github/workflows/tests.yml (lines 73–81):

  • Change file: ./coverage.xml to files: ./coverage.xml (the singular file input is deprecated and ignored by v4).
  • Optional: drop the CODECOV_TOKEN secret and add use_oidc: true under with: (requires permissions: id-token: write) to authenticate via OIDC instead of a secret.

Apply:

       - name: Upload coverage reports to Codecov
         uses: codecov/codecov-action@v4
         with:
-          file: ./coverage.xml
+          files: ./coverage.xml
           flags: unittests
           name: codecov-umbrella
           fail_ci_if_error: false
-        env:
-          CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
+          # Optional: use OIDC for authentication (requires `permissions: id-token: write`)
+          # use_oidc: true
#        env:
#          CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In .github/workflows/tests.yml around lines 73 to 81, the Codecov action uses
the deprecated singular input `file` and relies on a token secret; change `file:
./coverage.xml` to `files: ./coverage.xml` under the action's with: block, add
`use_oidc: true` to enable OIDC authentication (which requires setting workflow
permissions to `id-token: write` at the top of the workflow), and remove the
CODECOV_TOKEN from the action env block (or drop the entire env block) since
OIDC will be used instead.

6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ vendor
.phpunit.result.cache
tests/e2e/cypress/screenshots
tests/e2e/cypress/videos
tests/e2e/cypress/downloads
tests/e2e/cypress/downloads

# Code coverage
coverage.xml
coverage-html/
20 changes: 10 additions & 10 deletions .phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,7 @@
<exclude name="WordPress.WP.GlobalVariablesOverride.Prohibited" />
<exclude name="Generic.Commenting.DocComment.MissingShort" />
<exclude name="Squiz.Commenting.FileComment.MissingPackageTag" />
</rule>
<rule ref="WordPress.NamingConventions.PrefixAllGlobals">
<properties>
<!-- Value: replace the function, class, and variable prefixes used. Separate multiple prefixes with a comma. -->
<property name="prefixes" type="array">
<element value="wu_"/>
<element value="wp_ultimo"/>
</property>
</properties>
<exclude-pattern>/views/</exclude-pattern>
<exclude name="WordPress.NamingConventions.PrefixAllGlobals" />
</rule>
<rule ref="WordPress.WhiteSpace.ControlStructureSpacing">
<properties>
Expand Down Expand Up @@ -100,6 +91,15 @@
<element key="12" value="wu_transfer_sites"/>
<element key="13" value="wu_read_financial" />
<element key="14" value="wu_manage_invoice" />
<element key="15" value="wu_delete_memberships" />
<element key="16" value="read_tax_rates" />
<element key="17" value="wu_read_dashboard" />
<element key="18" value="wu_read_memberships" />
<element key="19" value="wu_read_customers" />
<element key="20" value="wu_read_products" />
<element key="21" value="wu_read_payments" />
<element key="22" value="wu_read_discount_codes" />
<element key="23" value="wu_read_settings" />
</property>
</properties>
</rule>
Expand Down
Loading
Loading