Plugin Check lokal und in der CI: Befunde vor dem Review

Management Summary
Plugin Check ist ein Prüfwerkzeug für WordPress-Erweiterungen. Es hilft bei der Entwicklung, typische Probleme vor der Veröffentlichung zu finden, etwa fehlende Lizenzangaben oder unsicheren Umgang mit angezeigten Daten. Prüfungen können auf dem eigenen Rechner und automatisch nach Änderungen stattfinden. Der Nutzen liegt in früher erkannten Fehlern und weniger vermeidbarer Nacharbeit bei der Einreichung. Der Artikel erklärt den sinnvollen Einsatz; ein leerer Bericht garantiert weder Sicherheit noch Aufnahme ins Verzeichnis.
Inhalt
Plugin Check sucht vor einer Einreichung bei WordPress.org nach typischen Fehlern: fehlenden Lizenzangaben, unsicheren Ausgaben oder falsch zugeordneten Übersetzungen. Das Werkzeug wird auch PCP genannt. Ein Treffer zeigt eine Stelle zur Prüfung; ein Lauf ohne Treffer beweist weder Sicherheit noch die spätere Aufnahme ins Verzeichnis.
Der Beitrag erklärt die Bedienung im WordPress-Verwaltungsbereich, auf der Kommandozeile und in GitHub Actions. CI bedeutet hier: Nach einer Codeänderung startet GitHub automatisch einen Prüflauf. Die technischen Einzelheiten beziehen sich auf Plugin Check 2.1.0 und die Action v1.1.9. Ein absichtlich fehlerhaftes Beispiel und eine verbesserte Fassung zeigen den Unterschied.
Was Plugin Check prüft
Plugin Check 2.1.0 setzt mindestens WordPress 6.3 und PHP 7.4 voraus. Die frühere Beispielumgebung mit WordPress 7.1.2 ist ein historischer Teststand, keine aktuelle Updateempfehlung. Für neue Testumgebungen zählt die aktuelle unterstützte WordPress-Version. Angaben wie „Tested up to“ beschreiben einen Teststand, keine vollständige Verträglichkeitsgarantie.
Version 2.1.0 registriert 34 Prüfungen. Jede Prüfung hat einen kurzen technischen Namen, etwa late_escaping. Statische Prüfungen lesen Programmdateien, ohne den untersuchten Plugin-Code auszuführen. Viele verwenden PHP_CodeSniffer, kurz PHPCS. Dessen einzelne Regeln heißen Sniffs. Escaping bedeutet, Ausgaben passend für HTML-Text oder HTML-Attribute zu schützen, damit enthaltene Zeichen nicht als fremder Code wirken.
Laufzeitprüfungen beobachten das aktivierte Plugin während der Ausführung. Plugin Check verwendet dafür eigene Testtabellen. Das ist keine vollständige Sicherheitsgrenze: Plugin-Code kann weiterhin Dateien oder externe Dienste ansprechen. Deshalb gehört die Prüfung in eine entbehrliche lokale Testinstallation ohne echte Kundendaten oder produktive Zugangsdaten. Die fünf Laufzeitprüfungen in 2.1.0 betreffen Größe, Einsatzbereich und Ladeverhalten von Skripten und Stylesheets.
| Kategorie (Slug) | Beispiele für Prüfungen in 2.1.0 |
|---|---|
General (general) | i18n_usage, php_error_reporting, ai_provider |
Plugin Repo (plugin_repo) | plugin_readme, plugin_header_fields, file_type, offloading_files, setting_sanitization, prefixing, plugin_review_phpcs, trademarks |
Security (security) | late_escaping, direct_file_access, safe_redirect, direct_db_queries, direct_db |
Performance (performance) | enqueued_scripts_in_footer, performant_wp_query_params, enqueued_scripts_scope, non_blocking_scripts |
Accessibility (accessibility) | keine: Die Kategorie ist definiert, aber keine mitgelieferte Prüfung aus 2.1.0 ist ihr zugeordnet |
Alle Security-Prüfungen aus 2.1.0 gehören zusätzlich zu plugin_repo. Diese Kategorie enthält also bereits Prüfungen zu Ausgaben und direktem Dateizugriff. Laut FAQ müssen für die Verzeichnisaufnahme üblicherweise alle Prüfungen der Kategorie Plugin Repo bestanden werden. Andere Kategorien ergänzen diese Vorprüfung. Die Entscheidung des Reviewteams bleibt erforderlich.
ERROR bedeutet Fehler, WARNING Warnung. Dazu gehört eine numerische Gewichtung, die Severity. Diese Einstufung ist keine zuverlässige Rangfolge des tatsächlichen Sicherheitsrisikos. Auch eine Warnung wegen fehlender Formularprüfung kann eine echte Lücke betreffen. Ein nur angezeigter URL-Parameter benötigt dagegen nicht allein deshalb eine Nonce. Entscheidend sind Verarbeitung, Ausgabe und mögliche Änderungen an Daten. Eine Nonce hilft gegen fremd ausgelöste Anfragen; eine Berechtigungsprüfung entscheidet, welches Konto eine Aktion ausführen darf.
Lokal ausführen: Backend und WP-CLI
Nach der Installation und Aktivierung erscheint unter Werkzeuge → Plugin Check die Auswahl für Plugins, Kategorien und Ergebnistypen. Der Zugang verlangt das Recht zur Plugin-Verwaltung. Ergebnisse nennen Datei, Zeile, Spalte, Typ, Code und Erklärung. Seit Version 1.8.0 ist ein Export als CSV, JSON oder Markdown möglich. Alle folgenden Befehle beziehen sich auf die lokale Testinstallation.
WP-CLI steuert WordPress über die Kommandozeile. wp plugin check akzeptiert einen Plugin-Namen, einen Pfad oder eine ZIP-Adresse. Standardmäßig laufen nur statische Prüfungen. Für Laufzeitprüfungen lädt --require die Datei cli.php vor dem WordPress-Start; außerdem muss das geprüfte Plugin aktiv sein. Ohne diese Voraussetzungen fehlt ein Teil der Prüfungen. Ein fehlender Laufzeitbefund belegt dann keine korrekte Funktion.
# Local disposable test installation; version used for this article.
wp plugin install plugin-check --version=2.1.0 --activate
# All static checks for wp-content/plugins/lw-hello-banner.
wp plugin check lw-hello-banner
# Include runtime checks (plugin must be active): load cli.php before WordPress boots.
wp plugin check lw-hello-banner --require=./wp-content/plugins/plugin-check/cli.php
# Limit the run to categories or to single checks.
wp plugin check lw-hello-banner --categories=plugin_repo,security
wp plugin check lw-hello-banner --checks=late_escaping,i18n_usage
# Findings as one JSON array; no findings produces a success line.
wp plugin check lw-hello-banner --ignore-warnings --format=strict-json --fields=file,line,column,type,code,message
# Show result codes, then ignore one specific code.
wp plugin check lw-hello-banner --format=csv --fields=code,message
wp plugin check lw-hello-banner --ignore-codes=textdomain_mismatch
# Checks for an update of an existing directory plugin.
wp plugin check lw-hello-banner --mode=update
# What is available in the installed version.
wp plugin list-checks --format=csv
wp plugin list-check-categoriesDie wichtigsten Optionen von wp plugin check in Version 2.1.0:
| Option | Wirkung |
|---|---|
--checks=, --exclude-checks= | nur die genannten Prüfungen ausführen oder auslassen |
--categories= | Lauf auf Kategorien beschränken, kommagetrennt |
--ignore-codes= | einzelne Ergebniscodes ausblenden, etwa textdomain_mismatch |
--ignore-warnings, --ignore-errors | einen der beiden Ergebnistypen ausblenden |
--format= | table (Standard), csv, json, ctrf sowie strict-table, strict-csv, strict-json, strict-ctrf |
--fields= | Spalten wählen, zum Beispiel code,message |
--exclude-directories=, --exclude-files= | Pfade bei dateibasierten Scans überspringen; .git, vendor, vendor_prefixed, vendor-prefixed und node_modules sind ohnehin ausgenommen |
--severity=, --error-severity=, --warning-severity= | nur Ergebnisse ab einer bestimmten Schwere zeigen |
--mode= | new (Standard) oder update; im Update-Modus ist ein veraltetes „Tested up to“ eine Warnung statt eines Fehlers |
--slug= | den Slug überschreiben, gegen den Text Domain und Readme verglichen werden |
Ein Prüfungsname wählt den Test aus, ein Ergebniscode bezeichnet einen Befund. Beispiel: --checks=i18n_usage wählt Übersetzungsprüfungen. --ignore-codes=WordPress.WP.I18n.TextDomainMismatch blendet dagegen passende Befunde aus. --format=csv --fields=code,message zeigt Codes und Erklärungen zum Nachschlagen.
Der CLI-Code von 2.1.0 beendet einen Lauf bei gefundenen Problemen nicht automatisch mit einem Fehlerstatus. Exitcode 0 bedeutet deshalb nicht „keine Befunde“. Ein automatischer Freigabeschritt muss die Ergebnisse zusätzlich auswerten und darf fehlende oder unlesbare Ausgaben nicht als Erfolg behandeln. Die GitHub Action enthält eine eigene Auswertung.
Bei --format=json steht vor jeder Datei eine Zeile FILE: … mit anschließendem JSON-Array. Die Gesamtausgabe ist daher kein einzelnes JSON-Dokument. --format=strict-json liefert bei Befunden ein gemeinsames Array. Dateinamen fehlen in den Standardspalten; --fields=file,line,column,type,code,message nimmt die Dateispalte hinzu. Ohne Befunde erscheint weiterhin eine Erfolgszeile statt eines leeren Arrays. Ein Skript muss beide Fälle ausdrücklich unterscheiden.
Ein Beispiel-Plugin mit eingebauten Fehlern
Das absichtlich fehlerhafte Plugin liegt in wp-content/plugins/lw-hello-banner/. Der Ordnername ist hier der Slug. Die Text Domain ordnet übersetzbare Texte dem Plugin zu und soll ebenfalls lw-hello-banner lauten. Das Beispiel zeigt einen Gruß, liest einen Namen aus der URL und bietet ein Notizfeld. Es enthält unter anderem rohe Ausgaben, fehlende Lizenzangaben und ein extern geladenes Skript. CDN bezeichnet dabei einen fremden Dienst zur Dateiauslieferung. Diese fehlerhafte Fassung dient nur zum Lesen und Prüfen in einer entbehrlichen Umgebung.
/**
* Plugin Name: LW Hello Banner
* Description: Shows a greeting banner at the top of the front page.
* Version: 0.1.0
* Author: Lukas Wojcik
* Text Domain: hello-banner
*/
// Intentionally faulty example for Plugin Check. Do not use on a live site.
error_reporting( E_ALL );
function lw_hello_banner_register_setting() {
register_setting( 'general', 'lw_hello_banner_note' );
add_settings_field(
'lw_hello_banner_note',
__( 'Banner note', 'hello-banner' ),
'lw_hello_banner_field',
'general'
);
}
add_action( 'admin_init', 'lw_hello_banner_register_setting' );
function lw_hello_banner_field() {
echo '<input type="text" name="lw_hello_banner_note" value="' . get_option( 'lw_hello_banner_note' ) . '">';
}
function lw_hello_banner_assets() {
wp_enqueue_script( 'lw-hello-banner', 'https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.3/dist/confetti.browser.min.js' );
}
add_action( 'wp_enqueue_scripts', 'lw_hello_banner_assets' );
function lw_hello_banner_render() {
$name = isset( $_GET['lw_name'] ) ? $_GET['lw_name'] : 'Guest';
$note = get_option( 'lw_hello_banner_note', '' );
echo '<div class="lw-hello-banner"><p>' . sprintf( __( 'Hello, %s!', 'hello-banner' ), $name ) . ' ' . $note . '</p></div>';
}
add_action( 'wp_body_open', 'lw_hello_banner_render' );Was Plugin Check dazu meldet
Die Tabelle ordnet typische Befunde aus dem Regelwerk von Plugin Check 2.1.0 den Fehlern im Beispiel zu. Anzahl und genaue Ausgabe hängen von Umgebung, Version und ausgewählten Prüfungen ab. Die Tabelle ist keine zugesicherte aktuelle Laufmessung.
| Ergebniscode | Prüfung (Kategorie) | Typ | Ursache im Beispiel |
|---|---|---|---|
no_plugin_readme | plugin_readme (plugin_repo) | ERROR | keine readme.txt |
plugin_header_no_license | plugin_header_fields (plugin_repo) | ERROR | kein License-Header |
textdomain_mismatch | plugin_header_fields (plugin_repo) | WARNING | Header nennt hello-banner, Slug ist lw-hello-banner |
missing_direct_file_access_protection | direct_file_access (security, plugin_repo) | ERROR | Funktionen und Hooks ohne ABSPATH-Abfrage |
WordPress.WP.I18n.TextDomainMismatch | i18n_usage (general, plugin_repo) | ERROR | __()-Aufrufe mit falscher Text Domain |
WordPress.WP.I18n.MissingTranslatorsComment | i18n_usage (general, plugin_repo) | ERROR | %s ohne translators:-Kommentar |
PluginCheck.CodeAnalysis.PHPErrorReporting.DirectErrorReportingCall | php_error_reporting (general) | WARNING | error_reporting( E_ALL ) |
WordPress.PHP.DevelopmentFunctions.prevent_path_disclosure_error_reporting | plugin_review_phpcs (plugin_repo) | WARNING | error_reporting( E_ALL ) |
PluginCheck.CodeAnalysis.SettingSanitization.register_settingMissing | setting_sanitization (plugin_repo) | ERROR | register_setting() ohne drittes Argument |
WordPress.Security.EscapeOutput.OutputNotEscaped | late_escaping (security, plugin_repo) | ERROR | get_option(), __(), $name und $note im echo |
PluginCheck.CodeAnalysis.EnqueuedResourceOffloading.OffloadedContent | offloading_files (plugin_repo) | ERROR | Skript-URL auf cdn.jsdelivr.net |
WordPress.WP.EnqueuedResourceParameters.MissingVersion, .NotInFooter | enqueued_scripts_in_footer (performance) | WARNING | keine Version, kein fünftes Argument |
WordPress.Security.NonceVerification.Recommended | plugin_review_phpcs (plugin_repo) | WARNING | $_GET['lw_name'] ohne Nonce-Prüfung |
WordPress.Security.ValidatedSanitizedInput.MissingUnslash, .InputNotSanitized | plugin_review_phpcs (plugin_repo) | WARNING | $_GET['lw_name'] unbehandelt verwendet |
Mehrere Prüfungen können dieselbe Ursache melden. Die Header-Prüfung vergleicht die Text Domain im Dateikopf mit dem Slug; die i18n-Prüfung kontrolliert Übersetzungsaufrufe. Auch error_reporting() kann mehrere Regeln treffen. Die Nonce- und Eingaberegeln stammen aus plugin_review_phpcs. Eine Auswahl nur der Kategorie security erfasst deshalb nicht sämtliche sicherheitsrelevanten Hinweise.
Statische und Laufzeitprüfungen untersuchen unterschiedliche Eigenschaften. Ein externes Skript kann schon wegen der fremden Adresse auffallen. Bei einem lokalen Skript ist zusätzlich wichtig, auf welchen Seiten es geladen wird. Ein Banner nur auf der Startseite braucht keine zugehörige Skriptdatei auf jeder Unterseite. Ein fehlender Treffer ersetzt diese Funktionsprüfung nicht.
Die korrigierte Fassung
Die verbesserte Fassung besteht aus Hauptdatei, readme.txt und lokalem JavaScript in assets/. Der Dateikopf nennt Lizenz und Mindestversionen. Die ABSPATH-Abfrage verhindert den direkten Aufruf außerhalb von WordPress. Das Notizfeld erhält eine Bereinigungsfunktion; HTML-Ausgaben werden unmittelbar vor der Ausgabe geschützt. Das Skript lädt nur auf der Startseite. defer verschiebt die Ausführung bis nach dem Einlesen des HTML-Dokuments. Diese Form der Ladeoptionen ist seit WordPress 6.3 verfügbar.
/**
* Plugin Name: LW Hello Banner
* Description: Shows a greeting banner at the top of the front page.
* Version: 0.2.0
* Requires at least: 6.3
* Requires PHP: 7.4
* Author: Lukas Wojcik
* License: GPLv2 or later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: lw-hello-banner
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
define( 'LW_HELLO_BANNER_VERSION', '0.2.0' );
/**
* Registers the banner note setting and its field on Settings > General.
*/
function lw_hello_banner_register_setting() {
register_setting(
'general',
'lw_hello_banner_note',
array(
'type' => 'string',
'sanitize_callback' => 'sanitize_text_field',
'default' => '',
)
);
add_settings_field(
'lw_hello_banner_note',
__( 'Banner note', 'lw-hello-banner' ),
'lw_hello_banner_field',
'general',
'default',
array( 'label_for' => 'lw_hello_banner_note' )
);
}
add_action( 'admin_init', 'lw_hello_banner_register_setting' );
/**
* Prints the input field for the banner note.
*/
function lw_hello_banner_field() {
printf(
'<input type="text" class="regular-text" id="lw_hello_banner_note" name="lw_hello_banner_note" value="%s">',
esc_attr( get_option( 'lw_hello_banner_note', '' ) )
);
}
/**
* Loads the bundled script on the front page only.
*/
function lw_hello_banner_assets() {
if ( ! is_front_page() ) {
return;
}
wp_enqueue_script(
'lw-hello-banner',
plugins_url( 'assets/lw-hello-banner.js', __FILE__ ),
array(),
LW_HELLO_BANNER_VERSION,
array(
'in_footer' => true,
'strategy' => 'defer',
)
);
}
add_action( 'wp_enqueue_scripts', 'lw_hello_banner_assets' );
/**
* Prints the banner on the front page.
*/
function lw_hello_banner_render() {
if ( ! is_front_page() ) {
return;
}
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only display value, nothing is stored.
$name = isset( $_GET['lw_name'] ) ? sanitize_text_field( wp_unslash( $_GET['lw_name'] ) ) : '';
if ( '' === $name ) {
$name = __( 'Guest', 'lw-hello-banner' );
}
$greeting = sprintf(
/* translators: %s: visitor name */
__( 'Hello, %s!', 'lw-hello-banner' ),
$name
);
$note = get_option( 'lw_hello_banner_note', '' );
echo '<div class="lw-hello-banner"><p>' . esc_html( $greeting );
if ( '' !== $note ) {
echo ' ' . esc_html( $note );
}
echo '</p><button type="button">' . esc_html__( 'Dismiss', 'lw-hello-banner' ) . '</button></div>';
}
add_action( 'wp_body_open', 'lw_hello_banner_render' );Der eigene URL-Parameter heißt lw_name. Der allgemeine Parameter name wird von WordPress bereits zur Beitragsauswahl verwendet und kann deshalb die aufgerufene Seite verändern oder eine 404-Antwort auslösen. Der Beispielwert wird bereinigt und nur als geschützter Text angezeigt. Der eng begrenzte phpcs:ignore-Kommentar unterdrückt deshalb die Nonce-Warnung für diese Zeile. Für einen Speichervorgang wäre diese Begründung falsch: Dort sind auch Formular- und Berechtigungsprüfung nötig. Die Unterschiede erklärt der Beitrag zu WordPress-Sicherheitsfunktionen.
=== LW Hello Banner ===
Contributors: lukaswojcik
Tags: banner, greeting
Requires at least: 6.3
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 0.2.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Shows a short, dismissible greeting banner at the top of the front page.
== Description ==
LW Hello Banner prints a greeting on the front page. An optional note can be set under Settings > General.
== Changelog ==
= 0.2.0 =
* Add output escaping, setting sanitization and a local script.
= 0.1.0 =
* Initial version.Tested up to nennt die tatsächlich geprüfte WordPress-Hauptversion, beispielsweise 7.1. Die Zahl darf nicht nur geändert werden, um eine Meldung zu beseitigen. Das Regelwerk kann einen veralteten Wert bei neuen Plugins als Fehler und im Update-Modus als Warnung melden. Ein Patchwert wie 7.1.2 kann ebenfalls beanstandet werden. Die Lizenzangaben in Readme und Hauptdatei müssen zusammenpassen. Weitere Einzelheiten stehen im Beitrag über Readme und Plugin-Header.
// assets/lw-hello-banner.js
( function () {
const banner = document.querySelector( '.lw-hello-banner' );
if ( ! banner ) {
return;
}
const button = banner.querySelector( 'button' );
if ( button ) {
button.addEventListener( 'click', function () {
banner.hidden = true;
} );
}
} )();Plugin Check in GitHub Actions
Die offizielle Action stammt aus WordPress/plugin-check-action. Der folgende Ablauf ist am Quelltext von v1.1.9 nachvollzogen. Die Action richtet Node 24 und die lokale WordPress-Testumgebung wp-env ein, installiert Plugin Check und benötigte Plugins und aktiviert das Prüfobjekt. Der Aufruf verwendet --require für Laufzeitprüfungen. Die übliche Ausführung von wp-env benötigt Docker; im Workflow dient ein Ubuntu-Rechner von GitHub als Testsystem.
Die Action liest die Ergebnisdatei und zeigt Befunde direkt an den betroffenen Dateien. Ein ausgewertetes ERROR setzt den Exitcode auf 1, eine Warnung allein nicht. Mit strict: true führen auch ausgewertete Warnungen zum Fehlerstatus. Das gilt nur für tatsächlich erkannte Ergebniseinträge. Unvollständige Ausgaben oder ausgeblendete Prüfungen erlauben keinen allgemeinen Sicherheitsnachweis. Bei Pull Requests kann zusätzlich ein Zusammenfassungskommentar entstehen; die Rohdatei wird als herunterladbares Prüfergebnis gespeichert.
Eingaben in v1.1.9: build-dir (Standard ./), checks, exclude-checks, categories, exclude-files, exclude-directories, ignore-codes, ignore-warnings, ignore-errors, include-experimental, wp-version (latest oder trunk), severity, error-severity, warning-severity, include-low-severity-errors, include-low-severity-warnings, slug, strict und repo-token. Listen-Eingaben nehmen einen Eintrag je Zeile.
build-dir bestimmt den geprüften Ordner. Dessen letzter Namensbestandteil dient normalerweise als Slug; die Eingabe slug kann diesen Wert ersetzen. Ein abweichender Name kann falsche Übersetzungsbefunde auslösen. Außerdem gehört Entwicklungszubehör wie .github nicht in das ausgelieferte Plugin. Der Workflow baut deshalb mit git archive einen eigenen Ausgabeordner. Einträge mit export-ignore in .gitattributes bleiben dabei draußen. Nur bereits im Git-Commit enthaltene Dateien gelangen in dieses Archiv.
# .github/workflows/plugin-check.yml
name: Plugin Check
on:
pull_request:
push:
branches:
- main
permissions:
contents: read
pull-requests: write # only for the summary comment on pull requests
jobs:
plugin-check:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
# Build the folder that would be shipped, without .github and other
# development files (see export-ignore in .gitattributes).
- name: Build distributable plugin folder
run:
mkdir -p build
git archive --format=tar --prefix=lw-hello-banner/ HEAD | tar -x -C build
- name: Run Plugin Check
uses: wordpress/plugin-check-action@v1.1.9
with:
# The folder name becomes the slug (text domain check, readme check).
build-dir: ./build/lw-hello-banner
wp-version: latest
# Optional filters, one entry per line:
# categories: |
# plugin_repo
# security
# exclude-checks: |
# enqueued_scripts_scope
# ignore-codes: |
# textdomain_mismatch
# Fail on warnings as well:
# strict: true# .gitattributes: files that git archive leaves out of the build
/.gitattributes export-ignore
/.github export-ignore
/.gitignore export-ignore
/build export-ignorepull-requests: write ermöglicht den optionalen Zusammenfassungskommentar. Bei Pull Requests aus fremden Forks kann dieses Recht eingeschränkt sein. Ein Kommentarfehler wird im Action-Code als Fehlerhinweis protokolliert, setzt dort aber nicht zusätzlich den Exitcode. Der Workflow verwendet v1.1.9 statt des mitwandernden Tags v1. Für eine feste Codeidentität ist ein vollständiger geprüfter Commit-Hash stärker; auch Versions-Tags sind grundsätzlich veränderbar.
Grenzen und offene Punkte
- Plugin Check ersetzt keine manuelle Prüfung. Ein Lauf ohne Treffer garantiert keine Freigabe.
- Die PHP-Beispiele bestanden die Syntaxprüfung. Isolierte Tests prüften den Archivaufbau, den Bannerknopf und den offiziellen Ergebnisparser. Ein vollständiger WordPress-Lauf oder ein auf GitHub ausgeführter Workflow ist für diese Beispiele hier nicht belegt.
- Einige Prüfungen leiten wahrscheinliche Namensmuster aus dem Code ab. Ein gemeinsamer Funktionsanfang wie
lw_hello_banner_verringert Namenskollisionen. Eine daraus abgeleitete Regel muss trotzdem im Einzelfall bewertet werden. - Action v1.1.9 bietet keine Eingabe für eine feste Plugin-Check-Version. In einer frischen Umgebung wird die Verzeichnisversion installiert. Ein festes Action-Tag legt deshalb nicht sämtliche Abhängigkeiten fest.
- Eine Eingabe für die PHP-Version fehlt. Nur
trunkwählt in v1.1.9 eine andere WordPress-Quelle; andere Werte vonwp-versionführen zur aktuellen Veröffentlichung. Tests älterer Versionen brauchen einen gesonderten Aufbau, beschrieben in einem eigenen Beitrag dieser Reihe. - Skriptbefunde hängen von den geprüften Seiten und Ladebedingungen ab. Der Artikel zum gezielten Entfernen von Skripten erklärt das gezielte Entfernen von Plugin-Skripten.
Fragen und Antworten
Garantiert ein Lauf ohne Befunde, dass das Plugin ins Verzeichnis aufgenommen wird?
Nein. Ein Lauf ohne Treffer erleichtert die Vorbereitung, garantiert aber keine Freigabe. Die manuelle Prüfung beurteilt weitere Fragen wie Dienstzweck, Darstellung und Lizenz.
Warum meldet die GitHub Action mehr als der lokale Aufruf von wp plugin check?
Drei Unterschiede sind zuerst zu prüfen:
- Die Action lädt
cli.phpund aktiviert das Prüfobjekt. Ein lokaler Lauf kann Laufzeitprüfungen auslassen. - Plugin-Check-Version oder ausgewählte Prüfungen können abweichen.
- Der geprüfte Ordner kann Entwicklungsdateien enthalten, die im Veröffentlichungspaket fehlen.
Wann ist es vertretbar, eine Warnung zu unterdrücken?
Nur eine nachvollziehbar falsche Meldung darf gezielt ausgeblendet werden. Bei einer harmlosen Textanzeige kann ein begründeter phpcs:ignore-Kommentar an genau dieser Zeile passen. Das ist keine allgemeine Ausnahme für URL-Eingaben. ignore-codes blendet denselben Code im gesamten Plugin aus und kann echte Fehler verdecken.
Warum wird dieselbe Text Domain zweimal beanstandet?
Die Header-Prüfung kontrolliert den Dateikopf, die i18n-Prüfung die einzelnen Übersetzungsaufrufe. Beide müssen zum selben Plugin passen. Ein falscher Slug kann deshalb viele Meldungen erzeugen. slug in der Action beziehungsweise --slug auf der Kommandozeile legt den Vergleichswert ausdrücklich fest.
Quellen
- Plugin Check (PCP) auf WordPress.org
- WordPress/plugin-check, README
- Plugin Check Release 2.1.0
- Plugin Check: WP-CLI-Dokumentation (docs/CLI.md)
- Plugin Check: verfügbare Prüfungen (docs/checks.md)
- Default_Check_Repository.php (Tag 2.1.0)
- Check_Categories.php (Tag 2.1.0)
- Plugin_Check_Command.php (Tag 2.1.0)
- plugin-check.ruleset.xml (Tag 2.1.0)
- Quelltext der Prüfungen (Tag 2.1.0)
- Unit-Tests der Prüfungen (Tag 2.1.0)
- WordPress/plugin-check-action, README
- plugin-check-action: action.yml (v1.1.9)
- plugin-check-action: src/main.ts (v1.1.9)
- plugin-check-action Release v1.1.9
- wp_enqueue_script() – Developer Resources
- @wordpress/env – Block Editor Handbook
- WordPress.org version API
- actions/checkout Releases (v7.0.1)
- GitHub Docs: Variablen (GITHUB_WORKSPACE)
- GitHub Docs: Berechtigungen für GitHub Apps