Merge pull request #15 from kristianwind/repo-rename

Rename the repository to woo-discount-manager, keep the installed slug
This commit is contained in:
github-actions[bot]
2026-09-16 16:20:01 +00:00
committed by GitHub
5 changed files with 91 additions and 5 deletions
+4 -1
View File
@@ -4,7 +4,7 @@ Tags: woocommerce, discount, email, shipping, coupon
Requires at least: 5.8
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.4.5
Stable tag: 1.4.6
WC requires at least: 6.0
WC tested up to: 11.1.0
License: GPLv2 or later
@@ -96,6 +96,9 @@ The most specific match wins: exact email, then domain, then partial match.
== Changelog ==
= 1.4.6 =
* Housekeeping: the plugin's source moved to a shorter address. Updates continue to arrive as before, and nothing needs doing.
= 1.4.5 =
* Fixed: the plugin could offer its own release as an update to a different plugin. Plugins that update from the same place share one check inside WordPress, and this one answered for all of them instead of only for itself. If another such plugin is installed, update it as well.
* "Vis detaljer" next to the update notice now opens the plugin's own details, with the release notes as the changelog. It previously showed "Plugin not found", because WordPress was asking wordpress.org about a plugin that is not published there.
+7
View File
@@ -7,6 +7,13 @@
# Directory name the plugin gets inside wp-content/plugins, and the name of the
# built zip. WordPress identifies a plugin by "<slug>/<main file>", so changing
# this after release orphans every installed copy.
#
# 🔴 THIS DELIBERATELY DOES NOT MATCH THE REPOSITORY NAME, and it must not be
# "tidied up" to. The repo is woo-discount-manager; the installed directory has
# been woocommerce-email-discount-manager since the first release and is on a
# live shop. Renaming it would not move that installation — it would put a
# SECOND copy beside it and leave the old one active. The repo name is free to
# change (Gitea keeps a 301, measured), the installed slug never is.
PLUGIN_SLUG=woocommerce-email-discount-manager
# The file carrying the plugin header. Version: in here is the version.
+17
View File
@@ -143,6 +143,23 @@ for readme in readme.txt README.txt; do
|| note_fail "$readme has 'Stable tag: $stable' but the plugin header says $version."
done
ci_step "no secrets in tracked files"
# Suggested by the AI-manager port, and it costs nothing: a pushed key cannot be
# unpushed. It has to be rotated, and the window between the push and noticing
# is the whole problem.
#
# Deliberately narrow. Broad entropy heuristics fire on minified assets, hashes
# and base64 images, and a check that cries wolf gets commented out — which is
# worse than not having it. These are prefixes that mean one thing only.
before=$fails
while IFS= read -r -d '' f; do
[ -f "$f" ] || continue
if LC_ALL=C grep -nE '(sk-ant-[A-Za-z0-9_-]{16,}|sk-[A-Za-z0-9]{32,}|ghp_[A-Za-z0-9]{30,}|gho_[A-Za-z0-9]{30,}|github_pat_[A-Za-z0-9_]{50,}|AKIA[0-9A-Z]{16}|-----BEGIN [A-Z ]*PRIVATE KEY-----)' "$f"; then
note_fail "$f looks like it contains a credential. It cannot be unpushed — rotate it."
fi
done < <(git ls-files -z)
[ "$fails" = "$before" ] && echo " nothing that looks like a key or a private key"
ci_step "no placeholders left in the plugin header"
# The header is the plugin's business card: wp-admin shows the author and the
# links to whoever installs it, so a placeholder there survives for as long as
+59
View File
@@ -140,6 +140,65 @@ None of them were caught by reading the code, and a green build is exactly what
a broken check looks like. So: break it on purpose once, watch it go red, then
put it back. It costs one run.
## The bug you cannot find by reading your own repo
🔴 **`update_plugins_{$hostname}` is keyed on the hostname, not the
repository.** Every plugin whose `Update URI` points at the same host shares one
hook, and WordPress runs **every** callback on it for **every** one of those
plugins:
```php
// wp-includes/update.php
$update = apply_filters( "update_plugins_{$hostname}", false, $plugin_data, $plugin_file, $locales );
```
Answer unconditionally and you offer your release to your neighbour. Measured on
a live shop: a subscriptions plugin was shown this one's 1.4.4 and told it was
an update for itself. Load order decides who wins, so which plugin gets
corrupted is arbitrary — and pointed at one with auto-updates enabled, it
installs a stranger's zip over itself, unattended, on a shop taking money.
```php
add_filter( "update_plugins_{$host}", array( $this, 'offer_update' ), 10, 3 );
public function offer_update( $update, $plugin_data, $plugin_file = '' ) {
if ( '' !== $plugin_file && plugin_basename( SELF_FILE ) !== $plugin_file ) {
return $update;
}
```
Both halves. Leave the accepted-argument count at 2 and the third argument never
arrives, so the guard compares against an empty string and does nothing — the
same shape of bug it exists to fix. `plugins_api` is safe if it guards on
`$args->slug`.
**No integration test can find this.** A site test installs one plugin from that
host, so the collision cannot arise there. The assertion is the entire defence:
```php
wc_edm_ok( 'another plugin on the same host is not offered our release',
false === $updater->offer_update( false, $data, 'someone-else/someone-else.php' ) );
```
The same shape applies to anything else shared between sibling plugins. A
`shared-*.php` file copied byte-identically into five plugins fatals with
`Cannot redeclare` on the second activation unless everything in it is wrapped
in `function_exists()` / `class_exists()` / `defined()` — and then the copy that
loads first wins, which is alphabetical order, which is arbitrary. Freeze the
contract rather than versioning the file.
## The repository name and the installed slug are different things
The repo may be renamed freely — Gitea keeps a 301 on both the API and the deep
release-download paths (measured), and WordPress follows up to 5 redirects by
default, so installed copies keep updating through the old `Update URI`.
The **installed** slug can never change. It is `<slug>/<main file>` in
`wp-content/plugins`, and a new one installs a second copy beside the first
while the old one stays active. So `PLUGIN_SLUG` in `ci/plugin.conf` is allowed
to disagree with the repository name forever, and if it does, say so in the file
or somebody will helpfully align them.
## Two guards worth understanding before you move them
**`.gitea/workflows/` hides `.github/workflows/` completely.** Gitea uses the
+4 -4
View File
@@ -1,10 +1,10 @@
<?php
/**
* Plugin Name: WooCommerce Email Discount Manager
* Plugin URI: https://gitea.nolimit.dk/kw/woocommerce-email-discount-manager
* Update URI: https://gitea.nolimit.dk/kw/woocommerce-email-discount-manager
* Plugin URI: https://gitea.nolimit.dk/kw/woo-discount-manager
* Update URI: https://gitea.nolimit.dk/kw/woo-discount-manager
* Description: Apply discounts and show/hide shipping methods based on the customer's email address (full address, domain or partial match).
* Version: 1.4.5
* Version: 1.4.6
* Author: Kristian Wind
* Author URI: https://gitea.nolimit.dk/kw
* License: GPL-2.0-or-later
@@ -28,7 +28,7 @@ if ( ! defined( 'ABSPATH' ) ) {
exit;
}
define( 'WC_EDM_VERSION', '1.4.5' );
define( 'WC_EDM_VERSION', '1.4.6' );
define( 'WC_EDM_PLUGIN_FILE', __FILE__ );
define( 'WC_EDM_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'WC_EDM_PLUGIN_URL', plugin_dir_url( __FILE__ ) );