Refactor GitHub fork status behavior

This commit is contained in:
Sam Becker 2025-01-31 18:31:35 -06:00
parent c41d178301
commit ba32f4e8f7
7 changed files with 61 additions and 40 deletions

View File

@ -1,5 +1,7 @@
import { htmlHasBrParagraphBreaks, safelyParseFormattedHtml } from '@/utility/html';
import { parameterize } from '@/utility/string';
import {
htmlHasBrParagraphBreaks,
safelyParseFormattedHtml,
} from '@/utility/html';
describe('HTML', () => {
it('safely parses', () => {

View File

@ -1,14 +1,12 @@
import { Suspense } from 'react';
import GitHubForkStatusBadgeClient from './GitHubForkStatusBadgeClient';
import GitHubForkStatusBadgeServer from './GitHubForkStatusBadgeServer';
import { IS_DEVELOPMENT, IS_VERCEL_GIT_PROVIDER_GITHUB } from '@/site/config';
import { IS_DEVELOPMENT } from '@/site/config';
export default function GitHubForkStatusBadge() {
return IS_DEVELOPMENT
? <GitHubForkStatusBadgeClient label="Local" />
: IS_VERCEL_GIT_PROVIDER_GITHUB
? <Suspense>
<GitHubForkStatusBadgeServer />
</Suspense>
: null;
: <Suspense>
<GitHubForkStatusBadgeServer />
</Suspense>;
}

View File

@ -38,10 +38,11 @@ export default function GitHubForkStatusBadgeClient({
};
const className = clsx(
'opacity-0 transition-opacity animate-fade-in',
'inline-flex items-center gap-2',
'border transition-colors',
url ? 'hover:underline' : 'select-none',
'pl-[4.5px] pr-2 py-[3px]',
'pl-[4.5px] pr-2.5 py-[3px]',
'rounded-full shadow-sm',
classNameForStyle(),
);

View File

@ -1,5 +1,6 @@
import GitHubForkStatusBadgeClient from './GitHubForkStatusBadgeClient';
import {
VERCEL_GIT_BRANCH,
VERCEL_GIT_REPO_OWNER,
VERCEL_GIT_REPO_SLUG,
} from '@/site/config';
@ -8,29 +9,32 @@ import { getGitHubMeta } from '.';
export default async function GitHubForkStatusBadgeServer() {
const owner = VERCEL_GIT_REPO_OWNER;
const repo = VERCEL_GIT_REPO_SLUG;
const branch = VERCEL_GIT_BRANCH;
const {
url,
isForkedFromBase,
label,
title,
isBehind,
} = await getGitHubMeta({ owner, repo })
} = await getGitHubMeta({ owner, repo, branch })
.catch(() => {
console.log('Error getting GitHub meta', { owner, repo });
console.error('Error retrieving GitHub meta', { owner, repo, branch });
return {
url: undefined,
isForkedFromBase: false,
label: undefined,
title: undefined,
isBehind: false,
isBehind: undefined,
};
});
return (
<GitHubForkStatusBadgeClient {...{
return isForkedFromBase
? <GitHubForkStatusBadgeClient {...{
url,
label,
title,
style: isBehind ? 'warning' : 'mono',
}} />
);
: null;
}

View File

@ -1,7 +1,10 @@
import { VERCEL_BRANCH } from '@/site/config';
import {
TEMPLATE_BASE_OWNER,
TEMPLATE_BASE_REPO,
TEMPLATE_BASE_BRANCH,
} from '@/site/config';
const BASE_OWNER = 'sambecker';
const BASE_REPO = 'exif-photo-blog';
const DEFAULT_BRANCH = 'main';
interface RepoParams {
owner?: string
@ -9,31 +12,42 @@ interface RepoParams {
branch?: string
};
// Urls
// Website urls
const getGitHubRepoUrl = ({
owner = BASE_OWNER,
repo = BASE_REPO,
owner = TEMPLATE_BASE_OWNER,
repo = TEMPLATE_BASE_REPO,
}: RepoParams = {}) =>
`https://github.com/${owner}/${repo}`;
export const getGitHubCompareUrl = ({
owner,
repo,
branch = DEFAULT_BRANCH,
}: RepoParams = {}) =>
// eslint-disable-next-line max-len
`${getGitHubRepoUrl({ owner, repo })}/compare/${branch}...${TEMPLATE_BASE_OWNER}:${TEMPLATE_BASE_REPO}:${TEMPLATE_BASE_BRANCH}`;
// API urls
const getGitHubApiRepoUrl = ({
owner = BASE_OWNER,
repo = BASE_REPO,
owner = TEMPLATE_BASE_OWNER,
repo = TEMPLATE_BASE_REPO,
}: RepoParams = {}) =>
`https://api.github.com/repos/${owner}/${repo}`;
const getGitHubApiCommitsUrl = (params?: RepoParams) =>
`${getGitHubApiRepoUrl(params)}/commits/main`;
// Fetching
const getGitHubApiCompareUrl = ({
owner,
repo,
branch = 'main',
}: RepoParams = {}) =>
`${getGitHubApiRepoUrl()}/compare/main...${owner}:${repo}:${branch}`;
// eslint-disable-next-line max-len
`${getGitHubApiRepoUrl()}/compare/${TEMPLATE_BASE_BRANCH}...${owner}:${repo}:${branch}`;
// Requests
const getLatestBaseRepoCommitSha = async () => {
const response = await fetch(getGitHubApiCommitsUrl());
@ -44,21 +58,21 @@ const getLatestBaseRepoCommitSha = async () => {
const getIsRepoForkedFromBase = async (params: RepoParams) => {
const response = await fetch(getGitHubApiRepoUrl(params));
const data = await response.json();
return data.fork && data.source?.full_name === `${BASE_OWNER}/${BASE_REPO}`;
return (
Boolean(data.fork) &&
data.source?.full_name === `${TEMPLATE_BASE_OWNER}/${TEMPLATE_BASE_REPO}`
);
};
const getGitHubCommitsBehind = async (params?: RepoParams) => {
const response = await fetch(getGitHubApiCompareUrl({
...params,
branch: VERCEL_BRANCH,
}));
const response = await fetch(getGitHubApiCompareUrl(params));
const data = await response.json();
return data.behind_by as number;
};
const isRepoBaseRepo = async ({ owner, repo }: RepoParams) =>
owner?.toLowerCase() === BASE_OWNER &&
repo?.toLowerCase() === BASE_REPO;
owner?.toLowerCase() === TEMPLATE_BASE_OWNER &&
repo?.toLowerCase() === TEMPLATE_BASE_REPO;
export const getGitHubMeta = async (params: RepoParams) => {
const [

View File

@ -3,23 +3,26 @@ import type { StorageType } from '@/services/storage';
import { makeUrlAbsolute, shortenUrl } from '@/utility/url';
// HARD-CODED GLOBAL CONFIGURATION
export const SHOULD_PREFETCH_ALL_LINKS: boolean | undefined = undefined;
export const SHOULD_DEBUG_SQL = false;
// META / SOURCE / DOMAINS
export const SITE_TITLE =
process.env.NEXT_PUBLIC_SITE_TITLE ||
'Photo Blog';
// SOURCE
export const TEMPLATE_BASE_OWNER = 'sambecker';
export const TEMPLATE_BASE_REPO = 'exif-photo-blog';
export const TEMPLATE_BASE_BRANCH = 'main';
export const VERCEL_GIT_PROVIDER =
process.env.NEXT_PUBLIC_VERCEL_GIT_PROVIDER;
export const VERCEL_GIT_REPO_OWNER =
process.env.NEXT_PUBLIC_VERCEL_GIT_REPO_OWNER;
export const VERCEL_GIT_REPO_SLUG =
process.env.NEXT_PUBLIC_VERCEL_GIT_REPO_SLUG;
export const VERCEL_GIT_BRANCH = process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_REF;
export const VERCEL_GIT_COMMIT_MESSAGE =
process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_MESSAGE;
export const VERCEL_GIT_COMMIT_SHA =
@ -37,10 +40,9 @@ export const VERCEL_ENV = process.env.NEXT_PUBLIC_VERCEL_ENV;
export const VERCEL_PRODUCTION_URL = process.env.VERCEL_PROJECT_PRODUCTION_URL;
export const VERCEL_DEPLOYMENT_URL = process.env.NEXT_PUBLIC_VERCEL_URL;
export const VERCEL_BRANCH_URL = process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL;
export const VERCEL_BRANCH = process.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_REF;
// Last resort: cannot be used reliably
export const VERCEL_PROJECT_URL = VERCEL_BRANCH_URL && VERCEL_BRANCH
? `${VERCEL_BRANCH_URL.split(`-git-${VERCEL_BRANCH}-`)[0]}.vercel.app`
export const VERCEL_PROJECT_URL = VERCEL_BRANCH_URL && VERCEL_GIT_BRANCH
? `${VERCEL_BRANCH_URL.split(`-git-${VERCEL_GIT_BRANCH}-`)[0]}.vercel.app`
: undefined;
export const IS_PRODUCTION = process.env.NODE_ENV === 'production' && (

View File

@ -29,7 +29,7 @@ module.exports = {
'rotate-pulse':
'rotate-pulse 0.75s linear infinite normal both running',
'fade-in':
'fade-in 0.5s linear',
'fade-in 0.5s linear both running',
'hover-drift':
'hover-drift 8s linear infinite',
'hover-wobble':