@eldrforge/kodrdriv 1.2.20 → 1.2.22
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.
- package/WORKFLOW-PRECHECK-IMPLEMENTATION.md +239 -0
- package/WORKFLOW-SKIP-SUMMARY.md +121 -0
- package/dist/application.js +6 -2
- package/dist/application.js.map +1 -1
- package/dist/arguments.js +2 -2
- package/dist/arguments.js.map +1 -1
- package/dist/commands/audio-commit.js +15 -6
- package/dist/commands/audio-commit.js.map +1 -1
- package/dist/commands/audio-review.js +31 -15
- package/dist/commands/audio-review.js.map +1 -1
- package/dist/commands/commit.js +31 -20
- package/dist/commands/commit.js.map +1 -1
- package/dist/commands/link.js +27 -27
- package/dist/commands/link.js.map +1 -1
- package/dist/commands/publish.js +87 -34
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/release.js +32 -19
- package/dist/commands/release.js.map +1 -1
- package/dist/commands/review.js +36 -30
- package/dist/commands/review.js.map +1 -1
- package/dist/commands/select-audio.js +4 -4
- package/dist/commands/select-audio.js.map +1 -1
- package/dist/commands/tree.js +154 -38
- package/dist/commands/tree.js.map +1 -1
- package/dist/commands/unlink.js +13 -13
- package/dist/commands/unlink.js.map +1 -1
- package/dist/commands/updates.js +21 -0
- package/dist/commands/updates.js.map +1 -1
- package/dist/commands/versions.js +5 -5
- package/dist/commands/versions.js.map +1 -1
- package/dist/constants.js +4 -4
- package/dist/constants.js.map +1 -1
- package/dist/content/files.js +4 -4
- package/dist/content/files.js.map +1 -1
- package/dist/error/CommandErrors.js +1 -65
- package/dist/error/CommandErrors.js.map +1 -1
- package/dist/logging.js +3 -3
- package/dist/logging.js.map +1 -1
- package/dist/util/aiAdapter.js +28 -0
- package/dist/util/aiAdapter.js.map +1 -0
- package/dist/util/general.js +5 -5
- package/dist/util/general.js.map +1 -1
- package/dist/util/interactive.js +6 -437
- package/dist/util/interactive.js.map +1 -1
- package/dist/util/loggerAdapter.js +24 -0
- package/dist/util/loggerAdapter.js.map +1 -0
- package/dist/util/performance.js +4 -4
- package/dist/util/performance.js.map +1 -1
- package/dist/util/safety.js +4 -4
- package/dist/util/safety.js.map +1 -1
- package/dist/util/storage.js +2 -2
- package/dist/util/storage.js.map +1 -1
- package/dist/util/storageAdapter.js +25 -0
- package/dist/util/storageAdapter.js.map +1 -0
- package/package.json +6 -4
- package/test_output.txt +3 -3
- package/INTEGRATION-SUMMARY.md +0 -232
- package/TEST-STATUS.md +0 -168
- package/dist/content/issues.js +0 -331
- package/dist/content/issues.js.map +0 -1
- package/dist/content/releaseNotes.js +0 -90
- package/dist/content/releaseNotes.js.map +0 -1
- package/dist/prompt/commit.js +0 -76
- package/dist/prompt/commit.js.map +0 -1
- package/dist/prompt/instructions/commit.md +0 -133
- package/dist/prompt/instructions/release.md +0 -188
- package/dist/prompt/instructions/review.md +0 -169
- package/dist/prompt/personas/releaser.md +0 -24
- package/dist/prompt/personas/you.md +0 -55
- package/dist/prompt/release.js +0 -100
- package/dist/prompt/release.js.map +0 -1
- package/dist/prompt/review.js +0 -64
- package/dist/prompt/review.js.map +0 -1
- package/dist/util/github.js +0 -1071
- package/dist/util/github.js.map +0 -1
- package/dist/util/openai.js +0 -365
- package/dist/util/openai.js.map +0 -1
package/dist/commands/publish.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'path';
|
|
2
2
|
import { execute as execute$1 } from './commit.js';
|
|
3
3
|
import { hasStagedChanges } from '../content/diff.js';
|
|
4
4
|
import { execute as execute$2 } from './release.js';
|
|
5
5
|
import { getDryRunLogger, getLogger } from '../logging.js';
|
|
6
6
|
import { run, localBranchExists, runSecure, runWithDryRunSupport, safeJsonParse, validatePackageJson, validateGitRef, safeSyncBranchWithRemote, isBranchInSyncWithRemote } from '@eldrforge/git-tools';
|
|
7
|
-
import
|
|
7
|
+
import * as GitHub from '@eldrforge/github-tools';
|
|
8
8
|
import { create } from '../util/storage.js';
|
|
9
9
|
import { calculateBranchDependentVersion, calculateTargetVersion, checkIfTagExists, confirmVersionInteractively, getOutputPath } from '../util/general.js';
|
|
10
10
|
import { DEFAULT_OUTPUT_DIRECTORY, KODRDRIV_DEFAULTS } from '../constants.js';
|
|
11
|
-
import
|
|
11
|
+
import fs from 'fs/promises';
|
|
12
12
|
|
|
13
13
|
const scanNpmrcForEnvVars = async (storage)=>{
|
|
14
14
|
const logger = getLogger();
|
|
15
|
-
const npmrcPath =
|
|
15
|
+
const npmrcPath = path.join(process.cwd(), '.npmrc');
|
|
16
16
|
const envVars = [];
|
|
17
17
|
if (await storage.exists(npmrcPath)) {
|
|
18
18
|
try {
|
|
@@ -42,18 +42,18 @@ const scanNpmrcForEnvVars = async (storage)=>{
|
|
|
42
42
|
* and cleans them up if found by removing package-lock.json and regenerating it.
|
|
43
43
|
*/ const cleanupNpmLinkReferences = async (isDryRun)=>{
|
|
44
44
|
const logger = getDryRunLogger(isDryRun);
|
|
45
|
-
const packageLockPath =
|
|
45
|
+
const packageLockPath = path.join(process.cwd(), 'package-lock.json');
|
|
46
46
|
try {
|
|
47
47
|
// Check if package-lock.json exists
|
|
48
48
|
try {
|
|
49
|
-
await
|
|
49
|
+
await fs.access(packageLockPath);
|
|
50
50
|
} catch {
|
|
51
51
|
// No package-lock.json, nothing to clean
|
|
52
52
|
logger.verbose('No package-lock.json found, skipping npm link cleanup');
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
55
|
// Read and parse package-lock.json
|
|
56
|
-
const packageLockContent = await
|
|
56
|
+
const packageLockContent = await fs.readFile(packageLockPath, 'utf-8');
|
|
57
57
|
const packageLock = safeJsonParse(packageLockContent, packageLockPath);
|
|
58
58
|
// Check for file: dependencies in the lockfile
|
|
59
59
|
let hasFileReferences = false;
|
|
@@ -91,7 +91,7 @@ const scanNpmrcForEnvVars = async (storage)=>{
|
|
|
91
91
|
logger.info('DRY RUN: Would remove package-lock.json and regenerate it');
|
|
92
92
|
} else {
|
|
93
93
|
// Remove package-lock.json
|
|
94
|
-
await
|
|
94
|
+
await fs.unlink(packageLockPath);
|
|
95
95
|
logger.verbose('Removed package-lock.json with npm link references');
|
|
96
96
|
// Regenerate clean package-lock.json
|
|
97
97
|
logger.verbose('Regenerating package-lock.json from package.json...');
|
|
@@ -171,7 +171,7 @@ const runPrechecks = async (runConfig, targetBranch)=>{
|
|
|
171
171
|
if (isDryRun) {
|
|
172
172
|
logger.info(`Would verify current branch is not the target branch (${effectiveTargetBranch})`);
|
|
173
173
|
} else {
|
|
174
|
-
const currentBranch = await getCurrentBranchName();
|
|
174
|
+
const currentBranch = await GitHub.getCurrentBranchName();
|
|
175
175
|
if (currentBranch === effectiveTargetBranch) {
|
|
176
176
|
throw new Error(`Cannot run publish from the target branch '${effectiveTargetBranch}'. Please switch to a different branch before running publish.`);
|
|
177
177
|
}
|
|
@@ -210,9 +210,35 @@ const runPrechecks = async (runConfig, targetBranch)=>{
|
|
|
210
210
|
logger.info(`ℹ️ Target branch '${effectiveTargetBranch}' does not exist locally - will be created when needed.`);
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
|
+
// Check GitHub Actions workflow configuration
|
|
214
|
+
logger.info('Checking GitHub Actions workflow configuration...');
|
|
215
|
+
if (isDryRun) {
|
|
216
|
+
logger.info('Would check if GitHub Actions workflows are configured for pull requests');
|
|
217
|
+
} else {
|
|
218
|
+
try {
|
|
219
|
+
// TODO: Re-enable when checkWorkflowConfiguration is exported from github-tools
|
|
220
|
+
// const workflowConfig = await GitHub.checkWorkflowConfiguration(effectiveTargetBranch);
|
|
221
|
+
const workflowConfig = {
|
|
222
|
+
hasWorkflows: true,
|
|
223
|
+
hasPullRequestTriggers: true,
|
|
224
|
+
workflowCount: 0,
|
|
225
|
+
triggeredWorkflowNames: []
|
|
226
|
+
};
|
|
227
|
+
if (!workflowConfig.hasWorkflows) ; else if (!workflowConfig.hasPullRequestTriggers) ; else {
|
|
228
|
+
logger.info(`✅ Found ${workflowConfig.triggeredWorkflowNames.length} workflow(s) that will run on PRs to ${effectiveTargetBranch}:`);
|
|
229
|
+
for (const workflowName of workflowConfig.triggeredWorkflowNames){
|
|
230
|
+
logger.info(` - ${workflowName}`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
} catch (error) {
|
|
234
|
+
// Don't fail the precheck if we can't verify workflows
|
|
235
|
+
// The wait logic will handle it later
|
|
236
|
+
logger.debug(`Could not verify workflow configuration: ${error.message}`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
213
239
|
// Check if prepublishOnly script exists in package.json
|
|
214
240
|
logger.info('Checking for prepublishOnly script...');
|
|
215
|
-
const packageJsonPath =
|
|
241
|
+
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
|
216
242
|
if (!await storage.exists(packageJsonPath)) {
|
|
217
243
|
if (!isDryRun) {
|
|
218
244
|
throw new Error('package.json not found in current directory.');
|
|
@@ -277,7 +303,7 @@ const sortObjectKeys = (value)=>{
|
|
|
277
303
|
const isReleaseNecessaryComparedToTarget = async (targetBranch, isDryRun)=>{
|
|
278
304
|
const logger = getDryRunLogger(isDryRun);
|
|
279
305
|
// We compare current HEAD branch to the provided target branch
|
|
280
|
-
const currentBranch = await getCurrentBranchName();
|
|
306
|
+
const currentBranch = await GitHub.getCurrentBranchName();
|
|
281
307
|
// Check if target branch exists before trying to compare
|
|
282
308
|
try {
|
|
283
309
|
// Validate target branch exists and is accessible
|
|
@@ -393,7 +419,7 @@ const execute = async (runConfig)=>{
|
|
|
393
419
|
if (isDryRun) {
|
|
394
420
|
currentBranch = 'mock-branch';
|
|
395
421
|
} else {
|
|
396
|
-
currentBranch = await getCurrentBranchName();
|
|
422
|
+
currentBranch = await GitHub.getCurrentBranchName();
|
|
397
423
|
// Fetch latest remote information to avoid conflicts
|
|
398
424
|
logger.info('📡 Fetching latest remote information to avoid conflicts...');
|
|
399
425
|
try {
|
|
@@ -509,8 +535,8 @@ const execute = async (runConfig)=>{
|
|
|
509
535
|
logger.info('Would check for existing pull request');
|
|
510
536
|
logger.info('Assuming no existing PR found for demo purposes');
|
|
511
537
|
} else {
|
|
512
|
-
const branchName = await getCurrentBranchName();
|
|
513
|
-
pr = await findOpenPullRequestByHeadRef(branchName);
|
|
538
|
+
const branchName = await GitHub.getCurrentBranchName();
|
|
539
|
+
pr = await GitHub.findOpenPullRequestByHeadRef(branchName);
|
|
514
540
|
}
|
|
515
541
|
if (pr) {
|
|
516
542
|
logger.info(`Found existing pull request for branch: ${pr.html_url}`);
|
|
@@ -536,7 +562,10 @@ const execute = async (runConfig)=>{
|
|
|
536
562
|
await runWithDryRunSupport('npm run prepublishOnly', isDryRun, {}, true); // Use inherited stdio
|
|
537
563
|
// STEP 2: Commit dependency updates if any (still no version bump)
|
|
538
564
|
logger.verbose('Staging dependency updates for commit');
|
|
539
|
-
|
|
565
|
+
// Check if package-lock.json exists before trying to stage it
|
|
566
|
+
const packageLockExists = await storage.exists('package-lock.json');
|
|
567
|
+
const filesToStage = packageLockExists ? 'package.json package-lock.json' : 'package.json';
|
|
568
|
+
await runWithDryRunSupport(`git add ${filesToStage}`, isDryRun);
|
|
540
569
|
logger.verbose('Checking for staged dependency updates...');
|
|
541
570
|
if (isDryRun) {
|
|
542
571
|
logger.verbose('Would create dependency update commit if changes are staged');
|
|
@@ -637,7 +666,10 @@ const execute = async (runConfig)=>{
|
|
|
637
666
|
const { stdout: mergeChangesStatus } = await run('git status --porcelain');
|
|
638
667
|
if (mergeChangesStatus.trim()) {
|
|
639
668
|
logger.verbose('Staging post-merge changes for commit');
|
|
640
|
-
|
|
669
|
+
// Check if package-lock.json exists before trying to stage it
|
|
670
|
+
const packageLockExistsPostMerge = await storage.exists('package-lock.json');
|
|
671
|
+
const filesToStagePostMerge = packageLockExistsPostMerge ? 'package.json package-lock.json' : 'package.json';
|
|
672
|
+
await run(`git add ${filesToStagePostMerge}`);
|
|
641
673
|
if (await hasStagedChanges()) {
|
|
642
674
|
logger.verbose('Committing post-merge changes...');
|
|
643
675
|
await execute$1(runConfig);
|
|
@@ -704,7 +736,10 @@ const execute = async (runConfig)=>{
|
|
|
704
736
|
}
|
|
705
737
|
// STEP 5: Commit version bump as a separate commit
|
|
706
738
|
logger.verbose('Staging version bump for commit');
|
|
707
|
-
|
|
739
|
+
// Check if package-lock.json exists before trying to stage it
|
|
740
|
+
const packageLockExistsVersionBump = await storage.exists('package-lock.json');
|
|
741
|
+
const filesToStageVersionBump = packageLockExistsVersionBump ? 'package.json package-lock.json' : 'package.json';
|
|
742
|
+
await runWithDryRunSupport(`git add ${filesToStageVersionBump}`, isDryRun);
|
|
708
743
|
if (isDryRun) {
|
|
709
744
|
logger.verbose('Would create version bump commit');
|
|
710
745
|
} else {
|
|
@@ -758,7 +793,7 @@ const execute = async (runConfig)=>{
|
|
|
758
793
|
}
|
|
759
794
|
logger.info('Pushing to origin...');
|
|
760
795
|
// Get current branch name and push explicitly to avoid pushing to wrong remote/branch
|
|
761
|
-
const branchName = await getCurrentBranchName();
|
|
796
|
+
const branchName = await GitHub.getCurrentBranchName();
|
|
762
797
|
await runWithDryRunSupport(`git push origin ${branchName}`, isDryRun);
|
|
763
798
|
logger.info('Creating pull request...');
|
|
764
799
|
if (isDryRun) {
|
|
@@ -770,7 +805,7 @@ const execute = async (runConfig)=>{
|
|
|
770
805
|
};
|
|
771
806
|
} else {
|
|
772
807
|
const { stdout: commitTitle } = await run('git log -1 --pretty=%B');
|
|
773
|
-
pr = await createPullRequest(commitTitle, 'Automated release PR.', branchName, targetBranch);
|
|
808
|
+
pr = await GitHub.createPullRequest(commitTitle, 'Automated release PR.', branchName, targetBranch);
|
|
774
809
|
if (!pr) {
|
|
775
810
|
throw new Error('Failed to create pull request.');
|
|
776
811
|
}
|
|
@@ -779,23 +814,41 @@ const execute = async (runConfig)=>{
|
|
|
779
814
|
}
|
|
780
815
|
logger.info(`Waiting for PR #${pr.number} checks to complete...`);
|
|
781
816
|
if (!isDryRun) {
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
817
|
+
// Check if we already know from prechecks that no workflows will trigger
|
|
818
|
+
let shouldSkipWait = false;
|
|
819
|
+
try {
|
|
820
|
+
// TODO: Re-enable when checkWorkflowConfiguration is exported from github-tools
|
|
821
|
+
// const workflowConfig = await GitHub.checkWorkflowConfiguration(targetBranch);
|
|
822
|
+
const workflowConfig = {
|
|
823
|
+
hasWorkflows: true,
|
|
824
|
+
hasPullRequestTriggers: true,
|
|
825
|
+
workflowCount: 0,
|
|
826
|
+
triggeredWorkflowNames: []
|
|
827
|
+
};
|
|
828
|
+
if (!workflowConfig.hasWorkflows || !workflowConfig.hasPullRequestTriggers) ;
|
|
829
|
+
} catch (error) {
|
|
830
|
+
// If we can't verify, proceed with waiting to be safe
|
|
831
|
+
logger.debug(`Could not verify workflow configuration for wait skip: ${error.message}`);
|
|
832
|
+
}
|
|
833
|
+
if (!shouldSkipWait) {
|
|
834
|
+
var _runConfig_publish15, _runConfig_publish16, _runConfig_publish17;
|
|
835
|
+
// Configure timeout and user confirmation behavior
|
|
836
|
+
const timeout = ((_runConfig_publish15 = runConfig.publish) === null || _runConfig_publish15 === void 0 ? void 0 : _runConfig_publish15.checksTimeout) || KODRDRIV_DEFAULTS.publish.checksTimeout;
|
|
837
|
+
const senditMode = ((_runConfig_publish16 = runConfig.publish) === null || _runConfig_publish16 === void 0 ? void 0 : _runConfig_publish16.sendit) || false;
|
|
838
|
+
// sendit flag overrides skipUserConfirmation - if sendit is true, skip confirmation
|
|
839
|
+
const skipUserConfirmation = senditMode || ((_runConfig_publish17 = runConfig.publish) === null || _runConfig_publish17 === void 0 ? void 0 : _runConfig_publish17.skipUserConfirmation) || false;
|
|
840
|
+
await GitHub.waitForPullRequestChecks(pr.number, {
|
|
841
|
+
timeout,
|
|
842
|
+
skipUserConfirmation
|
|
843
|
+
});
|
|
844
|
+
}
|
|
792
845
|
}
|
|
793
846
|
const mergeMethod = ((_runConfig_publish2 = runConfig.publish) === null || _runConfig_publish2 === void 0 ? void 0 : _runConfig_publish2.mergeMethod) || 'squash';
|
|
794
847
|
if (isDryRun) {
|
|
795
848
|
logger.info(`Would merge PR #${pr.number} using ${mergeMethod} method`);
|
|
796
849
|
} else {
|
|
797
850
|
try {
|
|
798
|
-
await mergePullRequest(pr.number, mergeMethod, false); // Don't delete branch
|
|
851
|
+
await GitHub.mergePullRequest(pr.number, mergeMethod, false); // Don't delete branch
|
|
799
852
|
} catch (error) {
|
|
800
853
|
// Check if this is a merge conflict error
|
|
801
854
|
if (error.message && (error.message.includes('not mergeable') || error.message.includes('Pull Request is not mergeable') || error.message.includes('merge conflict'))) {
|
|
@@ -1004,14 +1057,14 @@ const execute = async (runConfig)=>{
|
|
|
1004
1057
|
while(retries > 0){
|
|
1005
1058
|
try {
|
|
1006
1059
|
var _runConfig_publish19;
|
|
1007
|
-
await createRelease(tagName, releaseTitle, releaseNotesContent);
|
|
1060
|
+
await GitHub.createRelease(tagName, releaseTitle, releaseNotesContent);
|
|
1008
1061
|
logger.info(`GitHub release created successfully for tag: ${tagName}`);
|
|
1009
1062
|
// Close milestone for this version if enabled
|
|
1010
1063
|
const milestonesEnabled = !((_runConfig_publish19 = runConfig.publish) === null || _runConfig_publish19 === void 0 ? void 0 : _runConfig_publish19.noMilestones);
|
|
1011
1064
|
if (milestonesEnabled) {
|
|
1012
1065
|
logger.info('🏁 Closing milestone for released version...');
|
|
1013
1066
|
const version = tagName.replace(/^v/, ''); // Remove 'v' prefix if present
|
|
1014
|
-
await closeMilestoneForVersion(version);
|
|
1067
|
+
await GitHub.closeMilestoneForVersion(version);
|
|
1015
1068
|
} else {
|
|
1016
1069
|
logger.debug('Milestone integration disabled via --no-milestones');
|
|
1017
1070
|
}
|
|
@@ -1049,7 +1102,7 @@ const execute = async (runConfig)=>{
|
|
|
1049
1102
|
if (!workflowNames || workflowNames.length === 0) {
|
|
1050
1103
|
logger.info('No specific workflow names configured, auto-detecting workflows triggered by release events...');
|
|
1051
1104
|
try {
|
|
1052
|
-
workflowNames = await getWorkflowsTriggeredByRelease();
|
|
1105
|
+
workflowNames = await GitHub.getWorkflowsTriggeredByRelease();
|
|
1053
1106
|
if (workflowNames.length === 0) {
|
|
1054
1107
|
logger.info('No workflows found that are triggered by release events.');
|
|
1055
1108
|
} else {
|
|
@@ -1060,7 +1113,7 @@ const execute = async (runConfig)=>{
|
|
|
1060
1113
|
workflowNames = undefined; // Fall back to monitoring all workflows
|
|
1061
1114
|
}
|
|
1062
1115
|
}
|
|
1063
|
-
await waitForReleaseWorkflows(tagName, {
|
|
1116
|
+
await GitHub.waitForReleaseWorkflows(tagName, {
|
|
1064
1117
|
timeout: workflowTimeout,
|
|
1065
1118
|
workflowNames,
|
|
1066
1119
|
skipUserConfirmation
|