Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 74 additions & 12 deletions site/scripts/convert-gitbook-to-docusaurus.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down Expand Up @@ -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/');
Expand Down Expand Up @@ -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)
Expand All @@ -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 <a> tags
content = content.replace(/(<a\s+[^>]*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;
});
Expand Down Expand Up @@ -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)) {
Expand Down
94 changes: 90 additions & 4 deletions site/scripts/migrate-branches-to-versions.js
Original file line number Diff line number Diff line change
Expand Up @@ -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...');
Expand Down Expand Up @@ -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);
Expand Down