-
Notifications
You must be signed in to change notification settings - Fork 668
[rush-lib] Abstract rush publish from npm only and introduce pluggable publish provider
#5619
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
The directory is already in .gitignore but was tracked before the rule was added.
Support single string or string array values for specifying publish targets per project (e.g., 'npm', 'vsix', 'none'). Empty arrays and non-string items are rejected by schema validation. This is the first step toward decoupling version bumping from npm-only publishing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add optional publishTarget field (string | string[]) to the raw JSON interface for rush.json project entries, enabling type-safe access to the new schema field added in the previous commit. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add private _publishTargets field and public publishTargets getter that normalizes the raw publishTarget value from rush.json: omitted defaults to ['npm'], a string is wrapped in an array, and arrays are preserved as-is. Updates tests to verify normalization behavior. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add three constructor validations for publishTarget: - "none" cannot be combined with other targets (e.g. ["npm", "none"]) - "none" is incompatible with lockstep version policies - Relax private:true check to only throw when targets include "npm", allowing private packages to publish as VSIX or other non-npm targets Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Cover lockstep version policy + 'none' rejection, individual version policy + 'none' acceptance, and shouldPublish + private + npm rejection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add IPublishProjectInfo, IPublishProviderPublishOptions, IPublishProviderCheckExistsOptions, IPublishProvider, and PublishProviderFactory types following existing provider patterns. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add exports for IPublishProvider, IPublishProjectInfo, IPublishProviderPublishOptions, IPublishProviderCheckExistsOptions, and PublishProviderFactory from rush-lib barrel exports. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add _publishProviderFactories Map, registerPublishProviderFactory() with duplicate detection, and getPublishProviderFactory() getter following existing cloud build cache provider pattern. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Test register/retrieve, duplicate detection, unregistered returns undefined, and multiple target registration on RushSession. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add JSON schema with providers object property where keys are publish target names and values are provider-specific configuration objects. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Create PublishConfiguration.ts with IPublishJson interface and PUBLISH_CONFIGURATION_FILE ProjectConfigurationFile instance that supports rig resolution with custom provider inheritance merge. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Test project-only config, missing config returns undefined, rig-only config loading, and project+rig merge behavior with test fixtures. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add rush-npm-publish-plugin with package.json, rush-plugin-manifest, tsconfig, rig config, plugin entry point, and stub NpmPublishProvider. Register in rush.json with rush lockstep version policy. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add NpmPublishProvider class implementing IPublishProvider with publishAsync and checkExistsAsync methods. Handles registry URL configuration, auth tokens, .npmrc-publish home directory, pnpm --no-git-checks flag, and dry-run mode. Add semver dependency. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add @rushstack/rush-npm-publish-plugin to rush-lib's publishOnlyDependencies, PluginManager tryAddBuiltInPlugin calls, start-dev.ts dev-time loading, and plugins-prepublish.js transform. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
14 tests covering publishAsync (pnpm/yarn/npm args, tags, dry-run, registry URL, auth token, access level, error handling), checkExistsAsync (version exists, not found, spawn failure, build metadata normalization, single version response), and .npmrc-publish HOME env handling. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add _loadPublishConfigAsync method with caching that loads config/publish.json via PUBLISH_CONFIGURATION_FILE with rig resolution for each project. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace hardcoded npm publish logic with provider-based dispatch. Projects are now grouped by publishTargets, and each target's registered provider handles publishing and exists checks. CLI flags (--registry, --npm-auth-token, --set-access-level) are passed as providerConfig overrides for the npm target. 'none' targets are skipped. Missing provider registrations throw descriptive errors. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add rush-vscode-publish-plugin with VsixPublishProvider that publishes VSIX packages to VS Code Marketplace via vsce CLI. Supports configurable vsixPathPattern and useAzureCredential options. Registered as built-in plugin alongside rush-npm-publish-plugin. Includes 7 unit tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add IPublishCommand interface and two new AsyncSeriesHook instances to RushLifecycleHooks. Plugins can tap these hooks for setup/auth before publishing and cleanup/reporting after publishing completes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add shouldPublish and publishTarget: ["vsix"] to the 4 VS Code extension projects so they participate in rush publish via the VSIX publish provider. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add tests that validate the 4 VS Code extension projects in rush.json are correctly configured with shouldPublish: true and publishTarget: ["vsix"], and that vscode-shared remains unpublished. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…for VSIX Add tests verifying VS Code extensions use individual versioning (no lockstep policy) and only target the 'vsix' publish provider, ensuring correct dispatch through the publish pipeline. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
rush publish rush version and rush publish and introduce pluggable publish provider
|
We discussed this today: 💬 Community call: Rush publish provider design review. I attached some meeting notes. |
rush version and rush publish and introduce pluggable publish providerrush publish from npm only and introduce pluggable publish provider
I've implemented the design requirements we've agreed on here. Pack is now implemented and npm/vsix packing has been moved into their respective publishprovider (without removing the existing heft-vsix plugins today to preserve back-compat). |
|
@iclanton What is the typical workflow for working around the CI errors that Should we just remove |
Addresses #5504
Architecture
The design follows the existing factory registration pattern from build cache plugins. Key components:
publishTargetfield inrush.json-- Per-project string or array (e.g.,"vsix",["npm", "vsix"]). Defaults to["npm"]when omitted for full backward compatibility. Special value"none"enables version-only mode. Validation enforces that"none"cannot be combined with other targets and thatprivate: truepackages cannot target"npm".IPublishProviderinterface -- Contract for publish plugins withpublishAsync(),packAsync(), andcheckExistsAsync()methods. Exported from the public API (as@beta) to enable third-party plugins.RushSessionregistration --registerPublishProviderFactory(targetName, factory)/getPublishProviderFactory(targetName)for lazy provider instantiation, following theregisterCloudBuildCacheProviderFactorypattern.Riggable
config/publish.json-- Per-project configuration loaded viaProjectConfigurationFilewith rig resolution. Provider-specific config sections (keyed by target name) are passed to providers viaIPublishProjectInfo.providerConfig.PublishActionrefactor -- The action becomes an orchestrator: loads per-project publish config, groups projects by target, and dispatches to registered providers. npm-specific CLI flags (--registry,--npm-auth-token,--set-access-level) are merged into the npm provider's config at runtime. The--packflag now dispatches through providerpackAsync()methods instead of hardcoding npm pack logic.rush-npm-publish-plugin-- Built-in plugin (registered byPluginManager) that extracts the existing npm publish logic fromPublishAction. ImplementspackAsync()to run<packageManager> packand move tarballs to the release folder. Zero configuration required for existing projects.rush-vscode-publish-plugin-- New plugin that publishes VSIX files viavsce publish --azure-credential. ImplementspackAsync()to runvsce package --no-dependenciesand produce.vsixartifacts. ReadsvsixPathPatternanduseAzureCredentialfromconfig/publish.json.Lifecycle hooks --
beforePublishandafterPublishhooks onRushLifecycleHooksfor cross-cutting concerns (auth setup, telemetry).VS Code extension enablement -- The 4 VS Code extensions in
rush.jsongainshouldPublish: trueandpublishTarget: "vsix", enabling them to userush change,rush version --bump, andrush publish.Backward compatibility
All existing
shouldPublish: trueprojects continue to work without any configuration changes --publishTargetdefaults to["npm"], and the npm publish plugin is always built-in.Recent changes
packAsync()to theIPublishProviderinterface with a newIPublishProviderPackOptionstype, so each provider defines what "packing" means for its artifact typePublishAction's--packflag to dispatch through providers (_packProjectViaProvidersAsync) instead of the old npm-hardcoded_npmPackAsyncpackAsync()inNpmPublishProvider(runs<packageManager> pack, moves tarball to release folder) andVsixPublishProvider(runsvsce package --no-dependencies --out <path>)@publicto@betarelease tagChangeTypeandIPublishProviderPackOptionsfrom the public APIHow it was tested
publishTargetvalidation inRushConfigurationProject(string normalization, array handling,"none"validation,private: trueinteraction)RushSessionpublish provider factory registration (register, retrieve, duplicate rejection)config/publish.jsonloading (project-only, rig-only, merged, missing file)NpmPublishProvider(publish flow, pack flow, check-exists, dry-run, config merging,.npmrc-publishhandling)VsixPublishProvider(publish flow, pack flow, dry-run, config defaults, check-exists always returns false)RushLifecycleHooks(beforePublish/afterPublishhook invocation)publishTargetconfiguration and version bump eligibilityImpacted documentation
publishTargetfield documentation)rush publishdispatch behavior,--packflag)publishTarget: "none")