From 49736330792b344f172943b858237b2ffe0fb7a0 Mon Sep 17 00:00:00 2001 From: WilcoSp Date: Wed, 2 Sep 2026 16:37:04 +0200 Subject: [PATCH 1/6] added support for gitea for changelogs --- .../[owner]/[repo]/[...path].get.ts | 3 + .../releases/[provider]/[owner]/[repo].get.ts | 35 +++++++++- server/utils/changelog/baseFileUrl.ts | 12 +++- server/utils/changelog/detectChangelog.ts | 69 +++++++++++++++++++ server/utils/changelog/mdRepoInfo.ts | 22 ++++++ shared/schemas/changelog/release.ts | 5 ++ 6 files changed, 142 insertions(+), 4 deletions(-) diff --git a/server/api/changelog/md/[provider]/[owner]/[repo]/[...path].get.ts b/server/api/changelog/md/[provider]/[owner]/[repo]/[...path].get.ts index a1582b1414..66bd991de7 100644 --- a/server/api/changelog/md/[provider]/[owner]/[repo]/[...path].get.ts +++ b/server/api/changelog/md/[provider]/[owner]/[repo]/[...path].get.ts @@ -3,6 +3,7 @@ import * as v from 'valibot' import { getBaseFileUrl } from '~~/server/utils/changelog/baseFileUrl' import { createForgejoRepoInfo, + createGiteaRepoInfo, createGithubRepoInfo, createGitLabRepoInfo, createTangledInfo, @@ -114,5 +115,7 @@ function getRepoInfo( return createGitLabRepoInfo(host ?? 'gitlab.com', owner, repo, path) case 'tangled': return createTangledInfo(owner, repo, path) + case 'gitea': + return createGiteaRepoInfo(host ?? 'gitea.com', owner, repo, path) } } diff --git a/server/api/changelog/releases/[provider]/[owner]/[repo].get.ts b/server/api/changelog/releases/[provider]/[owner]/[repo].get.ts index 20e618072a..cac921157f 100644 --- a/server/api/changelog/releases/[provider]/[owner]/[repo].get.ts +++ b/server/api/changelog/releases/[provider]/[owner]/[repo].get.ts @@ -9,9 +9,14 @@ import { GithubReleaseCollectionSchama, ForgejoReleaseCollectionSchema, GitlabReleaseCollectionSchema, + GiteaReleaseCollectionSchema, } from '~~/shared/schemas/changelog/release' import { changelogRenderer } from '~~/server/utils/changelog/markdown' -import { createForgejoRepoInfo, createGithubRepoInfo } from '~~/server/utils/changelog/mdRepoInfo' +import { + createForgejoRepoInfo, + createGiteaRepoInfo, + createGithubRepoInfo, +} from '~~/server/utils/changelog/mdRepoInfo' import { validateHostWithValibot } from '~~/server/utils/changelog/validateHost' export default defineCachedEventHandler( @@ -39,6 +44,8 @@ export default defineCachedEventHandler( return await getReleasesFromForgejo(owner, repo, host) case 'gitlab': return await getReleasesFromGitlab(owner, repo, host) + case 'gitea': + return await getReleasesFromGitea(owner, repo, host) default: throw createError({ @@ -158,3 +165,29 @@ async function getReleasesFromGitlab(owner: string, repo: string, host: string) } satisfies ReleaseData }) } + +async function getReleasesFromGitea(owner: string, repo: string, host: string) { + const data = await $fetch(`https://${host}/api/v1/repos/${owner}/${repo}/releases?draft=false`, { + headers: { + 'User-Agent': 'npmx.dev', + }, + }) + const releases = v.parse(GiteaReleaseCollectionSchema, data) + + const render = await changelogRenderer(createGiteaRepoInfo(host, owner, repo)) + + return releases.map(r => { + const { html, toc } = render(r.body, r.id) + return { + id: r.id, + html: html?.replace(/(?)\n/g, '
') ?? null, + title: r.name || r.tag_name, + prerelease: r.prerelease, + toc, + link: r.html_url, + publishedAt: r.published_at, + draft: r.draft, + tag: r.tag_name, + } satisfies ReleaseData + }) +} diff --git a/server/utils/changelog/baseFileUrl.ts b/server/utils/changelog/baseFileUrl.ts index 7cda63169b..9f79a7e226 100644 --- a/server/utils/changelog/baseFileUrl.ts +++ b/server/utils/changelog/baseFileUrl.ts @@ -16,10 +16,16 @@ export function getBaseFileUrl(ref: RepoRef): RepoFileUrl | null { raw: `https://codeberg.org/${ref.owner}/${ref.repo}/raw/branch/HEAD`, } case 'forgejo': { - const host = ref.host return { - blob: `https://${host}/${ref.owner}/${ref.repo}/src/branch/HEAD`, - raw: `https://${host}/${ref.owner}/${ref.repo}/raw/branch/HEAD`, + blob: `https://${ref.host}/${ref.owner}/${ref.repo}/src/branch/HEAD`, + raw: `https://${ref.host}/${ref.owner}/${ref.repo}/raw/branch/HEAD`, + } + } + case 'gitea': { + // although similar to forgejo, we keep these seperate because they're seperate maintained projects + return { + blob: `https://${ref.host}/${ref.owner}/${ref.repo}/src/branch/HEAD`, + raw: `https://${ref.host}/${ref.owner}/${ref.repo}/raw/branch/HEAD`, } } case 'gitlab': { diff --git a/server/utils/changelog/detectChangelog.ts b/server/utils/changelog/detectChangelog.ts index 6289a7aebd..1d04fd86df 100644 --- a/server/utils/changelog/detectChangelog.ts +++ b/server/utils/changelog/detectChangelog.ts @@ -8,6 +8,7 @@ import { GithubReleaseSchama, ForgejoReleaseSchama, GitlabReleaseSchame, + GiteaReleaseSchema, } from '~~/shared/schemas/changelog/release' import { resolveURL } from 'ufo' import * as v from 'valibot' @@ -66,6 +67,9 @@ async function checkReleases( case 'gitlab': { return checkLatestGitlabRelease(ref, directory) } + case 'gitea': { + return checkLatestGiteaRelease(ref, directory) + } } return [false, null] } @@ -340,3 +344,68 @@ async function checkLatestGitlabRelease( } return [false, null] } + +// gitea +async function checkLatestGiteaRelease( + ref: RepoRef, + directory?: string, +): Promise> { + try { + const host = ref.host ?? 'gitea.com' + + const response = await $fetch( + `https://${host}/api/v1/repos/${ref.owner}/${ref.repo}/releases/latest`, + { + headers: { + 'User-Agent': 'npmx.dev', + 'accept': 'application/json', + }, + }, + ) + + const release = v.parse(GiteaReleaseSchema, response) + + const matchedChangelog = release.body?.match(MD_REGEX)?.at(0) + + // /src/branch/ can be similar to /blob/ + if (!matchedChangelog || !matchedChangelog.includes('/src/branch/')) { + return [ + { + type: 'release', + link: `https://${host}/${ref.owner}/${ref.repo}/releases`, + provider: ref.provider, + repo: `${ref.owner}/${ref.repo}`, + host: ref.host, + }, + null, + ] + } + + const path = matchedChangelog.replace(/^.*\/src\/branch\/[^/]+\//i, '') + if ( + directory && + !( + path.startsWith(directory.endsWith('/') ? directory : `${directory}/`) || + ROOT_ONLY_REGEX.test(path) + ) + ) { + return [false, null] as const + } + return [ + { + provider: ref.provider, + type: 'md', + path, + repo: `${ref.owner}/${ref.repo}`, + link: matchedChangelog, + host: ref.host, + }, + null, + ] + } catch (e) { + if (e instanceof Error) { + return [null, e] + } + } + return [false, null] +} diff --git a/server/utils/changelog/mdRepoInfo.ts b/server/utils/changelog/mdRepoInfo.ts index fca0f1dd74..ece9875ccf 100644 --- a/server/utils/changelog/mdRepoInfo.ts +++ b/server/utils/changelog/mdRepoInfo.ts @@ -78,3 +78,25 @@ export function createTangledInfo(owner: string, repo: string, path?: string): M compareBaseUrl: `${hostBaseUrl}/${owner}/${repo}/compare`, } } + +// similar to forgejo, but they're seperate projects so keeping this also seperate +export function createGiteaRepoInfo( + host: string, + owner: string, + repo: string, + path?: string, +): MarkdownRepoInfo { + const hostBaseUrl = `https://${host}` + return { + hostBaseUrl, + blobBaseUrl: `${hostBaseUrl}/${owner}/${repo}/src/branch/HEAD`, + rawBaseUrl: `${hostBaseUrl}/${owner}/${repo}/raw/branch/HEAD`, + path, + commitBaseUrl: `${hostBaseUrl}/${owner}/${repo}/commit`, + issueChar: '#', + issueBaseUrl: `${hostBaseUrl}/${owner}/${repo}/issues`, + prChar: '#', + prBaseUrl: `${hostBaseUrl}/${owner}/${repo}/pulls`, + compareBaseUrl: `${hostBaseUrl}/${owner}/${repo}/compare`, + } +} diff --git a/shared/schemas/changelog/release.ts b/shared/schemas/changelog/release.ts index 0ac03ddd5c..d02edd9742 100644 --- a/shared/schemas/changelog/release.ts +++ b/shared/schemas/changelog/release.ts @@ -46,3 +46,8 @@ export const GitlabReleaseSchame = v.object({ }) export const GitlabReleaseCollectionSchema = v.array(GitlabReleaseSchame) + +// these are currently the same with forgejo, but exporting this one seperetely in case either change their schema +export const GiteaReleaseSchema = ForgejoReleaseSchama + +export const GiteaReleaseCollectionSchema = v.array(GiteaReleaseSchema) From 36d2ac9e2ef51be2c3f4fe14bfcc159c38248230 Mon Sep 17 00:00:00 2001 From: WilcoSp Date: Wed, 2 Sep 2026 16:45:51 +0200 Subject: [PATCH 2/6] ... --- shared/schemas/changelog/release.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/shared/schemas/changelog/release.ts b/shared/schemas/changelog/release.ts index d02edd9742..8734395b3c 100644 --- a/shared/schemas/changelog/release.ts +++ b/shared/schemas/changelog/release.ts @@ -47,7 +47,15 @@ export const GitlabReleaseSchame = v.object({ export const GitlabReleaseCollectionSchema = v.array(GitlabReleaseSchame) -// these are currently the same with forgejo, but exporting this one seperetely in case either change their schema -export const GiteaReleaseSchema = ForgejoReleaseSchama +export const GiteaReleaseSchema = v.object({ + id: v.number(), + tag_name: v.string(), + name: v.string(), + body: v.string(), + html_url: v.pipe(v.string(), v.url()), + draft: v.boolean(), + prerelease: v.boolean(), + published_at: v.pipe(v.string(), v.isoTimestamp()), +}) export const GiteaReleaseCollectionSchema = v.array(GiteaReleaseSchema) From 0756d225130180ceb9657d574b6a5f2a05d3232d Mon Sep 17 00:00:00 2001 From: WilcoSp Date: Wed, 2 Sep 2026 18:27:08 +0200 Subject: [PATCH 3/6] adding support for bitbucket to changelog --- .../[owner]/[repo]/[...path].get.ts | 3 +++ server/utils/changelog/baseFileUrl.ts | 8 ++++++- server/utils/changelog/markdown.ts | 21 +++++++++++-------- server/utils/changelog/mdRepoInfo.ts | 18 ++++++++++++++++ 4 files changed, 40 insertions(+), 10 deletions(-) diff --git a/server/api/changelog/md/[provider]/[owner]/[repo]/[...path].get.ts b/server/api/changelog/md/[provider]/[owner]/[repo]/[...path].get.ts index 66bd991de7..56bb1f112e 100644 --- a/server/api/changelog/md/[provider]/[owner]/[repo]/[...path].get.ts +++ b/server/api/changelog/md/[provider]/[owner]/[repo]/[...path].get.ts @@ -2,6 +2,7 @@ import { resolveURL } from 'ufo' import * as v from 'valibot' import { getBaseFileUrl } from '~~/server/utils/changelog/baseFileUrl' import { + createBitbucketRepoInfo, createForgejoRepoInfo, createGiteaRepoInfo, createGithubRepoInfo, @@ -117,5 +118,7 @@ function getRepoInfo( return createTangledInfo(owner, repo, path) case 'gitea': return createGiteaRepoInfo(host ?? 'gitea.com', owner, repo, path) + case 'bitbucket': + return createBitbucketRepoInfo(owner, repo, path) } } diff --git a/server/utils/changelog/baseFileUrl.ts b/server/utils/changelog/baseFileUrl.ts index 9f79a7e226..aa0b771ca9 100644 --- a/server/utils/changelog/baseFileUrl.ts +++ b/server/utils/changelog/baseFileUrl.ts @@ -22,7 +22,7 @@ export function getBaseFileUrl(ref: RepoRef): RepoFileUrl | null { } } case 'gitea': { - // although similar to forgejo, we keep these seperate because they're seperate maintained projects + // although similar to forgejo, we keep these seperate because they're seperately maintained projects return { blob: `https://${ref.host}/${ref.owner}/${ref.repo}/src/branch/HEAD`, raw: `https://${ref.host}/${ref.owner}/${ref.repo}/raw/branch/HEAD`, @@ -41,6 +41,12 @@ export function getBaseFileUrl(ref: RepoRef): RepoFileUrl | null { raw: `https://tangled.org/${ref.owner}/${ref.repo}/raw/HEAD`, } } + case 'bitbucket': { + return { + blob: `https://bitbucket.org/${ref.owner}/${ref.repo}/src/HEAD`, + raw: `https://bitbucket.org/${ref.owner}/${ref.repo}/raw/HEAD`, + } + } } return null } diff --git a/server/utils/changelog/markdown.ts b/server/utils/changelog/markdown.ts index e57d3f42e3..4edd42b82c 100644 --- a/server/utils/changelog/markdown.ts +++ b/server/utils/changelog/markdown.ts @@ -118,9 +118,9 @@ export interface MarkdownRepoInfo { /** the base url of repository commit */ commitBaseUrl: string /** base url for a repository issue */ - issueBaseUrl: string + issueBaseUrl?: string /** the text char that indicates an issue */ - issueChar: keyof typeof issuePrRegexes + issueChar?: keyof typeof issuePrRegexes /** base url for a repository pull/merge request */ prBaseUrl: string /** @@ -130,7 +130,7 @@ export interface MarkdownRepoInfo { x*/ prChar: keyof typeof issuePrRegexes /** base url for a repository compare */ - compareBaseUrl: string + compareBaseUrl?: string } function resolveUrl(url: string, repoInfo: MarkdownRepoInfo, toUserContentId: ToUserContentIdFn) { @@ -220,13 +220,13 @@ function resolveGitLinkText(href: string, label: string, repoInfo: MarkdownRepoI case href.startsWith(repoInfo.commitBaseUrl): { return lastSegment.slice(0, 7) // only show the first 6 letters/numbers of a commit } - case href.startsWith(repoInfo.issueBaseUrl): { + case !!repoInfo.issueBaseUrl && href.startsWith(repoInfo.issueBaseUrl): { return `${repoInfo.issueChar}${lastSegment}` } case href.startsWith(repoInfo.prBaseUrl): { return `${repoInfo.prChar}${lastSegment}` } - case href.startsWith(repoInfo.compareBaseUrl): { + case !!repoInfo.compareBaseUrl && href.startsWith(repoInfo.compareBaseUrl): { return lastSegment } // for account we don't resolve, this is something the git providers also don't do @@ -256,16 +256,19 @@ function createResolveGitTextToLinks(mdInfo: MarkdownRepoInfo): IOptions['textFi return `${match.slice(0, 7)}` }) - .replace(issuePrRegexes[mdInfo.issueChar], match => { - const id = match.replace(mdInfo.issueChar, '') - return `${match}` - }) // account .replace(accountRegex, match => { const acc = match.replace('@', '') return `${match}` }) + if (mdInfo.issueChar && mdInfo.issueBaseUrl) { + text = text.replace(issuePrRegexes[mdInfo.issueChar], match => { + const id = match.replace(mdInfo.issueChar!, '') + return `${match}` + }) + } + // pr/mr if (mdInfo.issueChar != mdInfo.prChar) { text = text.replace(issuePrRegexes[mdInfo.prChar], match => { diff --git a/server/utils/changelog/mdRepoInfo.ts b/server/utils/changelog/mdRepoInfo.ts index ece9875ccf..2681d9bdaf 100644 --- a/server/utils/changelog/mdRepoInfo.ts +++ b/server/utils/changelog/mdRepoInfo.ts @@ -100,3 +100,21 @@ export function createGiteaRepoInfo( compareBaseUrl: `${hostBaseUrl}/${owner}/${repo}/compare`, } } + +export function createBitbucketRepoInfo( + owner: string, + repo: string, + path?: string, +): MarkdownRepoInfo { + const hostBaseUrl = 'https://bitbucket.org' + return { + hostBaseUrl, + blobBaseUrl: `${hostBaseUrl}/${owner}/${repo}/src/HEAD`, + rawBaseUrl: `${hostBaseUrl}/${owner}/${repo}/raw/HEAD`, + path, + commitBaseUrl: `${hostBaseUrl}/${owner}/${repo}/commits`, + prChar: '#', + prBaseUrl: `${hostBaseUrl}/${owner}/${repo}/pull-requests`, + // bitbucket uses jira instead of normal issues which can't be resolved, further the compare page also seems to be different + } +} From cc30bd03e710472dc5fffc31de18de264bb959ea Mon Sep 17 00:00:00 2001 From: WilcoSp Date: Wed, 2 Sep 2026 20:39:04 +0200 Subject: [PATCH 4/6] added an timeout & added fallback for if gitea host isn't defined --- .../changelog/md/[provider]/[owner]/[repo]/[...path].get.ts | 1 + .../api/changelog/releases/[provider]/[owner]/[repo].get.ts | 6 ++++++ .../releases/[provider]/[owner]/[repo]/raw/[tag].get.ts | 1 + server/utils/changelog/baseFileUrl.ts | 5 +++-- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/server/api/changelog/md/[provider]/[owner]/[repo]/[...path].get.ts b/server/api/changelog/md/[provider]/[owner]/[repo]/[...path].get.ts index 56bb1f112e..1f7edb0e3c 100644 --- a/server/api/changelog/md/[provider]/[owner]/[repo]/[...path].get.ts +++ b/server/api/changelog/md/[provider]/[owner]/[repo]/[...path].get.ts @@ -58,6 +58,7 @@ export default defineCachedEventHandler( headers: { 'User-Agent': 'npmx.dev', }, + timeout: 15_000, }) const markdown = v.parse(v.string(), data) if (raw != undefined) { diff --git a/server/api/changelog/releases/[provider]/[owner]/[repo].get.ts b/server/api/changelog/releases/[provider]/[owner]/[repo].get.ts index cac921157f..87b19ce128 100644 --- a/server/api/changelog/releases/[provider]/[owner]/[repo].get.ts +++ b/server/api/changelog/releases/[provider]/[owner]/[repo].get.ts @@ -19,6 +19,8 @@ import { } from '~~/server/utils/changelog/mdRepoInfo' import { validateHostWithValibot } from '~~/server/utils/changelog/validateHost' +const TIMEOUT_TIME = 15_000 + export default defineCachedEventHandler( async event => { const provider = getRouterParam(event, 'provider') as ProviderId @@ -86,6 +88,7 @@ async function getReleasesFromGithub(owner: string, repo: string) { 'Accept': '*/*', 'User-Agent': 'npmx.dev', }, + timeout: TIMEOUT_TIME, }) const { releases } = v.parse(GithubReleaseCollectionSchama, data) @@ -114,6 +117,7 @@ async function getReleasesFromForgejo(owner: string, repo: string, host: string) headers: { 'User-Agent': 'npmx.dev', }, + timeout: TIMEOUT_TIME, }) const releases = v.parse(ForgejoReleaseCollectionSchema, data) @@ -144,6 +148,7 @@ async function getReleasesFromGitlab(owner: string, repo: string, host: string) headers: { 'User-Agent': 'npmx.dev', }, + timeout: TIMEOUT_TIME, }) const releases = v.parse(GitlabReleaseCollectionSchema, data) @@ -171,6 +176,7 @@ async function getReleasesFromGitea(owner: string, repo: string, host: string) { headers: { 'User-Agent': 'npmx.dev', }, + timeout: TIMEOUT_TIME, }) const releases = v.parse(GiteaReleaseCollectionSchema, data) diff --git a/server/api/changelog/releases/[provider]/[owner]/[repo]/raw/[tag].get.ts b/server/api/changelog/releases/[provider]/[owner]/[repo]/raw/[tag].get.ts index a09079a1a8..6f3cf9f3b7 100644 --- a/server/api/changelog/releases/[provider]/[owner]/[repo]/raw/[tag].get.ts +++ b/server/api/changelog/releases/[provider]/[owner]/[repo]/raw/[tag].get.ts @@ -84,6 +84,7 @@ async function getMarkdownFromGithub(owner: string, repo: string, tag: string, e 'User-Agent': 'npmx.dev', }, ignoreResponseError: true, + timeout: 15_000, }, ) diff --git a/server/utils/changelog/baseFileUrl.ts b/server/utils/changelog/baseFileUrl.ts index aa0b771ca9..bd321ab81f 100644 --- a/server/utils/changelog/baseFileUrl.ts +++ b/server/utils/changelog/baseFileUrl.ts @@ -23,9 +23,10 @@ export function getBaseFileUrl(ref: RepoRef): RepoFileUrl | null { } case 'gitea': { // although similar to forgejo, we keep these seperate because they're seperately maintained projects + const host = ref.host ?? 'gitea.com' return { - blob: `https://${ref.host}/${ref.owner}/${ref.repo}/src/branch/HEAD`, - raw: `https://${ref.host}/${ref.owner}/${ref.repo}/raw/branch/HEAD`, + blob: `https://${host}/${ref.owner}/${ref.repo}/src/branch/HEAD`, + raw: `https://${host}/${ref.owner}/${ref.repo}/raw/branch/HEAD`, } } case 'gitlab': { From d04de2aa4f288e144f4c350cda0c85cf20bf57a1 Mon Sep 17 00:00:00 2001 From: WilcoSp Date: Wed, 2 Sep 2026 20:54:33 +0200 Subject: [PATCH 5/6] adding more timeout when trying to retrieve markdown from releases --- .../releases/[provider]/[owner]/[repo]/raw/[tag].get.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/server/api/changelog/releases/[provider]/[owner]/[repo]/raw/[tag].get.ts b/server/api/changelog/releases/[provider]/[owner]/[repo]/raw/[tag].get.ts index 6f3cf9f3b7..94df96b8c7 100644 --- a/server/api/changelog/releases/[provider]/[owner]/[repo]/raw/[tag].get.ts +++ b/server/api/changelog/releases/[provider]/[owner]/[repo]/raw/[tag].get.ts @@ -8,6 +8,8 @@ import { } from '~~/shared/schemas/changelog/release' import { validateHostWithValibot } from '~~/server/utils/changelog/validateHost' +const TIMEOUT_TIME = 15_000 + export default defineCachedEventHandler( async event => { const provider = getRouterParam(event, 'provider') as ProviderId @@ -84,7 +86,7 @@ async function getMarkdownFromGithub(owner: string, repo: string, tag: string, e 'User-Agent': 'npmx.dev', }, ignoreResponseError: true, - timeout: 15_000, + timeout: TIMEOUT_TIME, }, ) @@ -102,6 +104,7 @@ async function getMarkdownFromGithub(owner: string, repo: string, tag: string, e 'Accept': '*/*', 'User-Agent': 'npmx.dev', }, + timeout: TIMEOUT_TIME, }) const { releases } = v.parse(GithubReleaseCollectionSchama, responseUngh) @@ -130,6 +133,7 @@ async function getMarkdownFromForgejo( headers: { 'User-Agent': 'npmx.dev', }, + timeout: TIMEOUT_TIME, }) const release = v.parse(ForgejoReleaseSchama, data) @@ -151,6 +155,7 @@ async function getMarkdownFromGitlab( headers: { 'User-Agent': 'npmx.dev', }, + timeout: TIMEOUT_TIME, }) const release = v.parse(GitlabReleaseSchame, data) From 36c408ffd3e721841fef09ee2be26d141bd3971a Mon Sep 17 00:00:00 2001 From: WilcoSp Date: Wed, 2 Sep 2026 21:38:58 +0200 Subject: [PATCH 6/6] handling timeout --- .../releases/[provider]/[owner]/[repo]/raw/[tag].get.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/api/changelog/releases/[provider]/[owner]/[repo]/raw/[tag].get.ts b/server/api/changelog/releases/[provider]/[owner]/[repo]/raw/[tag].get.ts index 94df96b8c7..98bb2a25a9 100644 --- a/server/api/changelog/releases/[provider]/[owner]/[repo]/raw/[tag].get.ts +++ b/server/api/changelog/releases/[provider]/[owner]/[repo]/raw/[tag].get.ts @@ -88,7 +88,7 @@ async function getMarkdownFromGithub(owner: string, repo: string, tag: string, e ignoreResponseError: true, timeout: TIMEOUT_TIME, }, - ) + ).catch(() => null) const parsed = v.safeParse(v.object({ body: v.string() }), responseGithub)