@linchpinagency/skills 0.1.11 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ GitHub Copilot, and other compatible coding agents.
|
|
|
12
12
|

|
|
13
13
|
|
|
14
14
|
<!-- x-release-please-start-version -->
|
|
15
|
-
### Latest release: 0.1.
|
|
15
|
+
### Latest release: 0.1.12
|
|
16
16
|
<!-- x-release-please-end -->
|
|
17
17
|
|
|
18
18
|
| Release | Skill standard | Install |
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: quality-gates
|
|
3
|
-
description: Run a Linchpin project's own lint, coding-standards, static-analysis, and
|
|
4
|
-
version: 1.
|
|
3
|
+
description: Run a Linchpin project's own lint, coding-standards, static-analysis, test and Plugin Check gates before committing or opening a PR — detecting the toolchain from composer.json, package.json, phpcs.xml.dist and lint-staged rather than assuming it. Use when preparing to commit, when asked "is this ready to commit/ship", when CI lint or PHPCS is failing, when a pre-commit hook blocks you, when a plugin has to pass Plugin Check before it ships, or when a repo is missing the standard lint scripts. Not for writing the commit message — use `commit-and-release`.
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Quality gates
|
|
@@ -22,6 +22,7 @@ is checked but in what counts as a failure.
|
|
|
22
22
|
- The user asks whether a change is ready to ship.
|
|
23
23
|
- CI lint / PHPCS / PHPStan failed and you need to reproduce and fix it locally.
|
|
24
24
|
- A husky pre-commit hook is blocking a commit.
|
|
25
|
+
- A plugin is heading for WordPress.org, packagist.linchpin.com, or a release.
|
|
25
26
|
- A repo is missing the house lint scripts and should get them.
|
|
26
27
|
|
|
27
28
|
**Not this skill:** the commit message, branch, or release — [`commit-and-release`](../commit-and-release/SKILL.md).
|
|
@@ -47,6 +48,7 @@ the same conventions but expose different gates.
|
|
|
47
48
|
| `package.json` → `scripts` | JS/CSS gates (`lint:js`, `lint:css`, `format`, `lint:check`) | Fall back to `eslint`/`prettier` only if configured |
|
|
48
49
|
| `lint-staged.config.js` + `.husky/` | Pre-commit is already wired — **mirror those exact commands** | Run the scripts directly |
|
|
49
50
|
| Nested `package.json` (e.g. `themes/*`, `plugins/*`, `src/`) | Gates run **in that workspace**, not the root | Root only |
|
|
51
|
+
| A plugin header (`Plugin Name:`) plus `readme.txt`, or `.github/workflows/plugin-check.yml` | It is a distributed plugin → **Plugin Check applies** | Skip it; Plugin Check is meaningless for a theme or a site repo |
|
|
50
52
|
| `.linchpin.json` | Project metadata and local environments | Not every repo has one |
|
|
51
53
|
|
|
52
54
|
Full command matrix: [`references/toolchain.md`](references/toolchain.md).
|
|
@@ -68,7 +70,13 @@ Full command matrix: [`references/toolchain.md`](references/toolchain.md).
|
|
|
68
70
|
5. **Fix, don't silence.** Auto-fixers first (`composer run phpcbf`, `composer run fixer`,
|
|
69
71
|
`npm run format`), then re-run the gate; hand-fix what remains. → Gate passes with the
|
|
70
72
|
fix in the code, not in the config.
|
|
71
|
-
6. **
|
|
73
|
+
6. **Plugin Check gate** — distributed plugins only. `composer run plugin-check` where the
|
|
74
|
+
repo has it, otherwise the commands in
|
|
75
|
+
[`references/toolchain.md`](references/toolchain.md#plugin-check). It builds the
|
|
76
|
+
distributable and boots WordPress, so it is slower than the rest: run it before opening
|
|
77
|
+
the PR rather than on every commit. → Zero findings, **warnings included**, or each one
|
|
78
|
+
fixed or excluded with a stated reason.
|
|
79
|
+
7. **Report gaps, then hand off.** State which gates ran, which were skipped and why. If the
|
|
72
80
|
repo lacks a house script, propose it (see `references/toolchain.md`) and add it **only
|
|
73
81
|
with approval**. → Then go to [`commit-and-release`](../commit-and-release/SKILL.md).
|
|
74
82
|
|
|
@@ -133,6 +141,14 @@ registered there hides exactly the bug the sniff exists to catch. Setting the sn
|
|
|
133
141
|
dependency change ([`dependency-updates`](../dependency-updates/SKILL.md)), not a fix.
|
|
134
142
|
- **Never** commit `vendor/`, `node_modules/`, or build output unless the repo already
|
|
135
143
|
tracks it — check `.gitignore` and `.distignore` first.
|
|
144
|
+
- **Never** read a green "Plugin Check" tick on a PR as a passing Plugin Check.
|
|
145
|
+
`wordpress/plugin-check-action` fails the job on *errors* only, so a plugin carrying
|
|
146
|
+
warnings — the ones WordPress.org review actually raises — shows a passing check. The
|
|
147
|
+
local run is the one that tells the truth, because it treats any finding as a failure.
|
|
148
|
+
- **Never** assume `composer phpcs` covers Plugin Check. Plugin Check ships its own
|
|
149
|
+
`PluginCheck.*` sniffs inside the plugin-check plugin; they are not part of the Linchpin
|
|
150
|
+
standard, so `phpcs.xml.dist` cannot reference them and PHPCS runs green while Plugin
|
|
151
|
+
Check reports findings. Two gates, not one gate twice.
|
|
136
152
|
- If a tool can't run (not installed, no config, requires Docker that isn't up), **say so
|
|
137
153
|
explicitly**. A silently skipped gate reads as a passing gate.
|
|
138
154
|
|
|
@@ -143,5 +159,7 @@ registered there hides exactly the bug the sniff exists to catch. Setting the sn
|
|
|
143
159
|
- [ ] JS/CSS gate passed in the owning workspace (or correctly not applicable).
|
|
144
160
|
- [ ] Tests run for touched, covered code.
|
|
145
161
|
- [ ] The changed-file annotation count is zero — warnings included, not just errors.
|
|
162
|
+
- [ ] For a distributed plugin: Plugin Check run **locally** with zero findings, warnings
|
|
163
|
+
included — not merely a green badge on the PR.
|
|
146
164
|
- [ ] No suppressions, config widenings, or `--no-verify` were used to get green.
|
|
147
165
|
- [ ] Skipped gates and missing house scripts are named in the report.
|
|
@@ -58,6 +58,120 @@ it; running the root script may silently skip it.
|
|
|
58
58
|
lint-staged rules deliberately skip.
|
|
59
59
|
- A blocked commit means the gate found something real. Fix the code; never `--no-verify`.
|
|
60
60
|
|
|
61
|
+
## Plugin Check
|
|
62
|
+
|
|
63
|
+
Applies to **distributed plugins only** — anything with a plugin header that ships to
|
|
64
|
+
WordPress.org, packagist.linchpin.com, or a client as a zip. Skip it for themes and site
|
|
65
|
+
repos.
|
|
66
|
+
|
|
67
|
+
### It is not PHPCS, and PHPCS cannot stand in for it
|
|
68
|
+
|
|
69
|
+
Plugin Check ships its own PHPCS sniffs — the `PluginCheck.*` ruleset — **inside the
|
|
70
|
+
plugin-check plugin**. They are not part of the Linchpin standard, so `phpcs.xml.dist` has
|
|
71
|
+
no way to reference them. `composer run phpcs` therefore runs green on code Plugin Check
|
|
72
|
+
reports on, and no amount of configuring PHPCS closes the gap.
|
|
73
|
+
|
|
74
|
+
It also runs checks PHPCS has no concept of: readme structure, header fields, the stable
|
|
75
|
+
tag, translations, enqueued-asset rules, image sizes in the zip.
|
|
76
|
+
|
|
77
|
+
A worked example. This passes `composer run phpcs` and fails Plugin Check:
|
|
78
|
+
|
|
79
|
+
```php
|
|
80
|
+
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery
|
|
81
|
+
$ids = $wpdb->get_col( $wpdb->prepare( $sql, ...$values ) );
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
The `phpcs:disable` names the `WordPress.DB.*` sniffs, because those are the ones the local
|
|
85
|
+
standard has. `PluginCheck.Security.DirectDB.UnescapedDBParameter` is not silenced, is not
|
|
86
|
+
in the local standard, and fires only under Plugin Check.
|
|
87
|
+
|
|
88
|
+
### A green badge is not a passing check
|
|
89
|
+
|
|
90
|
+
`wordpress/plugin-check-action` fails the job on Plugin Check **errors** and not on
|
|
91
|
+
**warnings**. A PR can show a passing "Plugin Check" tick while carrying warnings that
|
|
92
|
+
WordPress.org review will raise — the check reports success and uploads the findings to an
|
|
93
|
+
artifact nobody opens.
|
|
94
|
+
|
|
95
|
+
So the local run is the authority, and it should treat **any finding as a failure**. When
|
|
96
|
+
CI and local disagree here, local is right.
|
|
97
|
+
|
|
98
|
+
This is the mirror image of *Green locally, red in CI* in
|
|
99
|
+
[`../SKILL.md`](../SKILL.md#green-locally-red-in-ci). There the shared lint workflow
|
|
100
|
+
annotates warnings a clean local run ignored; here CI ignores warnings a strict local run
|
|
101
|
+
catches. Same underlying cause both times — the two ends disagree about what counts as a
|
|
102
|
+
failure, not about what to check — so neither end is trustworthy on its own without knowing
|
|
103
|
+
which way it leans.
|
|
104
|
+
|
|
105
|
+
To see what CI actually found rather than trusting the tick:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
gh run view <run-id> --log | grep -A5 'Run Plugin Check'
|
|
109
|
+
gh run download <run-id> -n plugin-check-results # the findings, in full
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Running it
|
|
113
|
+
|
|
114
|
+
| Intent | Command |
|
|
115
|
+
| --- | --- |
|
|
116
|
+
| The gate | `composer run plugin-check` |
|
|
117
|
+
| What CI saw | `gh run download <run-id> -n plugin-check-results` |
|
|
118
|
+
|
|
119
|
+
When the repo has no script, the check needs a built plugin and a WordPress to run in:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# 1. Build the distributable — check what ships, not the source tree, or you
|
|
123
|
+
# get findings from tests/ that never ship and miss what the build breaks.
|
|
124
|
+
composer run build
|
|
125
|
+
|
|
126
|
+
# 2. Boot WordPress with the *built* plugin mapped in, on a port nothing else holds.
|
|
127
|
+
# wp-env defaults to 8888/8889, which any other project of yours already owns.
|
|
128
|
+
mkdir -p build/plugin-check && cd build/plugin-check
|
|
129
|
+
cat > .wp-env.json <<'JSON'
|
|
130
|
+
{ "core": null, "plugins": [ "../<slug>" ], "port": 8973, "testsPort": 8974 }
|
|
131
|
+
JSON
|
|
132
|
+
npx wp-env start
|
|
133
|
+
|
|
134
|
+
# 3. Check it, with the same flags as the workflow.
|
|
135
|
+
npx wp-env run cli wp plugin install plugin-check --activate
|
|
136
|
+
npx wp-env run cli wp plugin check <slug> \
|
|
137
|
+
--categories=general,performance,accessibility,security,plugin_repo \
|
|
138
|
+
--include-experimental \
|
|
139
|
+
--format=csv
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Keep `--categories` and `--exclude-checks` in step with
|
|
143
|
+
`.github/workflows/plugin-check.yml`. Two sets of flags that drift are two different gates,
|
|
144
|
+
and the PR is judged by the one you did not run.
|
|
145
|
+
|
|
146
|
+
### A finding you have decided to accept
|
|
147
|
+
|
|
148
|
+
Some findings are architectural and correct — a migration tool that queries `wp_posts`
|
|
149
|
+
directly because the post type it must reach is no longer registered, for instance. Those
|
|
150
|
+
do not get a silent pass:
|
|
151
|
+
|
|
152
|
+
1. Add the check id to `--exclude-checks` in **both** the local script and the workflow.
|
|
153
|
+
2. Comment the reason where the exclusion lives, not in a commit message.
|
|
154
|
+
3. Say so in the PR, because WordPress.org review will ask the same question.
|
|
155
|
+
|
|
156
|
+
`stable_tag_mismatch` / `no_stable_tag` / `trunk_stable_tag` are the standard exclusions on
|
|
157
|
+
a pre-release branch: release-please stamps the version on release, so before one the built
|
|
158
|
+
`readme.txt` legitimately trails the tag.
|
|
159
|
+
|
|
160
|
+
### The house script
|
|
161
|
+
|
|
162
|
+
```jsonc
|
|
163
|
+
// composer.json
|
|
164
|
+
"scripts": {
|
|
165
|
+
"plugin-check": "bash scripts/plugin-check.sh"
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
The script builds, boots wp-env against the built artifact, installs plugin-check, runs it
|
|
170
|
+
with the workflow's flags, and **exits non-zero on any finding**. `linchpin/block-alchemy`
|
|
171
|
+
carries the reference implementation. It needs `@wordpress/env` in `devDependencies` and
|
|
172
|
+
Docker running; both are worth stating in the failure message, because a missing Docker
|
|
173
|
+
looks like a passing gate otherwise.
|
|
174
|
+
|
|
61
175
|
## The house script set
|
|
62
176
|
|
|
63
177
|
When a repo is missing these, propose adding them — matching the repo's existing tooling,
|