Non-interactive publishing service for CI/CD and automated workflows
npm install @bernierllc/non-interactive-publisherA non-interactive publishing service for CI/CD and automated workflows. This service provides automated publishing capabilities for monorepo packages without user interaction.
- 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
``bash`
npm install @bernierllc/non-interactive-publisher
`typescript
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();
`
`typescript
// 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();
}
`typescript`
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
}
- createJob(packages: string[], config?: NonInteractivePublisherConfig): PromisegetJob(jobId: string): Promise
- listJobs(status?: PublishStatus, limit?: number): Promise
- cancelJob(jobId: string): Promise
- retryJob(jobId: string): Promise
-
- addToQueue(job: PublishJob, priority?: number, scheduledFor?: Date): PromisegetQueueStatus(): Promise
- clearQueue(): Promise
- removeFromQueue(jobId: string): Promise
-
- executeJob(jobId: string): PromiseexecutePackages(packages: string[], config?: NonInteractivePublisherConfig): Promise
- executeWorkflow(workflow: PublishWorkflowConfig): Promise
-
- getMetrics(): PromisegetJobHistory(limit?: number): Promise
- getPackageHistory(packageName: string, limit?: number): Promise
-
- start(): Promisestop(): Promise
- isRunning(): boolean
- healthCheck(): Promise
-
`typescript`
enum PublishTrigger {
MANUAL = 'manual',
SCHEDULED = 'scheduled',
WEBHOOK = 'webhook',
CI_CD = 'ci-cd',
DEPENDENCY_UPDATE = 'dependency-update',
VERSION_BUMP = 'version-bump'
}
`typescript`
enum PublishEnvironment {
DEVELOPMENT = 'development',
STAGING = 'staging',
PRODUCTION = 'production',
TESTING = 'testing'
}
`typescript`
enum PublishStatus {
PENDING = 'pending',
IN_PROGRESS = 'in-progress',
SUCCESS = 'success',
FAILED = 'failed',
CANCELLED = 'cancelled',
SKIPPED = 'skipped'
}
`typescript
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'));
`
`typescript
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 });
});
`
`typescript
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);
}
`
`bash``
npm test
npm run test:watch
npm run test:coverage
This package is licensed under the same terms as the parent project.