diff --git a/site/scripts/convert-gitbook-to-docusaurus.js b/site/scripts/convert-gitbook-to-docusaurus.js index 5fb706e8..4e7170a8 100644 --- a/site/scripts/convert-gitbook-to-docusaurus.js +++ b/site/scripts/convert-gitbook-to-docusaurus.js @@ -181,7 +181,8 @@ const BROKEN_LINKS = { 'deployments/harper-cloud/alarms.md', 'deployments/harper-cloud/instance-size-hardware-specs.md', 'deployments/harper-cloud/iops-impact.md', - 'deployments/harper-cloud/verizon-5g-wavelength-instances.md' + 'deployments/harper-cloud/verizon-5g-wavelength-instances.md', + 'content-types.md' ], byVersion: { @@ -923,16 +924,34 @@ function applyVersionSpecificFixes(content, filePath, version) { // Alarms links should work correctly with harper-studio name } - // Add general fixes for all versions >= 4.2 - if (version && parseFloat(version) >= 4.2) { + // Add general fixes for all versions >= 4.1 + if (version && parseFloat(version) >= 4.1) { // Fix broken-reference links (these should be removed as they're GitBook artifacts) content = content.replace(/\]\(broken-reference\)/g, ''); - // Additional comprehensive fixes for all 4.2+ versions - // Fix getting-started/getting-started links (should just be getting-started/) - content = content.replace(/\/getting-started\/getting-started/g, '/getting-started/'); - content = content.replace(/\.\.\/getting-started\/getting-started/g, '../getting-started/'); - content = content.replace(/\.\.\/\.\.\/getting-started\/getting-started/g, '../../getting-started/'); + // Fix getting-started/getting-started patterns BEFORE adding ./ prefix + // These patterns should just be getting-started/ + // Match the pattern anywhere in the link, not just in parentheses + content = content.replace(/getting-started\/getting-started\.md/g, 'getting-started/'); + content = content.replace(/getting-started\/getting-started(?![-\w])/g, 'getting-started/'); + + // Fix logging links in administration/logging index files BEFORE adding ./ prefix + if (filePath.includes('/administration/logging/') && (filePath.endsWith('/index.md') || filePath.endsWith('/README.md'))) { + content = content.replace(/\]\(logging\.md\)/g, '](standard-logging.md)'); + content = content.replace(/\]\(logging\)/g, '](standard-logging)'); + modified = true; + } + + // Fix relative paths that don't start with ./ or ../ or / or http + // This ensures all relative links are properly formatted for Docusaurus + content = content.replace(/\]\(([^.\/\#\)][^:)]*)\)/g, (match, path) => { + // Skip if it's an external link or anchor + if (path.includes('://') || path.startsWith('http')) { + return match; + } + modified = true; + return `](./${path})`; + }); // Fix double administration paths content = content.replace(/\/administration\/administration\//g, '/administration/'); @@ -1201,6 +1220,10 @@ function fixLinks(content, filePath, version) { return `${marker}[${linkText}](standard-logging.md)`; }); } + // Also handle the case where .md was already removed and ./ was added + content = content.replace(/\]\(\.\/logging\)/g, '](./standard-logging)'); + // And handle case where just 'logging' without .md + content = content.replace(/\]\(logging\)/g, '](standard-logging)'); } // Fix links to logging/logging.md throughout all files (should be logging/standard-logging.md) @@ -1212,11 +1235,28 @@ function fixLinks(content, filePath, version) { }); } - // Remove .md extensions from internal links - content = content.replace(/(\[[^\]]+\]\()([^)]+)(\.md)([)#])/g, (match, prefix, path, ext, suffix) => { - if (!path.includes('http://') && !path.includes('https://')) { + // Remove .md extensions from internal links - comprehensive fix + // This handles all markdown link patterns with .md extensions + content = content.replace(/(\[[^\]]+\]\()([^)]+\.md)([\)#])/g, (match, prefix, pathWithExt, suffix) => { + // Only process if it's not an external link + if (!pathWithExt.includes('http://') && !pathWithExt.includes('https://')) { modified = true; - return prefix + path + suffix; + // Remove the .md extension + const pathWithoutExt = pathWithExt.replace(/\.md$/, ''); + return prefix + pathWithoutExt + suffix; + } + return match; + }); + + // Also handle .md extensions in HTML links within tables (GitBook specific) + // This pattern catches href attributes in tags + content = content.replace(/(]*href=")([^"]+\.md)(")/g, (match, prefix, pathWithExt, suffix) => { + // Only process if it's not an external link + if (!pathWithExt.includes('http://') && !pathWithExt.includes('https://')) { + modified = true; + // Remove the .md extension + const pathWithoutExt = pathWithExt.replace(/\.md$/, ''); + return prefix + pathWithoutExt + suffix; } return match; }); @@ -1644,11 +1684,33 @@ function processDirectory(dirPath, targetDirPath, docsDir = dirPath, outputDir = // Create category file if needed createCategoryFile(dirPath, targetDirPath); + // Check if we have both index.md and README.md, and prefer README if index is blank + const hasIndex = entries.some(e => e.name === 'index.md'); + const hasReadme = entries.some(e => e.name === 'README.md'); + + if (hasIndex && hasReadme) { + const indexPath = path.join(dirPath, 'index.md'); + const indexContent = fs.readFileSync(indexPath, 'utf8'); + + // Check if index.md is essentially blank (contains only the comment about blank index) + if (indexContent.includes('blank index file needed to avoid "index" being added to URLs') || + indexContent.trim().length < 50) { + // Remove the blank index.md so README.md will be used instead + fs.unlinkSync(indexPath); + console.log(` Removed blank index.md in favor of README.md in ${dirPath}`); + } + } + // Process entries for (const entry of entries) { let entryName = entry.name; let actualSourcePath = path.join(dirPath, entry.name); + // Skip if this was the blank index.md we just removed + if (!fs.existsSync(actualSourcePath)) { + continue; + } + // Fix directories starting with numbers (webpack issue) // Rename them to prefix with 'v' (e.g., '1.alby' -> 'v1-alby') if (entry.isDirectory() && /^\d/.test(entry.name)) { diff --git a/site/scripts/migrate-branches-to-versions.js b/site/scripts/migrate-branches-to-versions.js index 9b7456d0..9ca7ed87 100644 --- a/site/scripts/migrate-branches-to-versions.js +++ b/site/scripts/migrate-branches-to-versions.js @@ -58,21 +58,78 @@ function gitExec(command, options = {}) { // Save current branch and changes function saveCurrentState() { - const currentBranch = gitExec('rev-parse --abbrev-ref HEAD'); + let currentBranch = gitExec('rev-parse --abbrev-ref HEAD'); + const currentCommit = gitExec('rev-parse HEAD'); const hasChanges = gitExec('status --porcelain'); + // Check if we're in detached HEAD state (common in CI) + if (currentBranch === 'HEAD') { + console.log('Detected detached HEAD state (common in CI)'); + console.log(`Current commit: ${currentCommit}`); + + // Try to find which branch we're on by checking which branches contain this commit + try { + const branches = gitExec(`branch -r --contains ${currentCommit}`); + console.log('Branches containing current commit:', branches); + + // In CI, we might want to use the commit hash directly + currentBranch = currentCommit; + console.log(`Will restore to commit: ${currentCommit}`); + } catch (e) { + console.log('Could not determine branch from commit'); + } + } else { + console.log(`Starting from branch: ${currentBranch}`); + } + + console.log(`Current working directory: ${process.cwd()}`); + if (hasChanges) { console.log('Stashing current changes...'); gitExec('stash push -m "migrate-branches-to-versions temporary stash"'); } - return { currentBranch, hasChanges: !!hasChanges }; + return { + currentBranch, + currentCommit, + isDetachedHead: currentBranch === currentCommit, + hasChanges: !!hasChanges, + startingDir: process.cwd() + }; } // Restore original state function restoreState(state) { - console.log(`Switching back to ${state.currentBranch}...`); - gitExec(`checkout ${state.currentBranch}`); + console.log(`\nRestoring original state...`); + const currentLocation = gitExec('rev-parse --abbrev-ref HEAD'); + console.log(`Current location: ${currentLocation}`); + console.log(`Current directory: ${process.cwd()}`); + + if (state.isDetachedHead) { + // In CI with detached HEAD, checkout the specific commit + console.log(`Restoring to commit: ${state.currentCommit}`); + gitExec(`checkout ${state.currentCommit}`); + + // Verify we're at the right commit + const actualCommit = gitExec('rev-parse HEAD'); + if (actualCommit !== state.currentCommit) { + console.error(`Warning: Expected commit ${state.currentCommit} but at ${actualCommit}`); + } else { + console.log(`✓ Successfully restored to commit ${state.currentCommit}`); + } + } else { + // Normal branch checkout + console.log(`Switching back to branch: ${state.currentBranch}...`); + gitExec(`checkout ${state.currentBranch}`); + + // Verify we're on the right branch + const actualBranch = gitExec('rev-parse --abbrev-ref HEAD'); + if (actualBranch !== state.currentBranch) { + console.error(`Warning: Expected to be on ${state.currentBranch} but actually on ${actualBranch}`); + } else { + console.log(`✓ Successfully restored to branch ${state.currentBranch}`); + } + } if (state.hasChanges) { console.log('Restoring stashed changes...'); @@ -517,6 +574,35 @@ async function migrate() { // Restore original state restoreState(originalState); + // After switching back, ensure the site directory exists + // In CI, switching branches might have removed it + console.log(`\nChecking if site directory exists at: ${SITE_DIR}`); + if (!fs.existsSync(SITE_DIR)) { + console.error('\n⚠️ Warning: Site directory was removed during branch switching.'); + console.error(`Expected site directory at: ${SITE_DIR}`); + console.error('This can happen in CI when switching to older branches.'); + console.error('The site directory should be restored by Git, but it may not be immediate.'); + + // Try to force Git to restore the directory + console.log('Attempting to restore site directory from Git...'); + try { + gitExec('checkout HEAD -- site'); + console.log('✓ Restored site directory from Git'); + + // Verify it was restored + if (fs.existsSync(SITE_DIR)) { + console.log('✓ Site directory now exists'); + } else { + console.error('✗ Site directory still missing after restore attempt'); + } + } catch (e) { + console.error('Could not restore site directory:', e.message); + console.error('Git may not have the site directory in the current branch'); + } + } else { + console.log('✓ Site directory exists'); + } + // Update and write docusaurus config after returning to original branch if (docusaurusConfig && fs.existsSync(DOCUSAURUS_CONFIG_PATH)) { const updatedConfig = updateDocusaurusConfig(docusaurusConfig);