1
0
mirror of https://github.com/kamranahmedse/developer-roadmap.git synced 2025-08-30 04:30:01 +02:00

fix: sync content to database (#9058)

This commit is contained in:
Arik Chakma
2025-08-20 20:36:47 +06:00
committed by GitHub
parent 402104665e
commit 36a9e987b5
3 changed files with 70 additions and 15 deletions

View File

@@ -54,7 +54,7 @@ jobs:
automated pr automated pr
reviewers: arikchakma reviewers: arikchakma
commit-message: "chore: sync content to repo" commit-message: "chore: sync content to repo"
title: "chore: sync content to repository" title: "chore: sync content to repository - ${{ inputs.roadmap_slug }}"
body: | body: |
## Sync Content to Repo ## Sync Content to Repo

View File

@@ -46,7 +46,7 @@ jobs:
echo "$CHANGED_FILES" echo "$CHANGED_FILES"
# Convert to space-separated list for the script # Convert to space-separated list for the script
CHANGED_FILES_LIST=$(echo "$CHANGED_FILES" | tr '\n' ' ') CHANGED_FILES_LIST=$(echo "$CHANGED_FILES" | tr '\n' ',')
echo "has_changes=true" >> $GITHUB_OUTPUT echo "has_changes=true" >> $GITHUB_OUTPUT
echo "changed_files=$CHANGED_FILES_LIST" >> $GITHUB_OUTPUT echo "changed_files=$CHANGED_FILES_LIST" >> $GITHUB_OUTPUT

View File

@@ -5,19 +5,49 @@ import type { OfficialRoadmapDocument } from '../src/queries/official-roadmap';
import { parse } from 'node-html-parser'; import { parse } from 'node-html-parser';
import { markdownToHtml } from '../src/lib/markdown'; import { markdownToHtml } from '../src/lib/markdown';
import { htmlToMarkdown } from '../src/lib/html'; import { htmlToMarkdown } from '../src/lib/html';
import {
allowedOfficialRoadmapTopicResourceType, export const allowedOfficialRoadmapTopicResourceType = [
type AllowedOfficialRoadmapTopicResourceType, 'roadmap',
type OfficialRoadmapTopicContentDocument, 'official',
type OfficialRoadmapTopicResource, 'opensource',
} from './sync-content-to-repo'; 'article',
'course',
'podcast',
'video',
'book',
'feed',
] as const;
export type AllowedOfficialRoadmapTopicResourceType =
(typeof allowedOfficialRoadmapTopicResourceType)[number];
export type OfficialRoadmapTopicResource = {
_id?: string;
type: AllowedOfficialRoadmapTopicResourceType;
title: string;
url: string;
};
export interface OfficialRoadmapTopicContentDocument {
_id?: string;
roadmapSlug: string;
nodeId: string;
description: string;
resources: OfficialRoadmapTopicResource[];
createdAt: Date;
updatedAt: Date;
}
const __filename = fileURLToPath(import.meta.url); const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename); const __dirname = path.dirname(__filename);
const args = process.argv.slice(2); const args = process.argv.slice(2);
const allFiles = args?.[0]?.replace('--files=', ''); const allFiles = args
const secret = args?.[1]?.replace('--secret=', ''); .find((arg) => arg.startsWith('--files='))
?.replace('--files=', '');
const secret = args
.find((arg) => arg.startsWith('--secret='))
?.replace('--secret=', '');
if (!secret) { if (!secret) {
throw new Error('Secret is required'); throw new Error('Secret is required');
} }
@@ -35,12 +65,16 @@ export async function fetchRoadmapJson(
); );
if (!response.ok) { if (!response.ok) {
throw new Error(`Failed to fetch roadmap json: ${response.statusText}`); throw new Error(
`Failed to fetch roadmap json: ${response.statusText} for ${roadmapId}`,
);
} }
const data = await response.json(); const data = await response.json();
if (data.error) { if (data.error) {
throw new Error(`Failed to fetch roadmap json: ${data.error}`); throw new Error(
`Failed to fetch roadmap json: ${data.error} for ${roadmapId}`,
);
} }
roadmapJsonCache.set(roadmapId, data); roadmapJsonCache.set(roadmapId, data);
@@ -57,6 +91,9 @@ export async function syncContentToDatabase(
`https://roadmap.sh/api/v1-sync-official-roadmap-topics`, `https://roadmap.sh/api/v1-sync-official-roadmap-topics`,
{ {
method: 'POST', method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ body: JSON.stringify({
topics, topics,
secret, secret,
@@ -65,17 +102,26 @@ export async function syncContentToDatabase(
); );
if (!response.ok) { if (!response.ok) {
const error = await response.json();
throw new Error( throw new Error(
`Failed to sync content to database: ${response.statusText}`, `Failed to sync content to database: ${response.statusText} ${JSON.stringify(error, null, 2)}`,
); );
} }
return response.json(); return response.json();
} }
const files = allFiles.split(' '); const files =
console.log(`🚀 Starting ${files.length} files`); allFiles
?.split(',')
.map((file) => file.trim())
.filter(Boolean) || [];
if (files.length === 0) {
console.log('No files to sync');
process.exit(0);
}
console.log(`🚀 Starting ${files.length} files`);
const ROADMAP_CONTENT_DIR = path.join(__dirname, '../src/data/roadmaps'); const ROADMAP_CONTENT_DIR = path.join(__dirname, '../src/data/roadmaps');
try { try {
@@ -124,6 +170,15 @@ try {
`${nodeSlug}.md`, `${nodeSlug}.md`,
); );
const fileExists = await fs
.stat(filePath)
.then(() => true)
.catch(() => false);
if (!fileExists) {
console.log(`🚨 File not found: ${filePath}`);
continue;
}
const content = await fs.readFile(filePath, 'utf8'); const content = await fs.readFile(filePath, 'utf8');
const html = markdownToHtml(content, false); const html = markdownToHtml(content, false);
const rootHtml = parse(html); const rootHtml = parse(html);