@eldrforge/kodrdriv 1.2.16 → 1.2.18
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/dist/commands/development.js +54 -0
- package/dist/commands/development.js.map +1 -1
- package/dist/commands/publish.js +130 -4
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/tree.js +11 -1
- package/dist/commands/tree.js.map +1 -1
- package/dist/constants.js +1 -1
- package/dist/util/openai.js +5 -0
- package/dist/util/openai.js.map +1 -1
- package/package.json +1 -1
package/dist/commands/publish.js
CHANGED
|
@@ -10,6 +10,7 @@ import { calculateBranchDependentVersion, calculateTargetVersion, checkIfTagExis
|
|
|
10
10
|
import { DEFAULT_OUTPUT_DIRECTORY, KODRDRIV_DEFAULTS } from '../constants.js';
|
|
11
11
|
import { safeJsonParse, validatePackageJson } from '../util/validation.js';
|
|
12
12
|
import { localBranchExists, safeSyncBranchWithRemote, isBranchInSyncWithRemote } from '../util/git.js';
|
|
13
|
+
import fs__default from 'fs/promises';
|
|
13
14
|
|
|
14
15
|
const scanNpmrcForEnvVars = async (storage)=>{
|
|
15
16
|
const logger = getLogger();
|
|
@@ -38,6 +39,76 @@ const scanNpmrcForEnvVars = async (storage)=>{
|
|
|
38
39
|
}
|
|
39
40
|
return envVars;
|
|
40
41
|
};
|
|
42
|
+
/**
|
|
43
|
+
* Checks if package-lock.json contains file: dependencies (from npm link)
|
|
44
|
+
* and cleans them up if found by removing package-lock.json and regenerating it.
|
|
45
|
+
*/ const cleanupNpmLinkReferences = async (isDryRun)=>{
|
|
46
|
+
const logger = getDryRunLogger(isDryRun);
|
|
47
|
+
const packageLockPath = path__default.join(process.cwd(), 'package-lock.json');
|
|
48
|
+
try {
|
|
49
|
+
// Check if package-lock.json exists
|
|
50
|
+
try {
|
|
51
|
+
await fs__default.access(packageLockPath);
|
|
52
|
+
} catch {
|
|
53
|
+
// No package-lock.json, nothing to clean
|
|
54
|
+
logger.verbose('No package-lock.json found, skipping npm link cleanup');
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
// Read and parse package-lock.json
|
|
58
|
+
const packageLockContent = await fs__default.readFile(packageLockPath, 'utf-8');
|
|
59
|
+
const packageLock = safeJsonParse(packageLockContent, packageLockPath);
|
|
60
|
+
// Check for file: dependencies in the lockfile
|
|
61
|
+
let hasFileReferences = false;
|
|
62
|
+
// Check in packages (npm v7+)
|
|
63
|
+
if (packageLock.packages) {
|
|
64
|
+
for (const [pkgPath, pkgInfo] of Object.entries(packageLock.packages)){
|
|
65
|
+
if (pkgInfo.resolved && typeof pkgInfo.resolved === 'string' && pkgInfo.resolved.startsWith('file:')) {
|
|
66
|
+
// Check if it's a relative path (from npm link) rather than a workspace path
|
|
67
|
+
const resolvedPath = pkgInfo.resolved.replace('file:', '');
|
|
68
|
+
if (resolvedPath.startsWith('../') || resolvedPath.startsWith('./')) {
|
|
69
|
+
hasFileReferences = true;
|
|
70
|
+
logger.verbose(`Found npm link reference: ${pkgPath} -> ${pkgInfo.resolved}`);
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Check in dependencies (npm v6)
|
|
77
|
+
if (!hasFileReferences && packageLock.dependencies) {
|
|
78
|
+
for (const [pkgName, pkgInfo] of Object.entries(packageLock.dependencies)){
|
|
79
|
+
if (pkgInfo.version && typeof pkgInfo.version === 'string' && pkgInfo.version.startsWith('file:')) {
|
|
80
|
+
const versionPath = pkgInfo.version.replace('file:', '');
|
|
81
|
+
if (versionPath.startsWith('../') || versionPath.startsWith('./')) {
|
|
82
|
+
hasFileReferences = true;
|
|
83
|
+
logger.verbose(`Found npm link reference: ${pkgName} -> ${pkgInfo.version}`);
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (hasFileReferences) {
|
|
90
|
+
logger.info('⚠️ Detected npm link references in package-lock.json');
|
|
91
|
+
logger.info('🧹 Cleaning up package-lock.json to remove relative file: dependencies...');
|
|
92
|
+
if (isDryRun) {
|
|
93
|
+
logger.info('DRY RUN: Would remove package-lock.json and regenerate it');
|
|
94
|
+
} else {
|
|
95
|
+
// Remove package-lock.json
|
|
96
|
+
await fs__default.unlink(packageLockPath);
|
|
97
|
+
logger.verbose('Removed package-lock.json with npm link references');
|
|
98
|
+
// Regenerate clean package-lock.json
|
|
99
|
+
logger.verbose('Regenerating package-lock.json from package.json...');
|
|
100
|
+
await runWithDryRunSupport('npm install --package-lock-only --no-audit --no-fund', isDryRun);
|
|
101
|
+
logger.info('✅ Regenerated clean package-lock.json');
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
logger.verbose('No npm link references found in package-lock.json');
|
|
105
|
+
}
|
|
106
|
+
} catch (error) {
|
|
107
|
+
// Log warning but don't fail - let npm update handle any issues
|
|
108
|
+
logger.warn(`⚠️ Failed to check/clean npm link references: ${error.message}`);
|
|
109
|
+
logger.verbose('Continuing with publish process...');
|
|
110
|
+
}
|
|
111
|
+
};
|
|
41
112
|
const validateEnvironmentVariables = (requiredEnvVars, isDryRun)=>{
|
|
42
113
|
const logger = getDryRunLogger(isDryRun);
|
|
43
114
|
const missingEnvVars = [];
|
|
@@ -450,6 +521,9 @@ const execute = async (runConfig)=>{
|
|
|
450
521
|
logger.info('No open pull request found, starting new release publishing process...');
|
|
451
522
|
// STEP 1: Prepare for release (update dependencies and run prepublish checks) with NO version bump yet
|
|
452
523
|
logger.verbose('Preparing for release: switching from workspace to remote dependencies.');
|
|
524
|
+
// Clean up any npm link references before updating dependencies
|
|
525
|
+
logger.verbose('Checking for npm link references in package-lock.json...');
|
|
526
|
+
await cleanupNpmLinkReferences(isDryRun);
|
|
453
527
|
logger.verbose('Updating dependencies to latest versions from registry');
|
|
454
528
|
const updatePatterns = (_runConfig_publish4 = runConfig.publish) === null || _runConfig_publish4 === void 0 ? void 0 : _runConfig_publish4.dependencyUpdatePatterns;
|
|
455
529
|
if (updatePatterns && updatePatterns.length > 0) {
|
|
@@ -997,12 +1071,64 @@ const execute = async (runConfig)=>{
|
|
|
997
1071
|
} else {
|
|
998
1072
|
logger.verbose('Skipping waiting for release workflows (disabled in config).');
|
|
999
1073
|
}
|
|
1074
|
+
// Switch back to source branch and sync with target
|
|
1000
1075
|
logger.info('');
|
|
1001
|
-
logger.info(
|
|
1076
|
+
logger.info(`🔄 Syncing source branch with target after publish...`);
|
|
1077
|
+
await runWithDryRunSupport(`git checkout ${currentBranch}`, isDryRun);
|
|
1078
|
+
if (!isDryRun) {
|
|
1079
|
+
// Merge target into source (should be fast-forward since PR just merged)
|
|
1080
|
+
logger.info(`Merging ${targetBranch} into ${currentBranch}...`);
|
|
1081
|
+
try {
|
|
1082
|
+
await run(`git merge ${targetBranch} --ff-only`);
|
|
1083
|
+
logger.info(`✅ Merged ${targetBranch} into ${currentBranch}`);
|
|
1084
|
+
} catch (error) {
|
|
1085
|
+
// If ff-only fails, something is wrong - source diverged somehow
|
|
1086
|
+
logger.error(`❌ Failed to fast-forward merge ${targetBranch} into ${currentBranch}`);
|
|
1087
|
+
logger.error(' This suggests the source branch has commits not in target.');
|
|
1088
|
+
logger.error(' This should not happen after a successful PR merge.');
|
|
1089
|
+
logger.warn('⚠️ Attempting regular merge...');
|
|
1090
|
+
await run(`git merge ${targetBranch} --no-edit`);
|
|
1091
|
+
}
|
|
1092
|
+
// Determine version bump based on branch configuration
|
|
1093
|
+
let versionCommand = 'prepatch'; // Default
|
|
1094
|
+
let versionTag = 'dev'; // Default
|
|
1095
|
+
if (branchDependentVersioning && runConfig.branches) {
|
|
1096
|
+
const sourceBranchConfig = runConfig.branches[currentBranch];
|
|
1097
|
+
if (sourceBranchConfig === null || sourceBranchConfig === void 0 ? void 0 : sourceBranchConfig.version) {
|
|
1098
|
+
// Use configured version strategy for source branch
|
|
1099
|
+
if (sourceBranchConfig.version.incrementLevel) {
|
|
1100
|
+
versionCommand = `pre${sourceBranchConfig.version.incrementLevel}`;
|
|
1101
|
+
}
|
|
1102
|
+
if (sourceBranchConfig.version.tag) {
|
|
1103
|
+
versionTag = sourceBranchConfig.version.tag;
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
// Bump to next development version
|
|
1108
|
+
logger.info(`Bumping to next development version...`);
|
|
1109
|
+
try {
|
|
1110
|
+
const { stdout: newVersion } = await run(`npm version ${versionCommand} --preid=${versionTag}`);
|
|
1111
|
+
logger.info(`✅ Version bumped to: ${newVersion.trim()}`);
|
|
1112
|
+
} catch (versionError) {
|
|
1113
|
+
logger.warn(`⚠️ Failed to bump version: ${versionError.message}`);
|
|
1114
|
+
logger.warn(' You may need to manually bump the version for next development cycle.');
|
|
1115
|
+
}
|
|
1116
|
+
// Push updated source branch
|
|
1117
|
+
logger.info(`Pushing updated ${currentBranch} branch...`);
|
|
1118
|
+
try {
|
|
1119
|
+
await run(`git push origin ${currentBranch}`);
|
|
1120
|
+
logger.info(`✅ Pushed ${currentBranch} to origin`);
|
|
1121
|
+
} catch (pushError) {
|
|
1122
|
+
logger.warn(`⚠️ Failed to push ${currentBranch}: ${pushError.message}`);
|
|
1123
|
+
logger.warn(` Please push manually: git push origin ${currentBranch}`);
|
|
1124
|
+
}
|
|
1125
|
+
} else {
|
|
1126
|
+
logger.info(`Would merge ${targetBranch} into ${currentBranch} with --ff-only`);
|
|
1127
|
+
logger.info(`Would bump version to next development version`);
|
|
1128
|
+
logger.info(`Would push ${currentBranch} to origin`);
|
|
1129
|
+
}
|
|
1002
1130
|
logger.info('');
|
|
1003
|
-
logger.info(
|
|
1004
|
-
logger.info(` - Run 'kodrdriv development' to return to working branch and bump version`);
|
|
1005
|
-
logger.info(` - Or manually switch to your working branch to continue development`);
|
|
1131
|
+
logger.info(`✅ Publish complete - on ${currentBranch} with next development version`);
|
|
1006
1132
|
};
|
|
1007
1133
|
|
|
1008
1134
|
export { execute };
|