Answer the details modal, and make two dead checks check

wp-admin builds "View version details" as
plugin-install.php?tab=plugin-information&plugin=<slug>, which calls
plugins_api() — which asks wordpress.org. This plugin is not there, so the link
opened a modal reading "Plugin not found." on the same screen that was telling
the shop owner an update was ready. Seen on the live shop, not inferred.

The filter is answered here now: name, version from the feed, author, links,
compatibility, and the release notes as the changelog — escaped rather than
rendered, because a release body is not a template language. Another plugin's
slug falls through untouched, with an assertion on that: answering for somebody
else would replace their modal with ours.

Two checks in ci/update-smoke.sh could not fail, both found by the subscriptions
port, both sitting under a comment explaining exactly what they were for:

- the plugin directories were counted into a variable that was never read. The
  comment above it describes a zip installing a SECOND copy beside the first;
  nothing tested it. Now: directories starting with the slug, exactly one.
- the last step ran `wp eval 'echo WC_EDM_VERSION;'`, hard-coding this plugin's
  constant into a script that is copied between plugins. Elsewhere it printed
  an empty value and carried on. The name is read out of the plugin header now
  and the value is compared against the version that was installed, because
  files can be replaced while the running code still reports the old version.

Both verified failing before being believed: copies=2 and copies=0 fail,
running != expected fails, and a plugin with no *_VERSION constant takes the
branch that says so instead of comparing against an empty string.

CORRECTION to the note added with the release-id fix. It said those four
releases published correctly "because this instance's author id is -1". That is
wrong in a way that invites relaxing: gitea.nolimit.dk is one instance and both
plugins publish to it. The difference is WHO publishes. A release created by the
Actions job token has the ghost user as its author ("id":-1) and the minus sign
hides it from [0-9]+; a release created by a real user — a cross-repo PAT, or
one published by hand — has "id":1 and the greedy match lands on it. Verified:
this repo's latest release reports {'id': -1, 'login': 'Ghost'}. Corrected in
CLAUDE.md and docs/REUSE.md.

docs/REUSE.md gains "Make a check fail once before you believe it", listing all
three dead checks found today. A green build is exactly what a broken check
looks like.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kristianwind
2026-09-16 14:00:21 +02:00
co-authored by Claude Opus 5
parent fc412e6f2f
commit 416c74ac5b
4 changed files with 164 additions and 8 deletions
+25 -3
View File
@@ -126,6 +126,20 @@ measures something else. It cost two rounds here, once on
If a script reports something you just fixed as still missing, `git status`
before you debug the script.
## Make a check fail once before you believe it
Three checks in this directory turned out to be incapable of failing, and all
three sat under a comment explaining exactly what they were for:
- `tests/smoke.php` printed `FAIL` and exited 0 for four releases.
- `ci/static.sh`'s PHP lint passed while linting an empty directory.
- `ci/update-smoke.sh` counted the plugin directories into a variable and never
looked at it — under a comment about a zip installing a second copy.
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.
## Two guards worth understanding before you move them
**`.gitea/workflows/` hides `.github/workflows/` completely.** Gitea uses the
@@ -144,9 +158,17 @@ the *last* id in the payload, and a release object carries an embedded
`author` and, once anything is attached, an `assets` array — each with an id of
its own. `ci/publish-release.sh` uses a four-line `json_field()` over `python3`
instead. Measured here: the greedy pattern returns the asset ids 1/2/3/4 for
releases whose real ids are 416/417/419/421. Four releases were published
correctly anyway, purely because this instance's author id is **-1** and the
minus sign stops `[0-9]+` from matching. That is not a safety margin.
releases whose real ids are 416/417/419/421.
Four releases were published correctly anyway, and the reason is **who
published them, not which instance**: a release created by the Actions job
token has the ghost user as its author (`"id":-1`), and the minus sign stops
`[0-9]+` from matching. A release created by a real user — a cross-repo PAT, or
one published by hand — has `"id":1` and the greedy match lands on it. Do not
read the `-1` as a safety margin; it lasts until the first release somebody
publishes by hand. And on a re-run the lookup fetches a response that *has*
assets, where the last id is an asset id: positive, on any instance, with any
token.
**A forge's own download URL is not the address your users can reach.**
`browser_download_url` is built from the forge's configured root URL;