@eldrforge/kodrdriv 1.2.16 → 1.2.17

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.
@@ -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(`✅ Publish complete!`);
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.increment) {
1100
+ versionCommand = `pre${sourceBranchConfig.version.increment}`;
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(`💡 Next steps:`);
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 };