@bernierllc/non-interactive-publisher
v0.1.0
Published
Non-interactive publishing service for CI/CD and automated workflows
Readme
@bernierllc/non-interactive-publisher
A non-interactive publishing service for CI/CD and automated workflows. This service provides automated publishing capabilities for monorepo packages without user interaction.
Features
- Automated Publishing: Execute publishing workflows without user interaction
- CI/CD Integration: Designed for continuous integration and deployment pipelines
- Job Management: Create, track, and manage publishing jobs
- Queue System: Prioritized job queue with scheduling capabilities
- Parallel Execution: Support for concurrent package publishing
- Retry Logic: Automatic retry with configurable backoff
- Rollback Support: Ability to rollback failed publishes
- Notifications: Multi-channel notification system
- Metrics & Monitoring: Comprehensive publishing metrics and health checks
- Environment Support: Different configurations for dev, staging, and production
Installation
npm install @bernierllc/non-interactive-publisherUsage
Basic Usage
import { NonInteractivePublisher } from '@bernierllc/non-interactive-publisher';
const publisher = new NonInteractivePublisher({
workspacePath: '/path/to/workspace',
environment: 'production',
enableDryRun: false,
enableParallel: true,
maxConcurrency: 3
});
// Start the publisher
await publisher.start();
// Create and execute a publishing job
const job = await publisher.createJob(['package1', 'package2']);
const results = await publisher.executeJob(job.id);
// Stop the publisher
await publisher.stop();CI/CD Integration
// In your CI/CD pipeline
const publisher = new NonInteractivePublisher({
environment: 'production',
trigger: 'ci-cd',
enableDryRun: false,
enableNotifications: true,
notificationChannels: ['slack', 'email']
});
try {
await publisher.start();
// Get packages that need publishing
const packages = await getPackagesNeedingPublish();
if (packages.length > 0) {
const job = await publisher.createJob(packages);
const results = await publisher.executeJob(job.id);
// Check results
const failed = results.filter(r => r.status === 'failed');
if (failed.length > 0) {
throw new Error(`Failed to publish packages: ${failed.map(f => f.packageName).join(', ')}`);
}
}
} finally {
await publisher.stop();
}Configuration
NonInteractivePublisherConfig
interface NonInteractivePublisherConfig {
workspacePath?: string; // Workspace root directory
environment?: PublishEnvironment; // Publishing environment
trigger?: PublishTrigger; // Publishing trigger type
enableDryRun?: boolean; // Enable dry-run mode
enableParallel?: boolean; // Enable parallel execution
enableRetry?: boolean; // Enable automatic retry
enableRollback?: boolean; // Enable rollback on failure
enableNotifications?: boolean; // Enable notifications
maxConcurrency?: number; // Maximum concurrent jobs
timeoutMs?: number; // Job timeout
maxRetries?: number; // Maximum retry attempts
retryDelayMs?: number; // Retry delay
notificationChannels?: string[]; // Notification channels
logLevel?: string; // Logging level
outputFormat?: string; // Output format
}API Reference
Job Management
createJob(packages: string[], config?: NonInteractivePublisherConfig): Promise<PublishJob>getJob(jobId: string): Promise<PublishJob | null>listJobs(status?: PublishStatus, limit?: number): Promise<PublishJob[]>cancelJob(jobId: string): Promise<boolean>retryJob(jobId: string): Promise<PublishJob>
Queue Management
addToQueue(job: PublishJob, priority?: number, scheduledFor?: Date): Promise<void>getQueueStatus(): Promise<PublishQueueItem[]>clearQueue(): Promise<void>removeFromQueue(jobId: string): Promise<boolean>
Publishing Execution
executeJob(jobId: string): Promise<PublishResult[]>executePackages(packages: string[], config?: NonInteractivePublisherConfig): Promise<PublishResult[]>executeWorkflow(workflow: PublishWorkflowConfig): Promise<PublishResult[]>
Monitoring and Metrics
getMetrics(): Promise<PublishMetrics>getJobHistory(limit?: number): Promise<PublishJob[]>getPackageHistory(packageName: string, limit?: number): Promise<PublishResult[]>
Lifecycle
start(): Promise<void>stop(): Promise<void>isRunning(): booleanhealthCheck(): Promise<boolean>
Types
PublishTrigger
enum PublishTrigger {
MANUAL = 'manual',
SCHEDULED = 'scheduled',
WEBHOOK = 'webhook',
CI_CD = 'ci-cd',
DEPENDENCY_UPDATE = 'dependency-update',
VERSION_BUMP = 'version-bump'
}PublishEnvironment
enum PublishEnvironment {
DEVELOPMENT = 'development',
STAGING = 'staging',
PRODUCTION = 'production',
TESTING = 'testing'
}PublishStatus
enum PublishStatus {
PENDING = 'pending',
IN_PROGRESS = 'in-progress',
SUCCESS = 'success',
FAILED = 'failed',
CANCELLED = 'cancelled',
SKIPPED = 'skipped'
}Examples
Scheduled Publishing
const publisher = new NonInteractivePublisher({
environment: 'production',
trigger: 'scheduled',
enableParallel: true
});
// Schedule a job for later execution
const job = await publisher.createJob(['package1', 'package2']);
await publisher.addToQueue(job, 1, new Date('2024-01-01T10:00:00Z'));Webhook-Triggered Publishing
const publisher = new NonInteractivePublisher({
environment: 'staging',
trigger: 'webhook',
enableNotifications: true
});
// Handle webhook
app.post('/webhook/publish', async (req, res) => {
const { packages } = req.body;
const job = await publisher.createJob(packages);
const results = await publisher.executeJob(job.id);
res.json({ jobId: job.id, results });
});Dependency Update Publishing
const publisher = new NonInteractivePublisher({
environment: 'development',
trigger: 'dependency-update',
enableDryRun: true
});
// Publish packages with updated dependencies
const packagesWithUpdates = await getPackagesWithDependencyUpdates();
if (packagesWithUpdates.length > 0) {
const job = await publisher.createJob(packagesWithUpdates);
await publisher.executeJob(job.id);
}Testing
npm test
npm run test:watch
npm run test:coverageLicense
This package is licensed under the same terms as the parent project.
