2025-01-30 16:17:36 +00:00
|
|
|
import type { LoaderFunction } from '@remix-run/cloudflare';
|
|
|
|
import { json } from '@remix-run/cloudflare';
|
2025-01-23 15:02:50 +00:00
|
|
|
import { execSync } from 'child_process';
|
|
|
|
|
2025-01-30 16:17:36 +00:00
|
|
|
interface GitHubRepoInfo {
|
|
|
|
name: string;
|
|
|
|
full_name: string;
|
|
|
|
default_branch: string;
|
|
|
|
stargazers_count: number;
|
|
|
|
forks_count: number;
|
|
|
|
open_issues_count: number;
|
|
|
|
parent?: {
|
|
|
|
full_name: string;
|
|
|
|
default_branch: string;
|
|
|
|
stargazers_count: number;
|
|
|
|
forks_count: number;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
const getLocalGitInfo = () => {
|
2025-01-23 15:02:50 +00:00
|
|
|
try {
|
2025-01-30 16:17:36 +00:00
|
|
|
return {
|
2025-01-30 20:08:23 +00:00
|
|
|
commitHash: execSync('git rev-parse HEAD').toString().trim(),
|
2025-01-30 16:17:36 +00:00
|
|
|
branch: execSync('git rev-parse --abbrev-ref HEAD').toString().trim(),
|
|
|
|
commitTime: execSync('git log -1 --format=%cd').toString().trim(),
|
|
|
|
author: execSync('git log -1 --format=%an').toString().trim(),
|
|
|
|
email: execSync('git log -1 --format=%ae').toString().trim(),
|
|
|
|
remoteUrl: execSync('git config --get remote.origin.url').toString().trim(),
|
|
|
|
repoName: execSync('git config --get remote.origin.url')
|
|
|
|
.toString()
|
|
|
|
.trim()
|
|
|
|
.replace(/^.*github.com[:/]/, '')
|
|
|
|
.replace(/\.git$/, ''),
|
|
|
|
};
|
2025-01-23 15:02:50 +00:00
|
|
|
} catch (error) {
|
2025-01-30 16:17:36 +00:00
|
|
|
console.error('Failed to get local git info:', error);
|
|
|
|
return null;
|
2025-01-23 15:02:50 +00:00
|
|
|
}
|
2025-01-30 16:17:36 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const getGitHubInfo = async (repoFullName: string) => {
|
|
|
|
try {
|
2025-01-30 20:08:23 +00:00
|
|
|
// Add GitHub token if available
|
|
|
|
const headers: Record<string, string> = {
|
|
|
|
Accept: 'application/vnd.github.v3+json',
|
|
|
|
};
|
|
|
|
|
|
|
|
const githubToken = process.env.GITHUB_TOKEN;
|
|
|
|
|
|
|
|
if (githubToken) {
|
|
|
|
headers.Authorization = `token ${githubToken}`;
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log('Fetching GitHub info for:', repoFullName); // Debug log
|
|
|
|
|
|
|
|
const response = await fetch(`https://api.github.com/repos/${repoFullName}`, {
|
|
|
|
headers,
|
|
|
|
});
|
2025-01-30 16:17:36 +00:00
|
|
|
|
|
|
|
if (!response.ok) {
|
2025-01-30 20:08:23 +00:00
|
|
|
console.error('GitHub API error:', {
|
|
|
|
status: response.status,
|
|
|
|
statusText: response.statusText,
|
|
|
|
repoFullName,
|
|
|
|
});
|
|
|
|
|
|
|
|
// If we get a 404, try the main repo as fallback
|
|
|
|
if (response.status === 404 && repoFullName !== 'stackblitz-labs/bolt.diy') {
|
|
|
|
return getGitHubInfo('stackblitz-labs/bolt.diy');
|
|
|
|
}
|
|
|
|
|
2025-01-30 16:17:36 +00:00
|
|
|
throw new Error(`GitHub API error: ${response.statusText}`);
|
|
|
|
}
|
|
|
|
|
2025-01-30 20:08:23 +00:00
|
|
|
const data = await response.json();
|
|
|
|
console.log('GitHub API response:', data); // Debug log
|
|
|
|
|
|
|
|
return data as GitHubRepoInfo;
|
2025-01-30 16:17:36 +00:00
|
|
|
} catch (error) {
|
|
|
|
console.error('Failed to get GitHub info:', error);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
export const loader: LoaderFunction = async ({ request: _request }) => {
|
|
|
|
const localInfo = getLocalGitInfo();
|
2025-01-30 20:08:23 +00:00
|
|
|
console.log('Local git info:', localInfo); // Debug log
|
2025-01-30 16:17:36 +00:00
|
|
|
|
|
|
|
// If we have local info, try to get GitHub info for both our fork and upstream
|
|
|
|
let githubInfo = null;
|
|
|
|
|
|
|
|
if (localInfo?.repoName) {
|
|
|
|
githubInfo = await getGitHubInfo(localInfo.repoName);
|
|
|
|
}
|
|
|
|
|
|
|
|
// If no local info or GitHub info, try the main repo
|
|
|
|
if (!githubInfo) {
|
|
|
|
githubInfo = await getGitHubInfo('stackblitz-labs/bolt.diy');
|
|
|
|
}
|
|
|
|
|
2025-01-30 20:08:23 +00:00
|
|
|
const response = {
|
2025-01-30 16:17:36 +00:00
|
|
|
local: localInfo || {
|
|
|
|
commitHash: 'unknown',
|
|
|
|
branch: 'unknown',
|
|
|
|
commitTime: 'unknown',
|
|
|
|
author: 'unknown',
|
|
|
|
email: 'unknown',
|
|
|
|
remoteUrl: 'unknown',
|
|
|
|
repoName: 'unknown',
|
|
|
|
},
|
|
|
|
github: githubInfo
|
|
|
|
? {
|
|
|
|
currentRepo: {
|
|
|
|
fullName: githubInfo.full_name,
|
|
|
|
defaultBranch: githubInfo.default_branch,
|
|
|
|
stars: githubInfo.stargazers_count,
|
|
|
|
forks: githubInfo.forks_count,
|
|
|
|
openIssues: githubInfo.open_issues_count,
|
|
|
|
},
|
|
|
|
upstream: githubInfo.parent
|
|
|
|
? {
|
|
|
|
fullName: githubInfo.parent.full_name,
|
|
|
|
defaultBranch: githubInfo.parent.default_branch,
|
|
|
|
stars: githubInfo.parent.stargazers_count,
|
|
|
|
forks: githubInfo.parent.forks_count,
|
|
|
|
}
|
|
|
|
: null,
|
|
|
|
}
|
|
|
|
: null,
|
|
|
|
isForked: Boolean(githubInfo?.parent),
|
|
|
|
timestamp: new Date().toISOString(),
|
2025-01-30 20:08:23 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
console.log('Final response:', response);
|
|
|
|
|
|
|
|
// Debug log
|
|
|
|
return json(response);
|
2025-01-30 16:17:36 +00:00
|
|
|
};
|