From 5db35604642959581df3be96c4452accb9a67d9d Mon Sep 17 00:00:00 2001 From: Richards Date: Tue, 11 Aug 2026 14:50:21 -0500 Subject: [PATCH] feat(LINCHPIN-5363): Allow wp-plugin and wp-theme as commit types wp-plugin and wp-theme were only ever valid scopes here (update(wp-plugin):, build(deps):), matching this repo's own README and tests. But release-please's changelog-sections groups strictly by commit type - that schema has no scope key - so a repo whose release-please-config gives WordPress plugins and themes their own changelog section has no way to reach it without wp-plugin/wp-theme being the type. linchpin/renovatebot-config's release-please-config.json already defines "WordPress Plugins" and "WordPress Themes" sections keyed on exactly those types, added on the assumption this package would accept them. It never did, so every Renovate PR there updating a WordPress plugin or theme via wp-plugin(wporg): / wp-plugin(linchpin): / wp-theme(deps): has been generating a commit that fails this config outright. Adds wp-plugin and wp-theme to TYPES, and wporg/linchpin to DEP_SCOPES so the type form has a scope to pair with beyond the type name itself. Both existing scope-form usages (update(wp-plugin):, build(deps):, etc.) and the new type-form usages are valid at the same time - this is additive, nothing that passed before stops passing. README and tests updated to document and cover both forms. --- README.md | 18 ++++++++++++++++-- index.js | 14 +++++++++++--- index.test.js | 27 +++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 500da84..5fc8b37 100644 --- a/README.md +++ b/README.md @@ -87,15 +87,29 @@ build(composer): Update humbug/php-scoper to v0.18.19 chore(actions): Update actions/checkout to v7 ``` -Allowed: `deps`, `deps-dev`, `wp-plugin`, `wp-theme`, `npm`, `composer`, `actions`. These are emitted by [linchpin/renovatebot-config](https://github.com/linchpin/renovatebot-config); anything else must still be a task key, `NO-TASK`, or an issue number. +Allowed: `deps`, `deps-dev`, `wp-plugin`, `wp-theme`, `npm`, `composer`, `actions`, `wporg`, `linchpin`. These are emitted by [linchpin/renovatebot-config](https://github.com/linchpin/renovatebot-config); anything else must still be a task key, `NO-TASK`, or an issue number. `build` is the [Angular convention's type for external dependencies](https://www.conventionalcommits.org/en/v1.0.0-beta.4/), and `update` reads better for a WordPress plugin bump — both are valid here. +### `wp-plugin` / `wp-theme` as a type instead of a scope + +`wp-plugin` and `wp-theme` are also valid **types**, not just scopes: + +``` +wp-plugin(wporg): Update akismet to v5.3 +wp-plugin(linchpin): Update some-plugin to v3.0 - Major +wp-theme(deps): Update twentytwentyfour to v2.0 +``` + +This exists for one reason: [release-please](https://github.com/googleapis/release-please)'s `changelog-sections` groups strictly by commit **type** — `changelog-sections[].type` is the only key that schema offers, there is no scope key — so a repo that wants WordPress plugin and theme updates in their own changelog section (rather than folded into whatever section `update` or `build` maps to) has no way to get one except by making `wp-plugin`/`wp-theme` the type. `wporg` and `linchpin` are then available as scopes to say which registry the package came from. + +Both forms lint cleanly. Use the scope form (`update(wp-plugin):`) unless a repo's `release-please-config.json` specifically defines a dedicated section for the `wp-plugin`/`wp-theme` type — [linchpin/renovatebot-config](https://github.com/linchpin/renovatebot-config) is the current example that does. + ## Rules | Rule | Level | Description | | --- | --- | --- | -| `type-enum` | error | Type must be one of: `add`, `improve`, `build`, `chore`, `ci`, `docs`, `feat`, `feature`, `fix`, `perf`, `refactor`, `remove`, `revert`, `style`, `test`, `update` | +| `type-enum` | error | Type must be one of: `add`, `improve`, `build`, `chore`, `ci`, `docs`, `feat`, `feature`, `fix`, `perf`, `refactor`, `remove`, `revert`, `style`, `test`, `update`, `wp-plugin`, `wp-theme` | | `subject-case` | warning | Subject must be in sentence-case | The config also sets a custom `parserPreset.parserOpts.headerPattern` that enforces the scope format. diff --git a/index.js b/index.js index 332fff1..19a37b2 100644 --- a/index.js +++ b/index.js @@ -1,12 +1,20 @@ 'use strict'; -const TYPES = ['add', 'improve', 'build', 'chore', 'ci', 'docs', 'feat', 'feature', 'fix', 'perf', 'refactor', 'remove', 'revert', 'style', 'test', 'update']; +// wp-plugin and wp-theme are deliberately in both TYPES and DEP_SCOPES. As a scope +// (`update(wp-plugin): ...`) they keep a WordPress update legible in a mostly automated +// log. As a type (`wp-plugin(wporg): ...`) they let a repo route WordPress plugin and +// theme updates to their own release-please changelog section - `changelog-sections[].type` +// is the only key that schema offers, so a dedicated section is only reachable through +// type. Neither usage is deprecated; pick whichever a repo's release-please-config needs. +const TYPES = ['add', 'improve', 'build', 'chore', 'ci', 'docs', 'feat', 'feature', 'fix', 'perf', 'refactor', 'remove', 'revert', 'style', 'test', 'update', 'wp-plugin', 'wp-theme']; // Dependency updates have no task behind them, so the scope slot carries the kind of // dependency instead - which is what the wider ecosystem does too (`build(deps)`, // `chore(deps-dev)`). wp-plugin and wp-theme keep WordPress updates obvious at a glance -// in a log that is mostly automated. deps-dev precedes deps so the longer one wins. -const DEP_SCOPES = ['deps-dev', 'deps', 'wp-plugin', 'wp-theme', 'npm', 'composer', 'actions']; +// in a log that is mostly automated. wporg and linchpin name a WordPress package's source +// for repos that promote wp-plugin/wp-theme to a type instead, and so need a scope other +// than the type itself. deps-dev precedes deps so the longer one wins. +const DEP_SCOPES = ['deps-dev', 'deps', 'wp-plugin', 'wp-theme', 'npm', 'composer', 'actions', 'wporg', 'linchpin']; // A ClickUp-style task key, NO-TASK, a GitHub issue number, or a dependency scope. const SCOPE = new RegExp(`^(?:[A-Z]+-\\d+|NO-TASK|#\\d+|${DEP_SCOPES.join('|')})$`); diff --git a/index.test.js b/index.test.js index 84b36e6..0cdef73 100644 --- a/index.test.js +++ b/index.test.js @@ -163,4 +163,31 @@ describe('@linchpinagency/commitlint-config', () => { expect(explain(header)).not.toBeNull(); }); }); + + // wp-plugin and wp-theme double as types, not just scopes, so a repo whose + // release-please-config gives WordPress plugins/themes their own changelog section can + // emit one. release-please groups strictly by type, so this is the only way in. + describe('wp-plugin and wp-theme as types', () => { + const { explain } = config; + const pattern = config.parserPreset.parserOpts.headerPattern; + + test.each([ + 'wp-plugin(wporg): Update akismet to v5.3', + 'wp-plugin(linchpin): Update some-plugin to v3.0', + 'wp-theme(deps): Update twentytwentyfour to v2.0', + ])('accepts %s', (header) => { + expect(explain(header)).toBeNull(); + expect(header).toMatch(pattern); + }); + + test('wporg and linchpin are valid scopes', () => { + expect(explain('wp-plugin(wporg): Update something')).toBeNull(); + expect(explain('wp-plugin(linchpin): Update something')).toBeNull(); + }); + + test('the scope form documented above still works alongside the type form', () => { + expect(explain('update(wp-plugin): Update translatepress-multilingual to v3.2.4')).toBeNull(); + expect(explain('update(wp-theme): Update ollie-pro to v2.6.1')).toBeNull(); + }); + }); });