From b60a91a0757c003d20a6476755892a74073c1dab Mon Sep 17 00:00:00 2001 From: "Abdullah." <125115953+mabdullahabaid@users.noreply.github.com> Date: Fri, 5 Jun 2026 13:59:40 +0500 Subject: [PATCH] fix(website): render releases from local notes, drop GitHub gate (#21238) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The releases page gated visible notes on fetchLatestGithubReleaseTag(); when that unauthenticated GitHub call was rate-limited at build (common on shared Cloudflare build IPs, no GITHUB_TOKEN), it returned null and getVisibleReleaseNotes returned [], rendering 'No releases are visible yet for the current published version' — the exact prod symptom. force-static made each deploy a coin flip. Committed MDX (+images) is the single source of truth, so gate visibility on nothing: render all local notes deterministically with no network call. Removes the dev/prod divergence and deletes the now-dead fetch-latest-release-tag.ts and get-visible-releases.ts. --- .../src/app/[locale]/releases/page.tsx | 25 ++++----------- .../lib/releases/fetch-latest-release-tag.ts | 24 -------------- .../src/lib/releases/get-visible-releases.ts | 32 ------------------- 3 files changed, 7 insertions(+), 74 deletions(-) delete mode 100644 packages/twenty-website/src/lib/releases/fetch-latest-release-tag.ts delete mode 100644 packages/twenty-website/src/lib/releases/get-visible-releases.ts diff --git a/packages/twenty-website/src/app/[locale]/releases/page.tsx b/packages/twenty-website/src/app/[locale]/releases/page.tsx index b639f592a2..88b47ca329 100644 --- a/packages/twenty-website/src/app/[locale]/releases/page.tsx +++ b/packages/twenty-website/src/app/[locale]/releases/page.tsx @@ -1,8 +1,6 @@ import { fetchCommunityStats } from '@/lib/community/fetch-community-stats'; import { getRouteI18n, type LocaleRouteParams } from '@/lib/i18n/server'; import { mergeSocialLinkLabels } from '@/lib/community/merge-social-link-labels'; -import { fetchLatestGithubReleaseTag } from '@/lib/releases/fetch-latest-release-tag'; -import { getVisibleReleaseNotes } from '@/lib/releases/get-visible-releases'; import { loadLocalReleaseNotes } from '@/lib/releases/load-local-release-notes'; import { ReleasesHero } from '@/app/[locale]/releases/_components/ReleasesHero'; import { Menu, MENU_DATA } from '@/sections/Menu'; @@ -25,22 +23,17 @@ type ReleasesPageProps = { }; export default async function ReleasesPage({ params }: ReleasesPageProps) { - const allNotes = loadLocalReleaseNotes(); - const [, latestTag, stats] = await Promise.all([ + const notes = loadLocalReleaseNotes(); + const [, stats] = await Promise.all([ getRouteI18n(params), - fetchLatestGithubReleaseTag(), fetchCommunityStats(), ]); const menuSocialLinks = mergeSocialLinkLabels(MENU_DATA.socialLinks, stats); - const visibleNotes = - process.env.NODE_ENV === 'development' - ? allNotes - : getVisibleReleaseNotes(allNotes, latestTag); return ( <> - {visibleNotes.length > 0 ? ( - + {notes.length > 0 ? ( + ) : null} {/* * Above-the-fold milestone scene texture. Preload kicks off the @@ -59,26 +52,22 @@ export default async function ReleasesPage({ params }: ReleasesPageProps) { - {allNotes.length === 0 ? ( + {notes.length === 0 ? ( Releases were not found. Add MDX under{' '} packages/twenty-website/src/content/releases and images under{' '} packages/twenty-website/public/images/releases. - ) : visibleNotes.length === 0 ? ( - - No releases are visible yet for the current published version. - ) : ( - visibleNotes.map((note, index) => ( + notes.map((note, index) => ( - {index < visibleNotes.length - 1 ? : null} + {index < notes.length - 1 ? : null} )) )} diff --git a/packages/twenty-website/src/lib/releases/fetch-latest-release-tag.ts b/packages/twenty-website/src/lib/releases/fetch-latest-release-tag.ts deleted file mode 100644 index 5197b06252..0000000000 --- a/packages/twenty-website/src/lib/releases/fetch-latest-release-tag.ts +++ /dev/null @@ -1,24 +0,0 @@ -export async function fetchLatestGithubReleaseTag(): Promise { - try { - const headers: Record = { - Accept: 'application/vnd.github+json', - 'X-GitHub-Api-Version': '2022-11-28', - }; - - if (process.env.GITHUB_TOKEN) { - headers.Authorization = `Bearer ${process.env.GITHUB_TOKEN}`; - } - - const response = await fetch( - 'https://api.github.com/repos/twentyhq/twenty/releases/latest', - { headers }, - ); - - if (!response.ok) return null; - - const data = (await response.json()) as { tag_name?: string }; - return data.tag_name ?? null; - } catch { - return null; - } -} diff --git a/packages/twenty-website/src/lib/releases/get-visible-releases.ts b/packages/twenty-website/src/lib/releases/get-visible-releases.ts deleted file mode 100644 index 0b865ba303..0000000000 --- a/packages/twenty-website/src/lib/releases/get-visible-releases.ts +++ /dev/null @@ -1,32 +0,0 @@ -import type { LocalReleaseNote } from '@/lib/releases/types'; -import { getFormattedReleaseNumber } from '@/lib/releases/get-formatted-release-number'; - -function safeReleaseNumber(version: string): number | null { - try { - return getFormattedReleaseNumber(version); - } catch { - return null; - } -} - -export function getVisibleReleaseNotes( - notes: LocalReleaseNote[], - latestPublishedTag: string | null, -): LocalReleaseNote[] { - if (!latestPublishedTag) { - return []; - } - - const publishedNumber = safeReleaseNumber(latestPublishedTag); - if (publishedNumber === null) { - return []; - } - - return notes.filter((note) => { - const noteNumber = safeReleaseNumber(note.release); - if (noteNumber === null) { - return false; - } - return noteNumber <= publishedNumber; - }); -}