Skip to content
Open
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
102 changes: 26 additions & 76 deletions .github/workflows/plugin-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,10 @@ jobs:
continue-on-error: false

# Tier 3: Plugin Check (needs build artifact)
# Manual wp-env approach — upstream plugin-check-action is broken (#579).
# Uses wordpress/plugin-check-action@v1.1.7, which fixes the wp-env
# "Environment not initialized" bug from upstream issue #579
# (closed via PR #590 — drops the URL-plugin bootstrap and installs
# plugin-check via WP-CLI after wp-env start with a post-boot check).

plugin-check:
name: Plugin Check
Expand All @@ -129,81 +132,28 @@ jobs:
name: chip-for-givewp-build
path: ./build

# Node 24+ breaks @wordpress/env ("Environment not initialized").
# Node 22 is the latest version confirmed working.
- name: Setup Node.js
uses: actions/setup-node@v6
# Setup PHP so the action can pick it up for wp-env's CLI container.
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
node-version: '22'

- name: Install @wordpress/env
run: npm install -g @wordpress/env

- name: Create wp-env override for CI
run: |
cat > .wp-env.override.json <<'JSONEOF'
{
"core": null,
"plugins": [
"https://downloads.wordpress.org/plugin/give.zip",
"https://downloads.wordpress.org/plugin/plugin-check.zip"
],
"mappings": {
"wp-content/plugins/chip-for-givewp": "./build/chip-for-givewp"
}
}
JSONEOF
cat .wp-env.override.json

- name: Start WordPress environment
run: |
npx wp-env start --update
# Give containers time to stabilize
sleep 10

- name: Activate Plugin Check
run: |
npx wp-env run cli wp plugin activate plugin-check
php-version: '8.2'

- name: Run Plugin Check
run: |
# Run plugin check and output JSON for parsing.
# Ignore trademarked_term: the plugin name "CHIP for GiveWP" and slug "chip-for-givewp"
# contain "wp" which is already published on WordPress.org and cannot be changed.
# Ignore NonPrefixedHooknameFound: all instances are GiveWP core hooks
# (give_forms_content_options_select, give_before_chip_info_fields, etc.)
# that third-party gateways are expected to use.
# wp-env run cli prepends status text to stdout; filter only JSON lines.
# WP CLI may return exit code 1 even with --ignore-codes; use || true and rely on jq parsing.
npx wp-env run cli wp plugin check chip-for-givewp \
--format=json \
--ignore-codes=trademarked_term,WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound \
2>/dev/null | grep -E '^\[|^\{' > /tmp/plugin-check-results.json || true

# Display results in a readable table format.
npx wp-env run cli wp plugin check chip-for-givewp \
--ignore-codes=trademarked_term,WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound

# Parse JSON to count errors and warnings.
ERRORS=$(jq '[.[] | select(.type == "ERROR")] | length' /tmp/plugin-check-results.json)
WARNINGS=$(jq '[.[] | select(.type == "WARNING")] | length' /tmp/plugin-check-results.json)

echo ""
echo "═══════════════════════════════════════"
echo " Plugin Check Summary"
echo "═══════════════════════════════════════"
echo " Errors: ${ERRORS}"
echo " Warnings: ${WARNINGS}"

if [ "${ERRORS}" -gt 0 ] || [ "${WARNINGS}" -gt 0 ]; then
echo ""
echo "❌ Plugin Check failed with ${ERRORS} error(s) and ${WARNINGS} warning(s)"
exit 1
fi

echo ""
echo "✅ Plugin Check passed (no errors or warnings)"

- name: Stop WordPress environment
if: always()
run: npx wp-env stop
uses: wordpress/plugin-check-action@v1.1.7
with:
build-dir: ./build/chip-for-givewp
# Plugin name "CHIP for GiveWP" and slug "chip-for-givewp"
# contain "wp" which is already published on WordPress.org
# and cannot be changed, so trademarked_term is a known false positive.
# NonPrefixedHooknameFound is unavoidable for a third-party
# GiveWP gateway: we listen to GiveWP's give_* / givewp_* hooks
# (add_action/add_filter), and until v2.0.0 we still fire two
# legacy give_before_chip_info_fields / give_after_chip_info_fields
# hooks kept for backward compatibility. See
# includes/class-chip-givewp-purchase.php and
# chip-for-givewp.php for the prefixed gwp_chip_* replacements
# introduced in 1.4.0.
# newline-separated per the action's input contract.
ignore-codes: |
trademarked_term
WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
8 changes: 8 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ Both gateways share the same backend logic (API calls, listener, settings) but h
- **`includes/js/refund.js`** — AJAX handler for the admin refund button.
- **`.wp-env.json`** — Local WordPress environment config (GiveWP + plugin-check).
- **`.wordpress-org/`** — WordPress.org plugin directory assets (banners, icons, screenshots).
- **`.github/workflows/`** — GitHub Actions CI/CD:
- `plugin-check.yml` — Runs the WordPress.org plugin check (PHP 8.2 + plugin-check-action@v1.1.7), PHPCS, PHPCompatibility, PHPUnit, and the plugin build. All four test jobs (`php-compatibility`, `phpcs`, `phpunit`, `plugin-check`) gate on the `build` job's artifact. The `plugin-check` job passes `ignore-codes: trademarked_term` and `…NonPrefixedHooknameFound` (both are documented false positives for this plugin — see the comments in that file).
- `prepare-release.yml` — Manual dispatch (`workflow_dispatch`, input: `version`). Validates the version, generates an AI changelog from the diff since the last tag (uses `AI_API_KEY` / `AI_MODEL` / `AI_API_URL`), runs `scripts/bump-version.sh`, then opens a `release/vX.Y.Z` PR to `main`. Tag creation is still manual after the PR merges.
- `release-zip.yml` — Fires on `release: created`. Builds a clean `dist/chip-for-givewp/` snapshot and uploads `chip-for-givewp.zip` to the GitHub release as an asset. The WordPress.org deploy workflow is responsible for the trunk/tag push.
- `deploy.yml` — Fires on `v*.*.*` or `*.*.*` tag push, or manual dispatch with `trunk`/`release` stage. Runs in the `wordpress-org` environment using `SVN_USERNAME` / `SVN_PASSWORD` secrets. For `trunk`, reverts `Stable tag` to whatever is currently live on WordPress.org so the testing build doesn't auto-update users; for `release`, commits to trunk, copies trunk → `tags/X.Y.Z`, and creates/updates the matching GitHub release. Excludes `.git*`, `.github`, `.vscode`, `ci-build`, `dist`, `node_modules`, `.wordpress-org` from the deploy.
- `pr-summary.yml` — Fires on PR `opened`/`synchronize`. Generates an AI summary of the PR diff and overwrites the PR description (idempotent — re-runs replace the previous summary).

### Settings Model
CHIP settings exist at two levels:
Expand Down Expand Up @@ -91,6 +97,8 @@ phpcs --standard=PHPCompatibilityWP --runtime-set testVersion 8.5 --extensions=p
- To update version: bump in `chip-for-givewp.php` (header + `GWP_CHIP_MODULE_VERSION`), `readme.txt` (`Stable tag`), and `changelog.txt`. Alternatively, use `./scripts/bump-version.sh X.Y.Z`.
- To update WordPress.org assets: place images in `.wordpress-org/` (banners, icons, screenshots). Deployed to SVN by `deploy.yml`.
- To run local WordPress environment: `wp-env` reads `.wp-env.json` (GiveWP + plugin-check pre-installed).
- To add or change CI `ignore-codes` for the WordPress.org plugin check: edit `.github/workflows/plugin-check.yml` (newline-separated list per the action's `action.yml`). Always include a comment explaining why each code is being ignored — the maintainers may ask.
- To reproduce the CI `plugin-check` job locally: `npx wp-env start && npx wp-env run cli wp plugin activate plugin-check && npx wp-env run cli wp plugin check chip-for-givewp --ignore-codes=trademarked_term,WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound`.

## External Dependencies

Expand Down
16 changes: 16 additions & 0 deletions chip-for-givewp.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ public function add_filters() {
* Adds WordPress actions.
*/
public function add_actions() {
// Preferred (prefixed) hook. Billing fields render on this hook.
add_action( 'gwp_chip_before_info_fields', array( $this, 'billing_fields' ) );

// Legacy hook — kept registered so any pre-1.4.0 listener still
// fires. Our own billing_fields callback detaches itself the
// first time the legacy hook runs (see billing_fields() below),
// so billing_fields is invoked exactly once per request even
// when both hooks fire.
add_action( 'give_before_chip_info_fields', array( $this, 'billing_fields' ) );
}

Expand Down Expand Up @@ -156,6 +164,14 @@ public function filter_gateway( $gateway_list, $form_id ) {
* @param int $form_id Form ID.
*/
public function billing_fields( $form_id ) {
// If this is being invoked via the legacy give_before_chip_info_fields
// hook, detach ourselves from it now that the new prefixed hook
// is wired up. We remove only our own callback so any other
// listeners on the legacy hook still run.
if ( doing_action( 'give_before_chip_info_fields' ) ) {
remove_action( 'give_before_chip_info_fields', array( $this, 'billing_fields' ) );
}

$chip_customization = give_get_meta( $form_id, '_give_customize_chip_donations', true, 'global' );
$billing_fields = give_get_meta( $form_id, '_give_chip-enable-billing-fields', true );

Expand Down
21 changes: 19 additions & 2 deletions includes/class-chip-givewp-purchase.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,34 @@ public function cc_form( $form_id ) {

ob_start();

// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- GiveWP core hook for gateway field rendering.
// Preferred (prefixed) hook. Use this for new code.
do_action( 'gwp_chip_before_info_fields', $form_id );

// Legacy hook kept for backward compatibility. Deprecated in 1.4.0;
// will be removed in 2.0.0. New code should listen to
// gwp_chip_before_info_fields instead.
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Legacy hook retained for back-compat with < 1.4.0 consumers.
do_action( 'give_before_chip_info_fields', $form_id );
?>
<fieldset class="no-fields" id="give_chip_payment_info">
<?php echo wp_kses_post( $instructions ); ?>
</fieldset>
<?php

// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- GiveWP core hook for gateway field rendering.
// Preferred (prefixed) hook. Use this for new code.
do_action( 'gwp_chip_after_info_fields', $form_id );

// Legacy hook kept for backward compatibility. Deprecated in 1.4.0;
// will be removed in 2.0.0. New code should listen to
// gwp_chip_after_info_fields instead.
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Legacy hook retained for back-compat with < 1.4.0 consumers.
do_action( 'give_after_chip_info_fields', $form_id );

if ( function_exists( '_deprecated_hook' ) ) {
_deprecated_hook( 'give_before_chip_info_fields', '1.4.0', 'gwp_chip_before_info_fields' );
_deprecated_hook( 'give_after_chip_info_fields', '1.4.0', 'gwp_chip_after_info_fields' );
}

echo wp_kses_post( ob_get_clean() );
}

Expand Down