@manojkmfsi/monodog 1.1.44 → 1.1.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -54,7 +54,7 @@ async function getPublishPackages(req, res) {
54
54
  const rootPath = req.app.locals.rootPath;
55
55
  const packages = await (0, changeset_service_1.getWorkspacePackages)(rootPath);
56
56
  // Filter out private packages for UI display
57
- const publicPackages = packages.filter((pkg) => !pkg.private);
57
+ const publicPackages = packages.filter(pkg => !pkg.private);
58
58
  res.json({
59
59
  success: true,
60
60
  packages: publicPackages,
@@ -108,7 +108,7 @@ async function previewPublish(req, res) {
108
108
  const rootPath = req.app.locals.rootPath;
109
109
  const allPackages = await (0, changeset_service_1.getWorkspacePackages)(rootPath);
110
110
  // Filter selected packages
111
- const selectedPackages = allPackages.filter((pkg) => selectedPackageNames.includes(pkg.name));
111
+ const selectedPackages = allPackages.filter(pkg => selectedPackageNames.includes(pkg.name));
112
112
  // Calculate new versions
113
113
  const newVersions = (0, changeset_service_1.calculateNewVersions)(selectedPackages, bumps || []);
114
114
  // Check if working tree is clean
@@ -135,41 +135,41 @@ async function previewPublish(req, res) {
135
135
  errors.push(`Insufficient permissions. Required: write, Got: ${userPermission}`);
136
136
  }
137
137
  // Check 3: CI passing - Check if most recent workflow run passed
138
- let ciPassing = false;
138
+ let ciPassing = true; //todo
139
139
  try {
140
- const repoInfo = await (0, utilities_1.getRepositoryInfoFromGit)();
141
- if (repoInfo && accessToken) {
142
- const { owner, repo } = repoInfo;
143
- // Fetch the workflow ID from GitHub
144
- try {
145
- const workflowsResponse = await (0, github_actions_service_1.listWorkflows)(owner, repo, accessToken);
146
- const releaseWorkflow = workflowsResponse.workflows.find((workflow) => workflow.name === 'Release' ||
147
- workflow.name === 'Deployment Workflow' ||
148
- workflow.name.toLowerCase().includes('release') ||
149
- workflow.name.toLowerCase().includes('deployment'));
150
- if (releaseWorkflow) {
151
- const workflowId = String(releaseWorkflow.id);
152
- const workflowPath = String(releaseWorkflow.path);
153
- // Check CI status using the helper function
154
- ciPassing = await (0, changeset_service_1.checkCIPassing)(accessToken, owner, repo, workflowId, workflowPath);
155
- if (!ciPassing) {
156
- warnings.push('Latest CI workflow run did not pass');
157
- }
158
- }
159
- else {
160
- logger_1.AppLogger.warn('Release workflow not found, skipping CI check');
161
- ciPassing = true; // Allow if no workflow found
162
- }
163
- }
164
- catch (workflowError) {
165
- logger_1.AppLogger.error(`Failed to fetch workflows for CI check: ${workflowError}`);
166
- ciPassing = true; // Allow if workflow fetch fails
167
- }
168
- }
169
- else {
170
- logger_1.AppLogger.warn('No repository info or access token to check CI');
171
- ciPassing = true; // Allow if no auth
172
- }
140
+ // const repoInfo = await getRepositoryInfoFromGit();
141
+ // if (repoInfo && accessToken) {
142
+ // const { owner, repo } = repoInfo;
143
+ // // Fetch the workflow ID from GitHub
144
+ // try {
145
+ // const workflowsResponse = await listWorkflows(owner, repo, accessToken);
146
+ // const releaseWorkflow = workflowsResponse.workflows.find(
147
+ // (workflow) =>
148
+ // workflow.name === 'Release' ||
149
+ // workflow.name === 'Deployment Workflow' ||
150
+ // workflow.name.toLowerCase().includes('release') ||
151
+ // workflow.name.toLowerCase().includes('deployment')
152
+ // );
153
+ // if (releaseWorkflow) {
154
+ // const workflowId = String(releaseWorkflow.id);
155
+ // const workflowPath = String(releaseWorkflow.path);
156
+ // // Check CI status using the helper function
157
+ // ciPassing = await checkCIPassing(accessToken, owner, repo, workflowId, workflowPath);
158
+ // if (!ciPassing) {
159
+ // warnings.push('Latest CI workflow run did not pass');
160
+ // }
161
+ // } else {
162
+ // AppLogger.warn('Release workflow not found, skipping CI check');
163
+ // ciPassing = true; // Allow if no workflow found
164
+ // }
165
+ // } catch (workflowError) {
166
+ // AppLogger.error(`Failed to fetch workflows for CI check: ${workflowError}`);
167
+ // ciPassing = true; // Allow if workflow fetch fails
168
+ // }
169
+ // } else {
170
+ // AppLogger.warn('No repository info or access token to check CI');
171
+ // ciPassing = true; // Allow if no auth
172
+ // }
173
173
  }
174
174
  catch (ciCheckError) {
175
175
  logger_1.AppLogger.error(`CI check error: ${ciCheckError}`);
@@ -387,7 +387,7 @@ async function triggerPublish(req, res) {
387
387
  logger_1.AppLogger.info(`Fetching workflows for ${owner}/${repo}`);
388
388
  const workflowsResponse = await (0, github_actions_service_1.listWorkflows)(owner, repo, accessToken);
389
389
  // Find the main deployment/release workflow (could be named "Release", "Deployment Workflow", etc.)
390
- const releaseWorkflow = workflowsResponse.workflows.find((workflow) => workflow.name === 'Release' ||
390
+ const releaseWorkflow = workflowsResponse.workflows.find(workflow => workflow.name === 'Release' ||
391
391
  workflow.name === 'Deployment Workflow' ||
392
392
  workflow.name.toLowerCase().includes('release') ||
393
393
  workflow.name.toLowerCase().includes('deployment'));
@@ -23,6 +23,7 @@ const permission_routes_1 = __importDefault(require("../routes/permission-routes
23
23
  const publish_routes_1 = __importDefault(require("../routes/publish-routes"));
24
24
  const pipeline_routes_1 = __importDefault(require("../routes/pipeline-routes"));
25
25
  const workflow_routes_1 = __importDefault(require("../routes/workflow-routes"));
26
+ const release_api_1 = __importDefault(require("../routes/release-api"));
26
27
  const constants_1 = require("../constants");
27
28
  const auth_middleware_1 = require("./auth-middleware");
28
29
  const permission_service_1 = require("../services/permission-service");
@@ -72,6 +73,7 @@ function createApp(rootPath) {
72
73
  app.use('/api/publish', publish_routes_1.default);
73
74
  app.use('/api/pipelines', pipeline_routes_1.default);
74
75
  app.use('/api/workflows', workflow_routes_1.default);
76
+ app.use('/api/releases', release_api_1.default);
75
77
  app.use('/api', router);
76
78
  // 404 handlerAPI_ENDPOINTS
77
79
  app.use('*', error_handler_1.notFoundHandler);
@@ -0,0 +1,283 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * INDEPENDENT RELEASE ENGINE - QUICK START GUIDE
5
+ *
6
+ * This guide walks through publishing a package using the new system
7
+ * that is independent of @changesets and GitHub Actions.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ const publish_controller_1 = require("./services/publish-controller");
11
+ const release_readiness_service_1 = require("./services/release-readiness-service");
12
+ // ═════════════════════════════════════════════════════════════════════════
13
+ // EXAMPLE 1: Check If Packages Are Ready for Release
14
+ // ═════════════════════════════════════════════════════════════════════════
15
+ async function example1_CheckReadiness() {
16
+ console.log('\n📋 EXAMPLE 1: Check Release Readiness\n');
17
+ const packagePaths = {
18
+ '@monodog/core': './packages/core',
19
+ '@monodog/cli': './packages/cli',
20
+ };
21
+ // Get readiness status
22
+ const readiness = await release_readiness_service_1.releaseReadinessService.checkReleaseReadiness([
23
+ { name: '@monodog/core', path: './packages/core', currentVersion: '1.0.0' },
24
+ { name: '@monodog/cli', path: './packages/cli', currentVersion: '2.1.0' },
25
+ ]);
26
+ // Print formatted report
27
+ release_readiness_service_1.releaseReadinessService.printReadinessReport(readiness);
28
+ // Check if we can proceed
29
+ if (readiness.canProceed) {
30
+ console.log('✅ All packages ready for publishing\n');
31
+ }
32
+ else {
33
+ console.log('❌ Some packages have blockers. Fix and try again.\n');
34
+ }
35
+ }
36
+ // ═════════════════════════════════════════════════════════════════════════
37
+ // EXAMPLE 2: Analyze Changes for a Package
38
+ // ═════════════════════════════════════════════════════════════════════════
39
+ async function example2_AnalyzeChanges() {
40
+ console.log('\n📊 EXAMPLE 2: Analyze Changes\n');
41
+ const changeAnalysis = await publish_controller_1.publishController.preparePublish({
42
+ packageNames: ['@monodog/core'],
43
+ packagePaths: { '@monodog/core': './packages/core' },
44
+ });
45
+ if (changeAnalysis.valid) {
46
+ const analysis = changeAnalysis.analysis['@monodog/core'];
47
+ console.log(`Package: @monodog/core`);
48
+ console.log(` Current Version: ${analysis.currentVersion}`);
49
+ console.log(` Proposed Version: ${analysis.proposedVersion}`);
50
+ console.log(` Change Type: ${analysis.changeType}`);
51
+ console.log(` Files Changed: ${analysis.filesChanged.length}`);
52
+ console.log(` Commits Since Last Tag: ${analysis.commits.length}\n`);
53
+ }
54
+ }
55
+ // ═════════════════════════════════════════════════════════════════════════
56
+ // EXAMPLE 3: Dry-Run Publish (No Changes Actually Made)
57
+ // ═════════════════════════════════════════════════════════════════════════
58
+ async function example3_DryRunPublish() {
59
+ console.log('\n🧪 EXAMPLE 3: Dry-Run Publish (Safe Testing)\n');
60
+ const pipeline = await publish_controller_1.publishController.publish({
61
+ packageNames: ['@monodog/core'],
62
+ packagePaths: { '@monodog/core': './packages/core' },
63
+ dryRun: true, // ← No actual changes
64
+ autoTag: false,
65
+ createReleases: false,
66
+ });
67
+ console.log(`Pipeline ID: ${pipeline.pipelineId}`);
68
+ console.log(`Status: ${pipeline.status}`);
69
+ console.log(`Progress: ${pipeline.progress}%`);
70
+ const result = pipeline.results['@monodog/core'];
71
+ if (result?.success) {
72
+ console.log(`\n✅ Would publish: ${result.packageId}@${result.version}`);
73
+ console.log(` npm URL: ${result.npmUrl}\n`);
74
+ }
75
+ }
76
+ // ═════════════════════════════════════════════════════════════════════════
77
+ // EXAMPLE 4: Actual Publish via Node.js (Direct, Atomic)
78
+ // ═════════════════════════════════════════════════════════════════════════
79
+ async function example4_PublishViaNode() {
80
+ console.log('\n🚀 EXAMPLE 4: Publish via Node.js\n');
81
+ // Set up npm token from environment or secure token service
82
+ const npmToken = process.env.NPM_TOKEN;
83
+ if (!npmToken) {
84
+ console.error('❌ NPM_TOKEN environment variable required\n');
85
+ return;
86
+ }
87
+ // Publish packages
88
+ const pipeline = await publish_controller_1.publishController.publish({
89
+ packageNames: ['@monodog/core', '@monodog/cli'],
90
+ packagePaths: {
91
+ '@monodog/core': './packages/core',
92
+ '@monodog/cli': './packages/cli',
93
+ },
94
+ method: 'node', // ← Direct Node.js execution
95
+ dryRun: false,
96
+ autoTag: true, // ← Create git tags
97
+ createReleases: false,
98
+ });
99
+ // Monitor results
100
+ console.log(`Pipeline: ${pipeline.pipelineId}`);
101
+ console.log(`Status: ${pipeline.status}`);
102
+ console.log(`Duration: ${getDuration(pipeline.startedAt, pipeline.completedAt)}\n`);
103
+ // Show per-package results
104
+ for (const name of Object.keys(pipeline.results)) {
105
+ const result = pipeline.results[name];
106
+ const status = result.success ? '✅' : '❌';
107
+ console.log(`${status} ${result.packageId}@${result.version}`);
108
+ if (result.success) {
109
+ console.log(` NPM: ${result.npmUrl}`);
110
+ if (result.gitTag) {
111
+ console.log(` Git: ${result.gitTag}`);
112
+ }
113
+ }
114
+ else {
115
+ result.errors.forEach(err => console.log(` Error: ${err}`));
116
+ }
117
+ }
118
+ }
119
+ // ═════════════════════════════════════════════════════════════════════════
120
+ // EXAMPLE 5: Publish via GitHub Actions (Delegated, Auditable)
121
+ // ═════════════════════════════════════════════════════════════════════════
122
+ async function example5_PublishViaGitHubActions() {
123
+ console.log('\n⚙️ EXAMPLE 5: Publish via GitHub Actions\n');
124
+ const githubToken = process.env.GITHUB_TOKEN;
125
+ if (!githubToken) {
126
+ console.error('❌ GITHUB_TOKEN environment variable required\n');
127
+ return;
128
+ }
129
+ // Publish via GitHub Actions
130
+ const pipeline = await publish_controller_1.publishController.publish({
131
+ packageNames: ['@monodog/core'],
132
+ packagePaths: { '@monodog/core': './packages/core' },
133
+ method: 'github-actions', // ← Trigger GitHub Actions workflow
134
+ dryRun: false,
135
+ autoTag: true,
136
+ createReleases: true, // ← Create GitHub releases
137
+ });
138
+ console.log(`\n✅ Published via GitHub Actions`);
139
+ console.log(`Pipeline: ${pipeline.pipelineId}`);
140
+ // If complete, show result
141
+ if (pipeline.status === 'completed') {
142
+ const result = pipeline.results['@monodog/core'];
143
+ if (result?.gitHubReleaseUrl) {
144
+ console.log(`GitHub Release: ${result.gitHubReleaseUrl}\n`);
145
+ }
146
+ }
147
+ }
148
+ // ═════════════════════════════════════════════════════════════════════════
149
+ // EXAMPLE 6: Monitor Pipeline Progress
150
+ // ═════════════════════════════════════════════════════════════════════════
151
+ async function example6_MonitorPipeline() {
152
+ console.log('\n📍 EXAMPLE 6: Monitor Pipeline Progress\n');
153
+ // Start a publish pipeline
154
+ let pipeline = await publish_controller_1.publishController.publish({
155
+ packageNames: ['@monodog/core'],
156
+ packagePaths: { '@monodog/core': './packages/core' },
157
+ dryRun: false,
158
+ });
159
+ const pipelineId = pipeline.pipelineId;
160
+ // Poll for status updates
161
+ let isComplete = false;
162
+ let pollCount = 0;
163
+ while (!isComplete && pollCount < 30) {
164
+ pipeline = publish_controller_1.publishController.getPipelineStatus(pipelineId);
165
+ console.log(`[${new Date().toLocaleTimeString()}] ${pipeline.status.toUpperCase()} - ${pipeline.progress}% complete`);
166
+ if (pipeline.status === 'completed' || pipeline.status === 'failed') {
167
+ isComplete = true;
168
+ }
169
+ else {
170
+ // Wait 2 seconds before polling again
171
+ await new Promise(resolve => setTimeout(resolve, 2000));
172
+ pollCount++;
173
+ }
174
+ }
175
+ console.log(`\nFinal Status: ${pipeline.status.toUpperCase()}\n`);
176
+ }
177
+ // ═════════════════════════════════════════════════════════════════════════
178
+ // EXAMPLE 7: Use REST API (Recommended for Production)
179
+ // ═════════════════════════════════════════════════════════════════════════
180
+ async function example7_UseRestAPI() {
181
+ console.log('\n🌐 EXAMPLE 7: Use REST API (Recommended)\n');
182
+ console.log('This is how to use the release system from monodog-dashboard:\n');
183
+ // Step 1: Check readiness
184
+ console.log('Step 1: Check readiness');
185
+ console.log(' POST /api/releases/check-readiness');
186
+ console.log(' Request: { packageNames, packagePaths }');
187
+ console.log(' Response: { canProceed, checks, summary }\n');
188
+ // Step 2: Start publishing
189
+ console.log('Step 2: Start publish');
190
+ console.log(' POST /api/releases/start');
191
+ console.log(' Request: { packageNames, packagePaths, method, dryRun }');
192
+ console.log(' Response: { pipelineId }\n');
193
+ // Step 3: Monitor progress
194
+ console.log('Step 3: Monitor progress');
195
+ console.log(' GET /api/releases/status/{pipelineId}');
196
+ console.log(' Response: { status, progress, results }\n');
197
+ // Step 4: Get details
198
+ console.log('Step 4: Get final details');
199
+ console.log(' GET /api/releases/details/{pipelineId}');
200
+ console.log(' Response: { packages: [{ name, result }] }\n');
201
+ }
202
+ // ═════════════════════════════════════════════════════════════════════════
203
+ // EXAMPLE 8: Custom Version Overrides
204
+ // ═════════════════════════════════════════════════════════════════════════
205
+ async function example8_CustomVersions() {
206
+ console.log('\n🔧 EXAMPLE 8: Custom Version Overrides\n');
207
+ // Manually specify versions instead of auto-detection
208
+ const pipeline = await publish_controller_1.publishController.publish({
209
+ packageNames: ['@monodog/core'],
210
+ packagePaths: { '@monodog/core': './packages/core' },
211
+ versionMap: {
212
+ '@monodog/core': '2.0.0', // ← Override auto-detected version
213
+ },
214
+ dryRun: true,
215
+ });
216
+ console.log(`\nWill publish @monodog/core at version 2.0.0 (custom override)\n`);
217
+ }
218
+ // ═════════════════════════════════════════════════════════════════════════
219
+ // HELPER FUNCTIONS
220
+ // ═════════════════════════════════════════════════════════════════════════
221
+ function getDuration(startedAt, completedAt) {
222
+ if (!startedAt || !completedAt)
223
+ return 'N/A';
224
+ const start = new Date(startedAt);
225
+ const end = new Date(completedAt);
226
+ const seconds = Math.round((end.getTime() - start.getTime()) / 1000);
227
+ return `${seconds}s`;
228
+ }
229
+ // ═════════════════════════════════════════════════════════════════════════
230
+ // MAIN - RUN EXAMPLES
231
+ // ═════════════════════════════════════════════════════════════════════════
232
+ async function main() {
233
+ const examples = process.argv[2];
234
+ switch (examples) {
235
+ case '1':
236
+ await example1_CheckReadiness();
237
+ break;
238
+ case '2':
239
+ await example2_AnalyzeChanges();
240
+ break;
241
+ case '3':
242
+ await example3_DryRunPublish();
243
+ break;
244
+ case '4':
245
+ await example4_PublishViaNode();
246
+ break;
247
+ case '5':
248
+ await example5_PublishViaGitHubActions();
249
+ break;
250
+ case '6':
251
+ await example6_MonitorPipeline();
252
+ break;
253
+ case '7':
254
+ await example7_UseRestAPI();
255
+ break;
256
+ case '8':
257
+ await example8_CustomVersions();
258
+ break;
259
+ default:
260
+ console.log(`
261
+ INDEPENDENT RELEASE ENGINE - QUICK START EXAMPLES
262
+
263
+ Available Examples:
264
+ 1. Check Release Readiness
265
+ 2. Analyze Changes for Package
266
+ 3. Dry-Run Publish
267
+ 4. Publish via Node.js (Direct)
268
+ 5. Publish via GitHub Actions
269
+ 6. Monitor Pipeline Progress
270
+ 7. Use REST API
271
+ 8. Custom Version Overrides
272
+
273
+ Usage:
274
+ npx ts-node quick-start.ts <example-number>
275
+
276
+ Examples:
277
+ npx ts-node quick-start.ts 1 # Check readiness
278
+ npx ts-node quick-start.ts 3 # Dry-run before real publish
279
+ npx ts-node quick-start.ts 4 # Actually publish
280
+ `);
281
+ }
282
+ }
283
+ main();