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(); + }); + }); });