Compare commits
3 Commits
wc-cleanup
...
feat/v1.6.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a54b5c90a8 | ||
|
|
4a506e1c56 | ||
|
|
6da83981b4 |
3
.github/workflows/cto-review.yml
vendored
3
.github/workflows/cto-review.yml
vendored
@@ -208,8 +208,7 @@ jobs:
|
||||
1. Assess whether the change is safe to merge and deploy to production (peptiderepo.com on Hostinger WordPress).
|
||||
2. Flag security issues, cost traps (paid AI API usage), performance regressions, missing input sanitization, missing output escaping, hardcoded secrets, broken migrations, or violations of the repo's CONVENTIONS.md.
|
||||
3. Check that the PR follows the project's git workflow: branch naming (claude/<scope>-<date>), Agent-Session trailer in commits, PR description covers what/why/risk/test-plan.
|
||||
4. CTO app-map freshness. If this PR modifies any of: (a) the admin settings surface (register_setting, add_submenu_page, add_options_page, settings field labels, option keys, types, defaults); (b) the file/class structure (any file added, renamed, split per the 300-line rule, or materially restructured); or (c) the data flow (new external API client, new hook/filter fired publicly, new scheduled job, or changed class responsibilities) — then the PR description MUST include a line referencing an accompanying update to `Peptide Repo CTO/app-maps/<repo-slug>.md`. The CTO workspace is a separate repo, so CI cannot verify the doc update mechanically — you must inspect the PR description for an explicit mention. If the description is silent despite a triggering change, raise this as a MAJOR concern (not blocking) so the author can add the mention or open a follow-up PR on the CTO workspace.
|
||||
5. Be concise and direct. No pleasantries. Call out concrete line-level issues when possible.
|
||||
4. Be concise and direct. No pleasantries. Call out concrete line-level issues when possible.
|
||||
|
||||
You MUST respond by calling the submit_review function. Do not write prose outside the tool call.
|
||||
|
||||
|
||||
42
.github/workflows/deploy.yml
vendored
42
.github/workflows/deploy.yml
vendored
@@ -45,25 +45,13 @@ jobs:
|
||||
mkdir -p ~/.ssh
|
||||
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/deploy_key
|
||||
chmod 600 ~/.ssh/deploy_key
|
||||
# Best-effort: keyscan stderr captured for diagnosis but never fatal.
|
||||
# We use StrictHostKeyChecking=no on the actual ssh/rsync calls anyway.
|
||||
ssh-keyscan -p ${{ secrets.SSH_PORT }} ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts 2>/tmp/keyscan.err || {
|
||||
echo "::warning::ssh-keyscan failed (non-fatal). stderr:"
|
||||
cat /tmp/keyscan.err || true
|
||||
}
|
||||
|
||||
- name: Verify deploy destination is a theme directory
|
||||
run: |
|
||||
# Safety check: abort if destination does not look like a WordPress theme.
|
||||
# Prevents rsync --delete from wiping the wrong directory if the path
|
||||
# is ever mis-configured.
|
||||
DEST="/home/${{ secrets.SSH_USERNAME }}/domains/peptiderepo.com/public_html/wp-content/themes/peptide-starter"
|
||||
ssh -i ~/.ssh/deploy_key -p ${{ secrets.SSH_PORT }} -o StrictHostKeyChecking=no ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }} "test -f \"${DEST}/style.css\" || { echo \"ERROR: ${DEST}/style.css not found — aborting deploy to prevent rsync --delete wiping wrong directory\"; exit 1; }"
|
||||
|
||||
- name: Snapshot plugin inventory (pre-deploy)
|
||||
run: |
|
||||
# Record active plugins before deploy so we can verify nothing was
|
||||
# accidentally wiped by rsync if the destination path drifts.
|
||||
ssh -i ~/.ssh/deploy_key -p ${{ secrets.SSH_PORT }} -o StrictHostKeyChecking=no ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }} "wp --path=/home/${{ secrets.SSH_USERNAME }}/domains/peptiderepo.com/public_html plugin list --status=active --fields=name --allow-root 2>/dev/null | tee /tmp/plugins_pre_deploy.txt && echo \"Pre-deploy plugin count: $(wc -l < /tmp/plugins_pre_deploy.txt)\""
|
||||
|
||||
- name: Deploy via rsync
|
||||
run: |
|
||||
rsync -avz --delete \
|
||||
@@ -79,25 +67,6 @@ jobs:
|
||||
-e "ssh -i ~/.ssh/deploy_key -p ${{ secrets.SSH_PORT }} -o StrictHostKeyChecking=no" \
|
||||
./ ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }}:/home/${{ secrets.SSH_USERNAME }}/domains/peptiderepo.com/public_html/wp-content/themes/peptide-starter/
|
||||
|
||||
- name: Verify plugin inventory unchanged (post-deploy)
|
||||
run: |
|
||||
# Fail the deploy if rsync wiped any plugins. Compares active plugin
|
||||
# list before and after — any drop means something went wrong.
|
||||
ssh -i ~/.ssh/deploy_key -p ${{ secrets.SSH_PORT }} -o StrictHostKeyChecking=no ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }} << 'ENDSSH'
|
||||
wp --path=/home/${{ secrets.SSH_USERNAME }}/domains/peptiderepo.com/public_html plugin list --status=active --fields=name --allow-root 2>/dev/null > /tmp/plugins_post_deploy.txt
|
||||
PRE=$(wc -l < /tmp/plugins_pre_deploy.txt)
|
||||
POST=$(wc -l < /tmp/plugins_post_deploy.txt)
|
||||
echo "Pre-deploy active plugins: $PRE"
|
||||
echo "Post-deploy active plugins: $POST"
|
||||
if [ "$POST" -lt "$PRE" ]; then
|
||||
echo "ERROR: Plugin count dropped from $PRE to $POST after deploy."
|
||||
echo "Missing plugins:"
|
||||
diff /tmp/plugins_pre_deploy.txt /tmp/plugins_post_deploy.txt || true
|
||||
exit 1
|
||||
fi
|
||||
echo "Plugin inventory OK."
|
||||
ENDSSH
|
||||
|
||||
- name: Purge LiteSpeed Cache
|
||||
run: |
|
||||
ssh -i ~/.ssh/deploy_key -p ${{ secrets.SSH_PORT }} -o StrictHostKeyChecking=no \
|
||||
@@ -119,8 +88,13 @@ jobs:
|
||||
run: |
|
||||
sleep 5
|
||||
STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://peptiderepo.com)
|
||||
# 200 = normal healthy response.
|
||||
# 403 = peptide-starter-theme v1.5.2 CF-peer validator rejecting this
|
||||
# GHA-runner direct-to-origin request as non-Cloudflare traffic.
|
||||
# That rejection is the validator working — itself a positive
|
||||
# liveness signal. Real user traffic via Cloudflare gets 200.
|
||||
if [ "$STATUS" != "200" ] && [ "$STATUS" != "403" ]; then
|
||||
echo "ERROR: Site returned unexpected HTTP $STATUS after deploy"
|
||||
exit 1
|
||||
fi
|
||||
echo "Site is responsive (HTTP $STATUS)"
|
||||
echo "Site is responsive (HTTP $STATUS)"
|
||||
16
CHANGELOG.md
16
CHANGELOG.md
@@ -2,22 +2,6 @@
|
||||
|
||||
All notable changes to the Peptide Starter Theme are documented in this file.
|
||||
|
||||
## [1.7.0] - 2026-04-24 — Remove WooCommerce integration
|
||||
|
||||
WooCommerce is not used on peptiderepo.com. Removing dead code reduces the asset
|
||||
dequeue surface and eliminates the function_exists() guard introduced in the 2026-04-23
|
||||
hotfix.
|
||||
|
||||
### Removed
|
||||
- WooCommerce asset dequeue block from `inc/perf-asset-policy.php` (styles:
|
||||
woocommerce-layout, woocommerce-smallscreen, woocommerce-general; scripts:
|
||||
wc-add-to-cart, woocommerce, sourcebuster-js, wc-order-attribution)
|
||||
- Cart icon in `header.php` (was conditional on `class_exists('WooCommerce')`)
|
||||
- `peptide_starter_perf_woocommerce_styles` and `peptide_starter_perf_woocommerce_scripts`
|
||||
filter hooks
|
||||
- WooCommerce-specific tests from `tests/test-perf-asset-policy.php`
|
||||
- WooCommerce section from README.md and CONVENTIONS.md
|
||||
|
||||
## [1.6.0] - 2026-04-23 — Mobile Performance Phase 1
|
||||
|
||||
Mobile-perf optimization targeting LCP reduction through conditional asset
|
||||
|
||||
@@ -460,6 +460,11 @@ if ( is_active_sidebar( 'footer-1' ) ) {
|
||||
|
||||
### Class Existence Check
|
||||
|
||||
**For WooCommerce:**
|
||||
```php
|
||||
if ( class_exists( 'WooCommerce' ) ) {
|
||||
// Render cart icon
|
||||
}
|
||||
```
|
||||
|
||||
**For post types:**
|
||||
|
||||
@@ -115,6 +115,15 @@
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<!-- Cart Icon (WooCommerce) -->
|
||||
<?php if ( class_exists( 'WooCommerce' ) ) { ?>
|
||||
<button class="header-icon-btn cart-toggle" aria-label="<?php esc_attr_e( 'View cart', 'peptide-starter' ); ?>">
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M1 1H3.27924M3.27924 1L5.20081 13.5631C5.35072 14.4571 5.80765 15.2614 6.4543 15.8285C7.10095 16.3956 7.92274 16.6882 8.76721 16.6882H16.7257M16.7257 16.6882C17.3169 16.6882 17.7793 17.1506 17.7793 17.7418C17.7793 18.333 17.3169 18.7955 16.7257 18.7955M16.7257 16.6882C15.6515 16.6882 14.4632 16.6882 8.76721 16.6882M8.76721 16.6882C8.17601 16.6882 7.71365 17.1506 7.71365 17.7418C7.71365 18.333 8.17601 18.7955 8.76721 18.7955M5.20081 13.5631H16.7257" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
<?php } ?>
|
||||
|
||||
<!-- Mobile Menu Toggle -->
|
||||
<button class="menu-toggle" aria-label="<?php esc_attr_e( 'Toggle menu', 'peptide-starter' ); ?>">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*
|
||||
* Optimizes the front-end asset graph by dequeuing unnecessary plugin styles/scripts
|
||||
* and slimming font requests. Targets mobile LCP improvement through:
|
||||
* - Conditional dequeue of Elementor and USMI assets
|
||||
* - Conditional dequeue of WC, Elementor, and USMI assets
|
||||
* - Google Fonts weight slimming (36 faces → 5)
|
||||
* - Preconnect hints for font.googleapis.com + fonts.gstatic.com
|
||||
* - Defer attribute on cookie-notice script
|
||||
@@ -49,10 +49,11 @@ function peptide_starter_perf_asset_policy_init() {
|
||||
/**
|
||||
* Dequeue assets on non-applicable page types.
|
||||
*
|
||||
* Removes Elementor and Ultimate Social Media Icons assets from pages
|
||||
* Removes WooCommerce, Elementor, and Ultimate Social Media Icons assets from pages
|
||||
* that don't use them. Controlled by the kill-switch constant PEPTIDE_STARTER_PERF_DEQUEUE.
|
||||
*
|
||||
* Dequeue conditions:
|
||||
* - WC: removed unless on shop, cart, checkout, or account pages
|
||||
* - Elementor: removed if page doesn't use Elementor builder
|
||||
* - USMI: removed on homepage, archives, and blog index
|
||||
*
|
||||
@@ -64,6 +65,28 @@ function peptide_starter_perf_dequeue_plugin_assets() {
|
||||
return;
|
||||
}
|
||||
|
||||
// WooCommerce assets: dequeue on non-shop pages.
|
||||
if ( ! is_woocommerce() && ! is_cart() && ! is_checkout() && ! is_account_page() ) {
|
||||
// Get configured WC handles from filter; default list.
|
||||
$wc_styles = apply_filters(
|
||||
'peptide_starter_perf_woocommerce_styles',
|
||||
array( 'woocommerce-layout', 'woocommerce-smallscreen', 'woocommerce-general' )
|
||||
);
|
||||
|
||||
foreach ( $wc_styles as $handle ) {
|
||||
wp_dequeue_style( $handle );
|
||||
}
|
||||
|
||||
$wc_scripts = apply_filters(
|
||||
'peptide_starter_perf_woocommerce_scripts',
|
||||
array( 'wc-add-to-cart', 'woocommerce', 'sourcebuster-js', 'wc-order-attribution' )
|
||||
);
|
||||
|
||||
foreach ( $wc_scripts as $handle ) {
|
||||
wp_dequeue_script( $handle );
|
||||
}
|
||||
}
|
||||
|
||||
// Elementor assets: dequeue if page doesn't use Elementor.
|
||||
if ( ! peptide_starter_page_uses_elementor( get_queried_object_id() ) ) {
|
||||
$elementor_handles = apply_filters(
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/**
|
||||
* Tests for inc/perf-asset-policy.php.
|
||||
*
|
||||
* Covers: conditional dequeue logic (Elementor, USMI), font weight slimming,
|
||||
* Covers: conditional dequeue logic (WC, Elementor, USMI), font weight slimming,
|
||||
* preconnect hints, script defer, kill-switch, and filter overrides.
|
||||
*
|
||||
* @package peptide-starter
|
||||
@@ -24,16 +24,57 @@ class Test_Perf_Asset_Policy extends WP_UnitTestCase {
|
||||
define( 'PEPTIDE_STARTER_PERF_DEQUEUE', false );
|
||||
|
||||
// Enqueue dummy styles.
|
||||
wp_enqueue_style( 'elementor-frontend', 'http://example.com/elementor.css' );
|
||||
wp_enqueue_style( 'woocommerce-layout', 'http://example.com/wc.css' );
|
||||
|
||||
// Simulate wp_enqueue_scripts action.
|
||||
do_action( 'wp_enqueue_scripts' );
|
||||
|
||||
// Since kill-switch is off, the style should still be queued.
|
||||
$this->assertTrue( wp_style_is( 'elementor-frontend', 'enqueued' ) );
|
||||
$this->assertTrue( wp_style_is( 'woocommerce-layout', 'enqueued' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: WC assets dequeued on non-shop pages.
|
||||
*
|
||||
* Homepage (front page) is not a WC page, so WC styles/scripts should dequeue.
|
||||
*/
|
||||
public function test_wc_dequeue_on_homepage() {
|
||||
$this->go_to( home_url( '/' ) );
|
||||
|
||||
// Enqueue WC styles.
|
||||
wp_enqueue_style( 'woocommerce-layout', 'http://example.com/wc-layout.css' );
|
||||
wp_enqueue_style( 'woocommerce-general', 'http://example.com/wc-general.css' );
|
||||
wp_enqueue_script( 'woocommerce', 'http://example.com/wc.js' );
|
||||
|
||||
// Run dequeue at priority 100.
|
||||
peptide_starter_perf_dequeue_plugin_assets();
|
||||
|
||||
// All WC assets should be dequeued.
|
||||
$this->assertFalse( wp_style_is( 'woocommerce-layout', 'enqueued' ) );
|
||||
$this->assertFalse( wp_style_is( 'woocommerce-general', 'enqueued' ) );
|
||||
$this->assertFalse( wp_script_is( 'woocommerce', 'enqueued' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: WC assets remain on /shop page.
|
||||
*
|
||||
* On WC shop pages, WC assets should NOT dequeue.
|
||||
*/
|
||||
public function test_wc_not_dequeued_on_shop() {
|
||||
// Skip if WooCommerce is not active.
|
||||
if ( ! class_exists( 'WooCommerce' ) ) {
|
||||
$this->markTestSkipped( 'WooCommerce not active.' );
|
||||
}
|
||||
|
||||
// Enqueue WC styles.
|
||||
wp_enqueue_style( 'woocommerce-layout', 'http://example.com/wc-layout.css' );
|
||||
|
||||
// The dequeue function checks is_woocommerce(); we'll mock it.
|
||||
// For a true test, we'd need a real WC shop page setup.
|
||||
// Instead, we assert the filter allows override.
|
||||
$default_handles = apply_filters( 'peptide_starter_perf_woocommerce_styles', array() );
|
||||
$this->assertIsArray( $default_handles );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test: Elementor assets dequeued on pages without Elementor.
|
||||
|
||||
Reference in New Issue
Block a user