@bernierllc/publish-orchestrator
v0.9.0
Published
Orchestrate publishing workflows for monorepo packages
Downloads
814
Readme
@bernierllc/publish-orchestrator
A service package that orchestrates complete publishing workflows for monorepo packages using core packages for package analysis, validation, changeset management, and workspace management.
Features
- Complete Workflow Orchestration: Coordinates the entire publishing process from workspace analysis to package publication
- Multiple Publishing Modes: Supports interactive, non-interactive, batch, and automatic publishing modes
- Smart Package Selection: Multiple strategies for selecting packages to publish (manual, recent, modified, all, category-based)
- Concurrent Publishing: Configurable concurrency control for publishing multiple packages
- Workflow State Management: Track and manage publishing workflows with unique IDs
- Error Recovery: Comprehensive error handling with rollback capabilities
- Dry Run Support: Test publishing workflows without actually publishing
- Real-time Progress Tracking: Monitor workflow execution with detailed step results
Installation
npm install @bernierllc/publish-orchestratorQuick Start
import { PublishOrchestrator, PublishMode, SelectionStrategy } from '@bernierllc/publish-orchestrator';
// Create orchestrator instance
const orchestrator = new PublishOrchestrator({
workspacePath: '/path/to/workspace',
maxConcurrentPublishes: 3
});
// Analyze what can be published
const analysis = await orchestrator.analyzeWorkflow({
mode: PublishMode.INTERACTIVE,
selectionStrategy: SelectionStrategy.RECENT
});
console.log(`Can publish: ${analysis.canPublish}`);
console.log(`Packages to publish: ${analysis.packagesToPublish.length}`);
console.log(`Recommendations: ${analysis.recommendations.join(', ')}`);
// Execute publishing workflow
const result = await orchestrator.executeWorkflow({
mode: PublishMode.NON_INTERACTIVE,
selectionStrategy: SelectionStrategy.MANUAL,
packages: ['@myorg/package-1', '@myorg/package-2'],
versionBump: 'patch',
message: 'Bug fixes and improvements'
});
console.log(`Success: ${result.success}`);
console.log(`Published: ${result.publishedPackages.join(', ')}`);
console.log(`Duration: ${result.duration}ms`);API Reference
PublishOrchestrator
The main orchestrator class that coordinates publishing workflows.
Constructor
new PublishOrchestrator(options?: PublishOrchestratorOptions)Options:
workspacePath?: string- Path to the workspace root (default:process.cwd())configPath?: string- Path to configuration filelogLevel?: 'debug' | 'info' | 'warn' | 'error'- Logging level (default:'info')maxConcurrentPublishes?: number- Maximum concurrent package publishes (default:3)timeoutMs?: number- Workflow timeout in milliseconds (default:300000)retryAttempts?: number- Number of retry attempts (default:3)retryDelayMs?: number- Delay between retries in milliseconds (default:1000)
Methods
analyzeWorkflow(config)
Analyze a publishing workflow to determine what can be published.
async analyzeWorkflow(config: PublishWorkflowConfig): Promise<WorkflowAnalysis>Returns:
canPublish: boolean- Whether any packages can be publishedpackagesToPublish: PackageInfo[]- Packages ready for publishingpackagesToSkip: PackageInfo[]- Packages that should be skippedvalidationIssues: ValidationResult[]- Validation problems foundworkspaceIssues: string[]- Workspace configuration issuesrecommendations: string[]- Recommendations for the workflowestimatedDuration: number- Estimated workflow duration in milliseconds
executeWorkflow(config)
Execute a complete publishing workflow.
async executeWorkflow(config: PublishWorkflowConfig): Promise<PublishWorkflowResult>Returns:
success: boolean- Whether the workflow completed successfullyworkflowId: string- Unique workflow identifierpublishedPackages: string[]- Successfully published package namesfailedPackages: string[]- Failed package namesskippedPackages: string[]- Skipped package nameschangesets: ChangesetInfo[]- Created changesetsduration: number- Total workflow duration in millisecondserrors: Error[]- Errors encountered during executionwarnings: string[]- Warnings generated during execution
validateWorkflow(config)
Validate a publishing workflow configuration.
async validateWorkflow(config: PublishWorkflowConfig): Promise<ValidationResult[]>rollbackWorkflow(workflowId)
Generate rollback information for a failed workflow.
async rollbackWorkflow(workflowId: string): Promise<RollbackInfo>getWorkflowStatus(workflowId)
Get the current status of a workflow.
async getWorkflowStatus(workflowId: string): Promise<PublishWorkflowState | null>cancelWorkflow(workflowId)
Cancel a running workflow.
async cancelWorkflow(workflowId: string): Promise<boolean>Configuration Types
PublishWorkflowConfig
interface PublishWorkflowConfig {
mode: PublishMode;
selectionStrategy: SelectionStrategy;
packages?: string[];
categories?: string[];
versionBump?: 'major' | 'minor' | 'patch';
message?: string;
dryRun?: boolean;
force?: boolean;
skipValidation?: boolean;
skipTests?: boolean;
interactive?: boolean;
}PublishMode
enum PublishMode {
INTERACTIVE = 'interactive',
NON_INTERACTIVE = 'non_interactive',
BATCH = 'batch',
AUTO = 'auto'
}SelectionStrategy
enum SelectionStrategy {
MANUAL = 'manual',
RECENT = 'recent',
MODIFIED = 'modified',
ALL = 'all',
CATEGORY = 'category'
}Publishing Modes
Interactive Mode
User-guided publishing with prompts and confirmations.
const config = {
mode: PublishMode.INTERACTIVE,
selectionStrategy: SelectionStrategy.ALL
};Non-Interactive Mode
Automated publishing without user prompts.
const config = {
mode: PublishMode.NON_INTERACTIVE,
selectionStrategy: SelectionStrategy.MANUAL,
packages: ['@myorg/package-1'],
versionBump: 'patch',
message: 'Automated release'
};Batch Mode
Publish multiple packages in a single workflow.
const config = {
mode: PublishMode.BATCH,
selectionStrategy: SelectionStrategy.CATEGORY,
categories: ['core', 'service'],
versionBump: 'minor'
};Auto Mode
Fully automated publishing based on changes.
const config = {
mode: PublishMode.AUTO,
selectionStrategy: SelectionStrategy.MODIFIED
};Package Selection Strategies
Manual Selection
Specify exact packages to publish.
const config = {
selectionStrategy: SelectionStrategy.MANUAL,
packages: ['@myorg/package-1', '@myorg/package-2']
};Recent Selection
Publish recently modified packages.
const config = {
selectionStrategy: SelectionStrategy.RECENT
};Modified Selection
Publish packages with uncommitted changes.
const config = {
selectionStrategy: SelectionStrategy.MODIFIED
};All Selection
Publish all packages in the workspace.
const config = {
selectionStrategy: SelectionStrategy.ALL
};Category Selection
Publish packages by category.
const config = {
selectionStrategy: SelectionStrategy.CATEGORY,
categories: ['core', 'service', 'ui']
};Workflow Steps
The orchestrator executes the following steps in sequence:
- Analyze Workspace - Detect and validate workspace configuration
- Validate Packages - Check package structure and configuration
- Select Packages - Choose packages based on selection strategy
- Create Changesets - Generate changesets for selected packages
- Validate Changesets - Verify changeset format and content
- Publish Packages - Execute actual publishing via changeset CLI
- Verify Publish - Confirm successful publication
- Cleanup - Remove temporary files and resources
Error Handling
The orchestrator provides comprehensive error handling:
- Step-level errors are captured and logged
- Workflow failures trigger automatic rollback procedures
- Partial failures allow for selective package publishing
- Retry mechanisms handle transient failures
- Detailed error reporting includes context and recommendations
Examples
Basic Publishing
import { PublishOrchestrator, PublishMode, SelectionStrategy } from '@bernierllc/publish-orchestrator';
const orchestrator = new PublishOrchestrator();
// Simple publish of all packages
const result = await orchestrator.executeWorkflow({
mode: PublishMode.NON_INTERACTIVE,
selectionStrategy: SelectionStrategy.ALL,
versionBump: 'patch'
});
if (result.success) {
console.log(`Published ${result.publishedPackages.length} packages`);
} else {
console.error('Publishing failed:', result.errors);
}Dry Run Testing
// Test publishing workflow without actually publishing
const analysis = await orchestrator.analyzeWorkflow({
mode: PublishMode.INTERACTIVE,
selectionStrategy: SelectionStrategy.RECENT
});
if (analysis.canPublish) {
const result = await orchestrator.executeWorkflow({
mode: PublishMode.NON_INTERACTIVE,
selectionStrategy: SelectionStrategy.RECENT,
dryRun: true,
versionBump: 'minor'
});
console.log('Dry run completed:', result);
}Workflow Monitoring
// Start a workflow and monitor its progress
const workflowPromise = orchestrator.executeWorkflow({
mode: PublishMode.BATCH,
selectionStrategy: SelectionStrategy.CATEGORY,
categories: ['core']
});
// Monitor workflow status
const checkStatus = async () => {
const status = await orchestrator.getWorkflowStatus(workflowId);
if (status) {
console.log(`Workflow ${status.status}: ${status.stepResults.length} steps completed`);
}
};
// Check status every 5 seconds
const interval = setInterval(checkStatus, 5000);
// Wait for completion
const result = await workflowPromise;
clearInterval(interval);
console.log('Workflow completed:', result);Error Recovery
try {
const result = await orchestrator.executeWorkflow(config);
if (!result.success) {
// Generate rollback information
const rollbackInfo = await orchestrator.rollbackWorkflow(result.workflowId);
console.log('Rollback commands:');
rollbackInfo.gitCommands.forEach(cmd => console.log(` ${cmd}`));
console.log('Manual steps:');
rollbackInfo.manualSteps.forEach(step => console.log(` - ${step}`));
}
} catch (error) {
console.error('Workflow execution failed:', error);
}Integration with Core Packages
The publish orchestrator integrates with the following core packages:
- @bernierllc/package-analyzer - Package discovery and analysis
- @bernierllc/package-validator - Package structure validation
- @bernierllc/changeset-manager - Changeset creation and management
- @bernierllc/workspace-manager - Workspace detection and configuration
Testing
# Run tests
npm test
# Run tests with coverage
npm run test:coverage
# Run tests in watch mode
npm run test:watchContributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
License
This package is licensed under the same terms as the parent project. See the LICENSE file for details.
