Skip to content

[rush][rush-published-versions-json-plugin] Add plugin-native global commands; add published versions JSON plugin.#5701

Merged
iclanton merged 11 commits intomicrosoft:mainfrom
iclanton:rush-published-versions-plugin
Mar 24, 2026
Merged

[rush][rush-published-versions-json-plugin] Add plugin-native global commands; add published versions JSON plugin.#5701
iclanton merged 11 commits intomicrosoft:mainfrom
iclanton:rush-published-versions-plugin

Conversation

@iclanton
Copy link
Member

@iclanton iclanton commented Mar 15, 2026

Summary

This PR makes two related changes:

  1. Extends the Rush plugin API to allow plugins to implement native global commands without requiring a shell script. Previously, global commands always required a shellCommand — plugins had no way to run their own code directly.

  2. Adds @rushstack/rush-published-versions-json-plugin, a new Rush plugin that generates a JSON file recording the version numbers of all published packages in a monorepo. Usage: rush record-published-versions --output-path <path>. This plugin is also the first consumer of the new API, serving as a reference implementation.

Details

Rush plugin API changes (@microsoft/rush-lib):

  • New "globalPlugin" command kind: A new commandKind value for command-line.json that can only be used in plugin-provided command-line.json files. Unlike "global" commands, "globalPlugin" commands have no shellCommand or autoinstallerName — the implementation is provided entirely by the plugin's code via the runGlobalCustomCommand hook. If a repo user tries to use "globalPlugin" in the repo's command-line.json, Rush rejects it with a clear error. At runtime, "globalPlugin" is normalized to a "global" command with an empty shell command and an isPluginOnly flag (similar to how "bulk" commands are normalized to "phased").
  • Added getCustomParametersByLongName() to IGlobalCommand, giving plugin hooks access to parsed command-line parameter values (e.g. --output-path). Parameters are keyed by long name and return CommandLineParameter objects from @rushstack/ts-command-line.
  • Added setHandled() to IGlobalCommand. When a plugin hook calls this, the default shell command execution is skipped. If a "globalPlugin" command runs but no plugin calls setHandled(), Rush throws a clear error indicating the plugin is not properly handling the command.
  • Narrowed the beforeInstall hook's command type from IGlobalCommand to IRushCommand, since install/update actions were never global custom commands.

Plugin (@rushstack/rush-published-versions-json-plugin):

  • Provides a command-line.json using the new "globalPlugin" command kind for the record-published-versions command, with a required --output-path string parameter.
  • The plugin's apply() method taps runGlobalCustomCommand.for('record-published-versions'), calls command.setHandled(), then generates a JSON map of { packageName: version } for all projects with shouldPublish or a versionPolicy.

Design alternatives considered:

  • Making shellCommand optional in the JSON schema — rejected because it would let repo users accidentally omit shellCommand and get a command that silently does nothing.
  • Using shellCommand: "" with a regular "global" kind — replaced with the dedicated "globalPlugin" kind, which is more explicit, self-documenting, and restricts usage to plugins only. The schema itself acts as a version gate: if Rush is too old to understand "globalPlugin", it fails at schema validation with a clear error.

No backwards compatibility concerns — IGlobalCommand is @beta and the new members are additive. Existing global commands with a shellCommand are unaffected.

How it was tested

  • Built @microsoft/rush-lib, @rushstack/rush-sdk, and @rushstack/rush-published-versions-json-plugin with rush build — all pass cleanly with no errors or warnings.
  • Verified the API review file (rush-lib.api.md) reflects the expected surface changes (globalPluginCommandKind added to RushConstants).

Impacted documentation

iclanton and others added 10 commits March 24, 2026 17:12
Introduces a new "globalPlugin" commandKind for command-line.json that can only
be used in Rush plugin command-line.json files. Unlike "global" commands, it has
no shellCommand — the implementation must be provided entirely by the plugin via
the runGlobalCustomCommand hook with setHandled().

- Added globalPluginCommandKind constant to RushConstants
- Added globalPluginCommand to JSON schema (no shellCommand/autoinstallerName)
- Added IGlobalPluginCommandJson type; at runtime, normalized to IGlobalCommandConfig
  with shellCommand="" and isPluginOnly=true (similar to bulk→phased conversion)
- Rejected globalPlugin in repo command-line.json (loadFromFileOrDefault)
- Updated plugin command-line.json to use the new kind
- Fixed plugin .npmignore to include command-line.json

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Rename isPluginOnly → providedByPlugin for clarity per review feedback.
Also update the first changefile comment to reflect the globalPlugin design.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@iclanton iclanton force-pushed the rush-published-versions-plugin branch from 81f7d9f to c4d9d79 Compare March 24, 2026 21:13
@iclanton iclanton changed the title [rush-lib][rush-published-versions-json-plugin] Add plugin-native global commands; add published versions JSON plugin. [rush][rush-published-versions-json-plugin] Add plugin-native global commands; add published versions JSON plugin. Mar 24, 2026
@iclanton iclanton enabled auto-merge (squash) March 24, 2026 21:15
@iclanton iclanton merged commit 2dca6f2 into microsoft:main Mar 24, 2026
6 checks passed
@github-project-automation github-project-automation bot moved this from Needs triage to Closed in Bug Triage Mar 24, 2026
@iclanton iclanton deleted the rush-published-versions-plugin branch March 24, 2026 21:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Closed

Development

Successfully merging this pull request may close these issues.

3 participants